GEMMA M0 boards can run CircuitPython — a different approach to programming compared to Arduino sketches. In fact, CircuitPython comes factory pre-loaded on GEMMA M0. If you’ve overwritten it with an Arduino sketch, or just want to learn the basics of setting up and using CircuitPython, this is explained in the Adafruit GEMMA M0 guide.
Below is CircuitPython code that works similarly (though not exactly the same) as the Arduino sketch shown on a prior page. To use this, plug the GEMMA M0 into USB…it should show up on your computer as a small flash drive…then edit the file “code.py” with your text editor of choice. Select and copy the code below and paste it into that file, entirely replacing its contents (don’t mix it in with lingering bits of old code). When you save the file, the code should start running almost immediately (if not, see notes at the bottom of this page).
If GEMMA M0 doesn’t show up as a drive, follow the GEMMA M0 guide link above to prepare the board for CircuitPython.
This code requires the neopixel.py library. A factory-fresh board will have this already installed. If you’ve just reloaded the board with CircuitPython, create the “lib” directory and then download neopixel.py from Github.
# SPDX-FileCopyrightText: 2014 HerrRausB https://github.com/HerrRausB # SPDX-FileCopyrightText: 2017 Mikey Sklar for Adafruit Industries # # SPDX-License-Identifier: LGPL-3.0-or-later # # 3D_Printed_NeoPixel_Ring_Hair_Dress.py # # this was ported to CircuitPython from the 'Gemma Hoop Animator' # # https://github.com/HerrRausB/GemmaHoopAnimator # # unless you # don't like the preset animations or find a # major bug, you don't need tochange anything here # import time import board import neopixel try: import urandom as random # for v1.0 API support except ImportError: import random from analogio import AnalogIn # available actions ACT_NOP = 0x00 # all leds off, do nothing ACT_SIMPLE_RING = 0x01 # all leds on ACT_CYCLING_RING_ACLK = 0x02 # anti clockwise cycling colors ACT_CYCLING_RING_CLKW = 0x04 # clockwise cycling colors ACT_WHEEL_ACLK = 0x08 # anti clockwise spinning wheel ACT_WHEEL_CLKW = 0x10 # clockwise spinning wheel ACT_SPARKLING_RING = 0x20 # sparkling effect numpix = 16 # total number of NeoPixels pixel_output = board.D0 # pin where NeoPixels are connected analog_input = board.A0 # needed to seed the random generator strip = neopixel.NeoPixel(pixel_output, numpix, brightness=.3, auto_write=False) # available color generation methods COL_RANDOM = 0x40 # colors will be generated randomly COL_SPECTRUM = 0x80 # colors will be set as cyclic spectral wipe # specifiyng the action list # the action's overall duration in milliseconds (be careful not action_duration = 0 # to use values > 2^16-1 - roughly one minute :-) action_and_color_gen = 1 # the color generation method # the duration of each action step rsp. the delay of the main action_step_duration = 2 # loop in milliseconds - thus, controls the action speed (be # careful not to use values > 2^16-1 - roughly one minute :-) color_granularity = 3 # controls the increment of the R, G, and B # portions of the rsp. color. 1 means the increment is 0,1,2,3,..., # 10 means the increment is 0,10,20,... don't use values > 255, and # note that even values > 127 wouldn't make much sense... # controls the speed of color changing independently from action color_interval = 4 # general global variables color = 0 color_timer = 0 action_timer = 0 action_step_timer = 0 color_idx = 0 curr_color_interval = 0 curr_action_step_duration = 0 curr_action_duration = 0 curr_action = 0 curr_color_gen = COL_RANDOM idx = 0 offset = 0 number_of_actions = 31 curr_action_idx = 0 curr_color_granularity = 1 spectrum_part = 0 # defining the animation actions by simply initializing the array of actions # this array variable must be called theactionlist !!! # # valid actions are: # ACT_NOP simply do nothing and switch everything off # ACT_SIMPLE_RING all leds on # ACT_CYCLING_RING_ACLK anti clockwise cycling colors # ACT_CYCLING_RING_CLKW clockwise cycling colors acording # ACT_WHEEL_ACLK anti clockwise spinning wheel # ACT_WHEEL_CLKW clockwise spinning wheel # ACT_SPARKLING_RING sparkling effect # # valid color options are: # COL_RANDOM colors will be selected randomly, which might # be not very sufficient due to well known # limitations of the random generation algorithm # COL_SPECTRUM colors will be set as cyclic spectral wipe # R -> G -> B -> R -> G -> B -> R -> ... # action action name & action step color color change # duration color generation method duration granularity interval theactionlist = [ [5, ACT_SPARKLING_RING | COL_RANDOM, 0.01, 25, 1], [2, ACT_CYCLING_RING_CLKW | COL_RANDOM, 0.02, 1, 0.005], [5, ACT_SPARKLING_RING | COL_RANDOM, 0.01, 25, 1], [2, ACT_CYCLING_RING_ACLK | COL_RANDOM, 0.02, 1, 0.005], [5, ACT_SPARKLING_RING | COL_RANDOM, 0.01, 25, 1], [2.5, ACT_CYCLING_RING_CLKW | COL_SPECTRUM, 0.25, 20, 0.020], [1, ACT_CYCLING_RING_CLKW | COL_SPECTRUM, 0.50, 1, 0.020], [.750, ACT_CYCLING_RING_CLKW | COL_SPECTRUM, 0.075, 1, 0.020], [.500, ACT_CYCLING_RING_CLKW | COL_SPECTRUM, 0.100, 1, 0.020], [.500, ACT_CYCLING_RING_CLKW | COL_SPECTRUM, 0.125, 1, 0.020], [.500, ACT_CYCLING_RING_CLKW | COL_SPECTRUM, 0.150, 1, 0.050], [.500, ACT_CYCLING_RING_CLKW | COL_SPECTRUM, 0.175, 1, 0.100], [.500, ACT_CYCLING_RING_CLKW | COL_SPECTRUM, 0.200, 1, 0.200], [.750, ACT_CYCLING_RING_CLKW | COL_SPECTRUM, 0.225, 1, 0.250], [1, ACT_CYCLING_RING_CLKW | COL_SPECTRUM, 0.250, 1, 0.350], [30, ACT_SIMPLE_RING | COL_SPECTRUM, 0.050, 1, 0.010], [2.5, ACT_WHEEL_ACLK | COL_SPECTRUM, 0.010, 1, 0.010], [2.5, ACT_WHEEL_ACLK | COL_SPECTRUM, 0.015, 1, 0.020], [2, ACT_WHEEL_ACLK | COL_SPECTRUM, 0.025, 1, 0.030], [1, ACT_WHEEL_ACLK | COL_SPECTRUM, 0.050, 1, 0.040], [1, ACT_WHEEL_ACLK | COL_SPECTRUM, 0.075, 1, 0.040], [1, ACT_WHEEL_ACLK | COL_SPECTRUM, 0.100, 1, 0.050], [.500, ACT_WHEEL_ACLK | COL_SPECTRUM, 0.125, 1, 0.060], [.500, ACT_WHEEL_CLKW | COL_SPECTRUM, 0.125, 5, 0.050], [1, ACT_WHEEL_CLKW | COL_SPECTRUM, 0.100, 10, 0.040], [1.5, ACT_WHEEL_CLKW | COL_SPECTRUM, 0.075, 15, 0.030], [2, ACT_WHEEL_CLKW | COL_SPECTRUM, 0.050, 20, 0.020], [2.5, ACT_WHEEL_CLKW | COL_SPECTRUM, 0.025, 25, 0.010], [3, ACT_WHEEL_CLKW | COL_SPECTRUM, 0.010, 30, 0.005], [5, ACT_SPARKLING_RING | COL_RANDOM, 0.010, 25, 1], [5, ACT_NOP, 0, 0, 0] ] # pylint: disable=global-statement def nextspectrumcolor(): global spectrum_part, color_idx, curr_color_granularity, color # spectral wipe from green to red if spectrum_part == 2: color = (color_idx, 0, 255-color_idx) color_idx += curr_color_granularity if color_idx > 255: spectrum_part = 0 color_idx = 0 # spectral wipe from blue to green elif spectrum_part == 1: color = (0, 255 - color_idx, color_idx) color_idx += curr_color_granularity if color_idx > 255: spectrum_part = 2 color_idx = 0 # spectral wipe from red to blue elif spectrum_part == 0: color = (255 - color_idx, color_idx, 0) color_idx += curr_color_granularity if color_idx > 255: spectrum_part = 1 color_idx = 0 def nextrandomcolor(): global color # granularity = 1 --> [0 .. 255] * 1 --> 0,1,2,3 ... 255 # granularity = 10 --> [0 .. 25] * 10 --> 0,10,20,30 ... 250 # granularity = 100 --> [0 .. 2] * 100 --> 0,100, 200 (boaring...) random_red = random.randint(0, int(256 / curr_color_granularity)) random_red *= curr_color_granularity random_green = random.randint(0, int(256 / curr_color_granularity)) random_green *= curr_color_granularity random_blue = random.randint(0, int(256 / curr_color_granularity)) random_blue *= curr_color_granularity color = (random_red, random_green, random_blue) def nextcolor(): # save some RAM for more animation actions if curr_color_gen & COL_RANDOM: nextrandomcolor() else: nextspectrumcolor() def setup(): # fingers corssed, the seeding makes sense to really get random colors... apin = AnalogIn(analog_input) random.seed(apin.value) apin.deinit() # let's go! nextcolor() strip.write() setup() while True: # Loop forever... # do we need to load the next action? if (time.monotonic() - action_timer) > curr_action_duration: current_action = theactionlist[curr_action_idx] curr_action_duration = current_action[action_duration] curr_action = current_action[action_and_color_gen] & 0x3F curr_action_step_duration = current_action[action_step_duration] curr_color_gen = current_action[action_and_color_gen] & 0xC0 curr_color_granularity = current_action[color_granularity] curr_color_interval = current_action[color_interval] curr_action_idx += 1 # take care to rotate the action list! curr_action_idx %= number_of_actions action_timer = time.monotonic() # do we need to change to the next color? if (time.monotonic() - color_timer) > curr_color_interval: nextcolor() color_timer = time.monotonic() # do we need to step up the current action? if (time.monotonic() - action_step_timer) > curr_action_step_duration: if curr_action: is_act_cycling = (ACT_CYCLING_RING_ACLK or ACT_CYCLING_RING_CLKW) if curr_action == ACT_NOP: # rather trivial even tho this will be repeated as long as the # NOP continues - i could have prevented it from repeating # unnecessarily, but that would mean more code and less # space for more actions within the animation for i in range(0, numpix): strip[i] = (0, 0, 0) elif curr_action == ACT_SIMPLE_RING: # even more trivial - just set the new color, if there is one for i in range(0, numpix): strip[i] = color elif curr_action == is_act_cycling: # spin the ring clockwise or anti clockwise if curr_action == ACT_CYCLING_RING_ACLK: idx += 1 else: idx -= 1 # prevent overflows or underflows idx %= numpix # set the new color, if there is one strip[idx] = color elif curr_action == ACT_WHEEL_ACLK or ACT_WHEEL_CLKW: # switch on / off the appropriate pixels according to # the current offset for idx in range(0, numpix): if ((offset + idx) & 7) < 2: strip[idx] = color else: strip[idx] = (0, 0, 0) # advance the offset and thus, spin the wheel if curr_action == ACT_WHEEL_CLKW: offset += 1 else: offset -= 1 # prevent overflows or underflows offset %= numpix elif curr_action == ACT_SPARKLING_RING: # switch current pixel off strip[idx] = (0, 0, 0) # pick a new pixel idx = random.randint(0, numpix) # set new pixel to the current color strip[idx] = color strip.write() action_step_timer = time.monotonic()
Text editor powered by tinymce.