# Learning Python 3 with the Linkbot/Linkbot Multitasking
### "Non-blocking" Linkbot Functions

Lets take an inventory of all of the functions that we've used so far to control various aspects of the Linkbot.
| Function Name | Function Description |
| setLEDColor(r, g, b) | Changes the LED color based on red, green, and blue intensities. |
| setBuzzerFrequency(Hz) | Makes the Linkbot buzzer play a frequency in Hertz. |
| moveJoint(jointNum, degrees) | Makes a single motor move. |
| move(degrees, degrees, degrees) | Makes multiple motors move simultaneously |
Using these functions, we can move our robot around, change the robot's LED color, and make the robot beep or play simple melodies. However, using only these functions, it is not possible to make a robot play a tune and change its LED colors while the robot is moving. For example, lets say we want to make our robot beep 2 times _while_ our robot is moving. We can try something like this:
Lets reason our way through each major point of this program.
* First, we turn on the buzzer on the Linkbot. It starts buzzing
* Pause the program for 0.25 seconds
* Turn off the Linkbot's buzzer.
* Pause the program for another 0.25 seconds. The end result of steps 1-4 is that the Linkbot buzzes its buzzer for 0.25 seconds. The next four lines do the same exact thing.
* At this point, the Linkbot has buzzed twice, and now the move function makes the Linkbot roll forward.
This is almost what we want to do, except we want the robot to beep twice while the robot is moving; not before it starts moving. Lets try again:
This program is almost exactly the same as the program before except we relocated the move function to the beginning of the program. Will this program make the robot beep twice as the robot is moving?
* First, we call the move function which moves the robot's motors. The robot begins moving. However, the program stays at item 1 until the move function is completed. After the robot finishes moving, the program continues.
* Here, the robot turns the buzzer on similar to the previous example. Using setBuzzerFrequency and time.sleep, it makes the buzzer beep twice.

### The moveNB Function

As we can see, we have failed yet again to make the robot beep twice while moving. In order to make the robot do these things simultaneously, we must use a similar but new type of function: Non-blocking functions. Lets take a look at an example:
* Here, instead of using the move function, we use the moveNB function.
The "NB" in the function name stands for "non-blocking". Both functions move the motors on the Linkbot, but there is one important difference: The NB version of the function "returns" immediately. What this means is Python continues on to the next line of code immediately without waiting for the movement to finish first. In other words, the moveNB function does not "block" Python from continuing on immediately after the function is called.
* Now, the Linkbot begins playing its buzzer while the Linkbot is still moving. We've accomplished our task! This program will move the robot and beep twice while the robot is moving.

### The moveWait Function

Now lets try one more example. Lets say we want to make the robot move its wheels 180 degrees to roll forward while beeping twice, and then change the LED color to green after the movement is done. To accomplish this, we introduce the moveWait function. Lets take a look and see how it works:
* As before, this line tells the robot to begin moving motors 1 and 3. Since we used the "NB" version of the function, Python continues directly on to the next line of code even though the robot is still moving.
* The next several lines of code beep the robot twice, similar to before.
* Here, we call a function called moveWait. This function blocks until all motor movements on the robot are finished. In effect, Python will wait at # 3 until the motors are done moving.
* Here, we set the LED color to green.
If we had omitted moveWait at # 3, the LED color would've been set whether the motors were still moving or not. By using the moveWait function, we force Python to wait for the motors to stop moving before setting the LED color.

### Other Non-Blocking Functions

Almost all Linkbot movement commands have a non-blocking version with the "NB" suffix. The ones that do not have a non-blocking version are the ones that move a Linkbot's motor continuously forever. We haven't explored any of them yet, but they are out there. These functions do not have non-blocking versions because they would block forever.
All of the functions that begin with the prefix "set", such as setBuzzerFrequency and setLEDColor, can be considered non-blocking because of how fast the buzzer and LED colors are set. For instance, if you run the following snippet of code:
The Linkbot would appear to start buzzing and change the LED color to green simultaneously. Technically, the robot is actually doing one before the other, but the two things happen so fast (typically within 5 milliseconds of each other) that it is practically simultaneous.