Before we start with the next example, let's recapitulate the key points from the first part of this guide.
Common patterns can be found in professionally written software for controlling hardware:
- queues with waiting tasks,
- tasks have priorities and
- there are interrupts.
When using the cooperative_multitasking library, the code follows some rules:
1. There is a procedure for every state.
2. The body of a procedure for a state first brings the hardware into the desired state. Then it defines what should happen next.
3. Choose what happens when the hardware is powered on.
4. Let the hardware run.
Example 2: Color Wheel with Neo TrinkeyThe code can be found in the code section of this project.
It cycles the four NeoPixels through every possible color - or at least many of them. Every NeoPixel changes colors at different speeds. If one (or both) of the capacitive touch inputs are touched, the colors of all four NeoPixels reset to the power-on state.
As usual, the first lines do the necessary imports. Lines 6-9 initialize the NeoPixels and the touch inputs. Line 10 constructs a list that holds four colors, encoded as inputs to the colorwheel function. Line 11 initializes the data structure needed for cooperative multitasking (the queue).
The procedure change_color(pixel) in lines 13-16 is a helper. It advances the pixel identified by the argument to the next color.
Now let's have a look on some more rules for using the cooperative_multitasking library.
5. There can also be procedures for changing states.
The procedures change_color_0(), change_color_1(), change_color_2() and change_color_3() do what their names suggest - they change the colors of their corresponding NeoPixels by using the helper procedure change_color(pixel). Then they wait an individual time span, and change the color again, wait again, change the color again and again...
The time spans are different (and relatively prime to each other), so every possible combination of colors will be displayed at some point.
Hey! What about rule 1? Where are the procedures for every possible NeoPixel state?
Um, well 😊... There is no rule without an exception. There are four NeoPixels with 256 different colors each. It would not be a good idea to represent that with more than 1000 procedures. That's why these states are encoded in the list colors from line 10.
6. There can be functions representing conditions.
CircuitPython does not support interrupts. So, how to implement the requirement that a touch resets the colors? The is_touched() and is_not_touched() functions in lines 34–38 are for this purpose.
These functions are used in the state procedures wait_for_color_reset() and color_reset().
The first of these procedures, wait_for_color_reset(), waits until the condition is_touched() is met for at least 300 milliseconds and then activates the second procedure.
The second procedure, color_reset(), resets all four colors and then waits until the condition is_not_touched() is met. Then it reactivates wait_for_color_reset() so that the next touch can be processed.
The priority=2 makes sure that detecting touches is more important than changing colors.
We have already seen something like the rest of the program in the first part of the guide: Choose what happens when the hardware is powered on (lines 48–52) and Let the hardware run (lines 54–55).
On power-on the program starts all four procedures for changing states and enters the state procedure wait_for_color_reset().
Try it yourselfIf you want to try the example:
- Update Neo Trinkey to CircuitPython 9.2.8, see https://learn.adafruit.com/adafruit-neo-trinkey/circuitpython#circuitpython-quickstart-3087052.
- Download cooperative_multitasking.mpy from https://bitbucket.org/amotzek/circuit-python/downloads/ and copy it to the lib folder of Neo Trinkey.
- Copy the source code of the example to code.py in the root directory of Neo Trinkey.
This was a not so simple example. Of queue with tasks, priorities and interrupts, we saw all three - by emulating interrupts with conditions. And the queue holds five tasks. The third part of this guide will have a complex example.
Comments