To program your Circuit Playground Express board with CircuitPython code, first make sure your board is set up to use CircuitPython - check out the Quick Start guide for instructions.
Once your board is set up and attached to your computer via a micro USB cable, you should see it appear as an attached drive named "CIRCUITPY". (You may need to double-click the Reset button to make it appear.)
Copy the code below and save it as a file named "code.py" on the "CIRCUITPY" drive.
# SPDX-FileCopyrightText: 2017 Collin Cunningham for Adafruit Industries # # SPDX-License-Identifier: MIT # Circuit Playground Express CircuitPython Morse Code Flasher # This is meant to work with the Circuit Playground Express board: # https://www.adafruit.com/product/3333 # Needs the NeoPixel module installed: # https://github.com/adafruit/Adafruit_CircuitPython_NeoPixel # Author: Collin Cunningham # License: MIT License (https://opensource.org/licenses/MIT) import time import board import neopixel # Configuration: # Message to display (capital letters and numbers only) message = 'SOS' dot_length = 0.15 # Duration of one Morse dot dash_length = (dot_length * 3.0) # Duration of one Morse dash symbol_gap = dot_length # Duration of gap between dot or dash character_gap = (dot_length * 3.0) # Duration of gap between characters flash_color = (255, 0, 0) # Color of the morse display. brightness = 0.5 # Display brightness (0.0 - 1.0) morse = [ ('A', '.-'), ('B', '-...'), ('C', '-.-.'), ('D', '-..'), ('E', '.'), ('F', '..-.'), ('G', '--.'), ('H', '....'), ('I', '..'), ('J', '.---'), ('K', '-.-'), ('L', '.-..'), ('M', '--'), ('N', '-.'), ('O', '---'), ('P', '.--.'), ('Q', '--.-'), ('R', '.-.'), ('S', '...'), ('T', '-'), ('U', '..-'), ('V', '...-'), ('W', '.--'), ('X', '-..-'), ('Y', '-.--'), ('Z', '--..'), ('0', '-----'), ('1', '.----'), ('2', '..---'), ('3', '...--'), ('4', '....-'), ('5', '.....'), ('6', '-....'), ('7', '--...'), ('8', '---..'), ('9', '----.'), ] # Define a class that represents the morse flasher. class MorseFlasher: def __init__(self, color=(255, 255, 255)): # set the color adjusted for brightness self._color = ( int(color[0] * brightness), int(color[1] * brightness), int(color[2] * brightness) ) def light(self, on=True): if on: pixels.fill(self._color) else: pixels.fill((0, 0, 0)) pixels.show() def showDot(self): self.light(True) time.sleep(dot_length) self.light(False) time.sleep(symbol_gap) def showDash(self): self.light(True) time.sleep(dash_length) self.light(False) time.sleep(symbol_gap) def encode(self, string): output = "" # iterate through string's characters for c in string: # find morse code for a character for x in morse: if x[0] == c: # add code to output output += x[1] # add a space in between characters output += " " # save complete morse code output to display self.display(output) def display(self, code=".-.-.- "): # iterate through morse code symbols for c in code: # show a dot if c == ".": self.showDot() # show a dash elif c == "-": self.showDash() # show a gap elif c == " ": time.sleep(character_gap) # Initialize NeoPixels pixels = neopixel.NeoPixel(board.NEOPIXEL, 10, auto_write=False) pixels.fill((0, 0, 0)) pixels.show() # Create a morse flasher object. flasher = MorseFlasher(flash_color) # Main loop will run forever while True: flasher.encode(message)
Once the new code.py file is saved, the board should restart and start displaying the SOS message in Morse code.
You should see flashes that correspond to the following sequence:
. . . - - - . . .
A Tour of the Code
So, what is all this CircuitPython code doing? Let’s take a look piece by piece …
Imports
First off, we import code libraries that allow us to do complex things with simple commands …
import time import board import neopixel
message = 'SOS' # Message to display (capital letters and numbers only) dot_length = 0.15 # Duration of one Morse dot dash_length = (dot_length * 3.0) # Duration of one Morse dash symbol_gap = dot_length # Duration of gap between dot or dash character_gap = (dot_length * 3.0) # Duration of gap between characters flash_color = (255, 0, 0) # Color of the morse display. brightness = 0.5 # Display brightness (0.0 - 1.0) morse = [('A', '.-'), ('B', '-...'), ('C', '-.-.'), ('D', '-..'), ('E', '.'), ('F', '..-.'), ('G', '--.'), ('H', '....'), ('I', '..'), ('J', '.---'), ('K', '-.-'), ('L', '.-..'), ('M', '--'), ('N', '-.'), ('O', '---'), ('P', '.--.'), ('Q', '--.-'), ('R', '.-.'), ('S', '...'), ('T', '-'), ('U', '..-'), ('V', '...-'), ('W', '.--'), ('X', '-..-'), ('Y', '-.--'), ('Z', '--..'), ('0', '-----'), ('1', '.----'), ('2', '..---'), ('3', '...--'), ('4', '....-'), ('5', '.....'), ('6', '-....'), ('7', '--...'), ('8', '---..'), ('9', '----.')]
message
is the string of letters or numbers we want to display in Morse code.
dot_length
is the length of time (in seconds) one morse dot will take to display. dot_length
is also used to determine the value of all the other time variables (dash_length
, symbol_gap
, & character_gap
) So, if you change dot_length
, all the other time variables will change in relation to it.
flash_color
is the color the LEDs will show when they flash.
brightness
determines how bright the flashes will be.
Finally, the morse
variable is an array of value pairs called “tuples”. Each tuple contains two values - the first one is the readable character we want to display in Morse code and the second is the sequence of Morse dots and dashes we’ll use to display that readable character.
MorseFlasher Object
Next up, we define the MorseFlasher object which will translate our readable characters to Morse code and handle all the LED flashing. It looks pretty big, but it's not too complicated once you break it down …
class MorseFlasher: def __init__(self, color=(255,255,255)): #set the color adjusted for brightness self._color = (int(color[0]*brightness), int(color[1]*brightness), int(color[2]*brightness)) def light(self, on=True): if on: pixels.fill(self._color) else: pixels.fill((0,0,0)) pixels.show() def showDot(self): self.light(True) time.sleep(dot_length) self.light(False) time.sleep(symbol_gap) def showDash(self): self.light(True) time.sleep(dash_length) self.light(False) time.sleep(symbol_gap) def encode(self, str): output = "" #iterate through string's characters for c in str: #find morse code for a character for x in morse: if x[0] == c: #add code to output output += x[1] # add a space in between characters output += " " #save complete morse code output to display self.display(output) def display(self, code=".-.-.- "): # iterate through morse code symbols for c in code: # show a dot if c == ".": self.showDot() # show a dash elif c == "-": self.showDash() # show a gap elif c == " ": time.sleep(character_gap)
Within the MorseFlasher
object, there are several functions that define how it works:
The __init__
function creates the MorseFlasher object and sets the color that it will show by multiplying an initial color by the brightness
variable.
The light
function turns the LEDs on or off depending on a given boolean (True or False) value.
The showDot
function turns the LEDs on, waits for one dot_length
, then turns them off and waits for one gap_length
.
The showDash
function turns the LEDs on, waits for one dash_length
, then turns them off and waits for one gap_length
.
The encode
function takes a message and translates it into morse code using the morse
array variable. It takes each character from the message, finds that character’s morse code from the array of tuples, and adds that code to a variable named output
. Once all the characters in the message have been translated, the display
function is called and given the output
variable.
Finally, the display
function takes a string of morse code (dots, dashes, and spaces) and converts into LED flashes. One by one, it checks each character in the code. If it finds a dot, it will call the show_dot
function. If it finds a dash, it will call the show_dash
function. And if it finds a space, it will wait for the length of one character_gap
.
Let's do this!
Once all of our functions have been defined, it’s time to get the party started and use all that code we've written above …
# Initialize NeoPixels pixels = neopixel.NeoPixel(board.NEOPIXEL, 10, auto_write=False) pixels.fill((0, 0, 0)) pixels.show() # Create a morse flasher object. flasher = MorseFlasher(flash_color) # Main loop will run forever while True: flasher.encode(message)
In order to easily control our LEDs, we create pixels
which is a Neopixel
object from the neopixel
library we imported earlier. We want to make sure the LEDs are all turned off at the start, so we set them to black (0, 0, 0)
and call pixels.show()
to show the colors we just set.
Next we create the MorseFlasher
object named flasher
and we give it the color we want the LEDs to flash.
Finally - we set all the gears in motion. Inside the main loop (while True:
) we call the flasher object’s encode
function and give it our message
to display. Once the function has completed and shown the message
, the main loop will begin again and our message
will be displayed - FOREVER! … or at least until you disconnect power or reprogram the Circuit Playground board ;)
Text editor powered by tinymce.