Setup ItsyBitsy M4 with CircuitPython
We'll need to get our board setup so we can run the CircuitPython code. Let's walk through these steps to get the latest version of CircuitPython onto your board.
The Mu Python Editor
Mu is a simple Python editor that works with Adafruit CircuitPython hardware. It's written in Python and works on Windows, MacOS, Linux and Raspberry Pi. The serial console is built right in, so you get immediate feedback from your board's serial output! While you can use any text editor with your code, Mu makes it super simple.
Installing or upgrading CircuitPython
You should ensure you have CircuitPython 4.0 or greater on your board. Plug your board in with a known good data + power cable (not the cheesy USB cable that comes with USB power packs, they are power only). You should see a new flash drive pop up.
If the drive is CIRCUITPY, then open the boot_out.txt file to ensure the version number is 4.0 or greater.
Adafruit CircuitPython 5.0.0-beta.0 on 2019-11-19; Adafruit ItsyBitsy M4 Express with samd51g19
Download the Adafruit CircuitPython Library Bundle
In order to run the code, we'll need to download a few libraries. Libraries contain code to help interface with hardware a lot easier for us.
Use the ItsyBitsy M4 page on Installing Libraries to get the library that matches the major version of CircuitPython you are using noted above, i.e. 4.x for the versiond starting with 4, 5.x for the versions starting with 5, etc.
To run the code for this project, we need the two libraries in the Required Libraries list below. Unzip the library bundle and search for the libraries. Drag and drop the files into a folder named lib on the CIRCUITPY drive (create the folder if it is not already on the ItsyBitsy M4).
Once we have all the files we need, a directory listing will look similar to above as far as files and directories.
Upload Code
Click on the download link below to grab the main code directly from GitHub. Rename the file to code.py and drop it onto the CIRCUITPY main (root) directory. The code will run properly when all of the files have been uploaded including libraries.
Use any text editor or favorite IDE to modify the code. We suggest using Mu as noted above.
# SPDX-FileCopyrightText: 2019 Phillip Burgess for Adafruit Industries # # SPDX-License-Identifier: MIT # pylint: disable=import-error """ NeoPixel goggles inspired by Rezz No interactive controls; speed, color and directions randomize periodically. """ from random import random, randrange from time import monotonic import board import neopixel import adafruit_fancyled.adafruit_fancyled as fancy # Configurable defaults BRIGHTNESS = 0.15 # 0.0 (off) to 1.0 (max brightness) # Global variables # Declare NeoPixel object. Data from ItsyBitsy pin 5 because it has built-in # level shifting. Each LED eye has 44 pixels, so 88 total. Leave brightness # at 1.0 here (NeoPixel library runs faster at full brightness) and adjust # the global BRIGHTNESS above instead (used later when selecting HSV colors). PIXELS = neopixel.NeoPixel( board.D5, 88, auto_write=False, brightness=1.0, pixel_order=neopixel.RGB) # MODE indicates the current animation state through several bit fields. # Bit 0 indicates the second eye is x-axis mirrored (1) or an exact copy # of the first (0). Bit 1 indicates hue is slowly cycling (2) vs holding # steady (0). Bit 2 indicates the middle of the 3 LED rings moves the # opposite (4) or same (0) direction as the other 2. MODE = randrange(8) # 0 to 7 # Every few seconds, one of the above attributes is randomly toggled. # This keeps track of the last time. TIME_OF_LAST_MODE_SWITCH = 0 # HUE works around the color wheel, see FancyLED docs. HUE = random() # Relative position of MIDDLE of 3 rings, 0 to 143 MIDDLE_POS = randrange(144) # Relative position of INNER and OUTER rings, 0 to 143 POS = randrange(144) # Amount to increment POS and MIDDLE_POS each frame SPEED = 2 + random() * 5 # The MIRROR_X and OFFSET(OUTER,MIDDLE,INNER) arrays precompute some values # for each pixel so we don't need to repeat that math every frame or LED. MIRROR_X = [] OFFSET_OUTER = [] OFFSET_MIDDLE = [] OFFSET_INNER = [] for i in range(24): MIRROR_X.append(67 - ((i + 11) % 24)) OFFSET_OUTER.append(i * 6) for i in range(16): MIRROR_X.append(83 - ((i + 7) % 16)) OFFSET_MIDDLE.append(i * 9) for i in range(4): MIRROR_X.append(87 - ((i + 2) % 4)) OFFSET_INNER.append(i * 36) def set_pixel(index, color): """Set one pixel in both eyes. Pass in pixel index (0 to 43) and color (as a packed RGB value). If MODE bit 0 is set, second eye will be X-axis mirrored, else an exact duplicate.""" # Set pixel in first eye PIXELS[index] = color # Set pixel in second eye (mirrored or direct) if MODE & 1: PIXELS[MIRROR_X[index]] = color else: PIXELS[44 + index] = color # Main loop, repeat indefinitely... while True: # Check if 5 seconds have passed since last mode switch NOW = monotonic() if (NOW - TIME_OF_LAST_MODE_SWITCH) > 5: # Yes. Save the time, change ONE mode bit, randomize speed TIME_OF_LAST_MODE_SWITCH = NOW MODE ^= 1 << randrange(3) SPEED = 2 + random() * 5 # Generate packed RGB value based on current HUE value COLOR = fancy.CHSV(HUE, 1.0, BRIGHTNESS).pack() # Draw outer ring; 24 pixels, 8 lit for i in range(24): j = (POS + OFFSET_OUTER[i]) % 72 if j < 24: set_pixel(i, COLOR) else: set_pixel(i, 0) # Draw middle ring; 16 pixels, 6 lit for i in range(16): j = (OFFSET_MIDDLE[i] + MIDDLE_POS) % 72 if j < 27: set_pixel(24 + i, COLOR) else: set_pixel(24 + i, 0) # Draw inner ring; 4 pixels, 3 lit for i in range(4): j = (POS + OFFSET_INNER[i]) % 144 if j < 108: set_pixel(40 + i, COLOR) else: set_pixel(40 + i, 0) # Push new state to LEDs PIXELS.show() # If MODE bit 1 is set, advance hue (else holds steady) if MODE & 2: HUE += 0.003 # Increment position of inner & outer ring POS = (POS + SPEED) % 144 # Middle ring advances one way or other depending on MODE bit 2 if MODE & 4: MIDDLE_POS = (MIDDLE_POS - SPEED) % 144 else: MIDDLE_POS = (MIDDLE_POS + SPEED) % 144
Text editor powered by tinymce.