First, follow this guide https://learn.adafruit.com/adafruit-gemma-m0/circuitpython to get started with coding the Gemma M0 in CircuitPython. Install the latest release version of CircuitPython on the board.
You may also want to install the Mu editor https://learn.adafruit.com/adafruit-gemma-m0/installing-mu-editor for your coding needs.
Once you can successfully code in Mu and upload to the board, return here.
Ringtones to the Rescue
If you want to write short little ditties, there's an established format we can use: RTTL (Ring Tone Text Transfer Language) that was originally developed by Nokia for cellphone ringtones.
We've written a library to make it easy to use RTTTL in CircuitPython. You can download the library as part the CircuitPython Bundle, and then drag a copy of the adafruit_rtttl into your Gemma M0 lib folder. (Check this page if you have questions about CircuitPython libraries.)
Then, to test it out and hear a familiar spy theme, copy the code below, paste it into Mu, and then save it to your Gemma M0 as main.py (if you want to run this code on a Circuit Playground Express, see below for alternate code.)
import adafruit_rtttl import board adafruit_rtttl.play(board.A2, "Bond:d=4,o=5,b=320:c,8d,8d,d,2d,c,c,c,c,8d#,8d#,2d#,d,d,d,c,8d,8d,d,2d,c,c,c,c,8d#,8d#,d#,2d#,d,c#,c,c6,1b.,g,f,1g.")
You can see that there isn't too much to it -- we import the rtttl library, and then we can use the adafruit_rtttl.play()
command. This command takes three elements: name, settings, and notes, all separated by a colon :
The song name element in this case is Bond
.
The settings elements specify:
-
d
for duration of a default note, in this case a4
means a quarter note. This is a convenience that allows you to not specify the duration of all the quarter notes. -
o
for the default octave of the song, the range is4
to7
. Here it is set to5
-
b
is the tempo ("beat") of the song in BPM (beats per minute) in this case320
Then we get to the final element, the notes. So, for the first few notes of the Bond theme intro we have c,8d,8d,d,2d,c,c,c,c
which is a C quarter note, two D eighth notes, a D quarter note, a D half note and four C quarter notes. Note, you can also use # for sharps.
Try writing your own tunes, or search online for ringtones published in the RTTTL format.
Here's another favorite:
import adafruit_rtttl import board adafruit_rtttl.play(board.D0, "The A Team:d=8,o=5,b=132:4d#6,a#,2d#6,16p,g#,4a#,4d#.,p,16g,16a#,d#6,a#,f6,2d#6,16p,c#.6,16c6,16a#,g#.,2a#.")
# rtttl example for Circuit Playground Express import board from digitalio import DigitalInOut, Direction import adafruit_rtttl spkrenable = DigitalInOut(board.SPEAKER_ENABLE) spkrenable.direction = Direction.OUTPUT spkrenable.value = True adafruit_rtttl.play(board.A0, "Bond:d=4,o=5,b=320:c,8d,8d,d,2d,c,c,c,c,8d#,8d#,2d#,d,d,d,c,8d,8d,d,2d,c,c,c,c,8d#,8d#,d#,2d#,d,c#,c,c6,1b.,g,f,1g.")
Longer Compositions
The RTTTL format works great for short songs -- after all, that's why it was originally designed. Longer songs, however, can get a bit messy if we simply string together note after note after note after note! Even traditional sheet music notation uses repeat signs and codas to avoid writing out one long, linear song!
So, we'll create a number of lists that each contain phrases or measures of the song that are repeated throughout, then we can reference those lists in a larger roadmap for the whole song.
tone Test
First, we'll use the built-in pulsio
function to play some test tones over the piezo buzzer connected to D0 and GND.
Copy the code below, paste it into Mu and then save it to your Gemma M0 to test out the tone example.
# SPDX-FileCopyrightText: 2018 Kattni Rembor for Adafruit Industries # # SPDX-License-Identifier: MIT """CircuitPython Essentials PWM with variable frequency piezo example""" import time import board import pwmio # For the M0 boards: piezo = pwmio.PWMOut(board.A2, duty_cycle=0, frequency=440, variable_frequency=True) # For the M4 boards: # piezo = pwmio.PWMOut(board.A1, duty_cycle=0, frequency=440, variable_frequency=True) while True: for f in (262, 294, 330, 349, 392, 440, 494, 523): piezo.frequency = f piezo.duty_cycle = 65535 // 2 # On 50% time.sleep(0.25) # On for 1/4 second piezo.duty_cycle = 0 # Off time.sleep(0.05) # Pause between notes time.sleep(0.5)
In the first example, we have the James Bond 007 Theme. Note how we create lists for each section -- Bond01, Bond02, and so on -- and then call them at the bottom of the code in the while True:
loop. See how the Bond01 section repeats twice, then the Bond02 and Bond03 pairings repeat twice more before, calling in Bond04. The opening phrase is again repeated a number of times right before the songs final passage.
First, we set up the pulseio
output as before.
Then, we create a variable called tempo
to define the length of a whole note, in this case 2 seconds. You can adjust that to increase or decrease the tempo. All note lengths are derived from this one variable, e.g.whole_note
is equal to tempo
, half_note
is a whole_note * 0.5
and so on.
Similarly, we create a series of variables to define the pitches different notes, starting from A2 (110Hz) up to B6 (1974Hz). This way, we can call the pitches with a note name instead of a frequency value. This makes it much easier to transcribe from standard music notation!
Here's the James Bond 007 Theme. Copy it and paste it into Mu, then save it to your Gemma M0 as main.py
It will play through once -- if you want to repeat it, simply press reset, or turn the board off and then on.
# SPDX-FileCopyrightText: 2018 John Edgar Park for Adafruit Industries # # SPDX-License-Identifier: MIT """ Plays the 007 theme song Gemma M0 with Piezo on D0 and GND """ import time import board import pwmio piezo = pwmio.PWMOut(board.D0, duty_cycle=0, frequency=440, variable_frequency=True) tempo = 2 # tempo is length of whole note in seconds, e.g. 1.5 # set up time signature whole_note = tempo # adjust this to change tempo of everything dotted_whole_note = whole_note * 1.5 # these notes are fractions of the whole note half_note = whole_note / 2 dotted_half_note = half_note * 1.5 quarter_note = whole_note / 4 dotted_quarter_note = quarter_note * 1.5 eighth_note = whole_note / 8 dotted_eighth_note = eighth_note * 1.5 sixteenth_note = whole_note / 16 # set up note values A2 = 110 As2 = 117 # 's' stands for sharp: A#2 Bb2 = 117 B2 = 123 C3 = 131 Cs3 = 139 Db3 = 139 D3 = 147 Ds3 = 156 Eb3 = 156 E3 = 165 F3 = 175 Fs3 = 185 Gb3 = 185 G3 = 196 Gs3 = 208 Ab3 = 208 A3 = 220 As3 = 233 Bb3 = 233 B3 = 247 C4 = 262 Cs4 = 277 Db4 = 277 D4 = 294 Ds4 = 311 Eb4 = 311 E4 = 330 F4 = 349 Fs4 = 370 Gb4 = 370 G4 = 392 Gs4 = 415 Ab4 = 415 A4 = 440 As4 = 466 Bb4 = 466 B4 = 494 C5 = 523 Cs5 = 554 Db5 = 554 D5 = 587 Ds5 = 622 Eb5 = 622 E5 = 659 F5 = 698 Fs5 = 740 Gb5 = 740 G5 = 784 Gs5 = 831 Ab5 = 831 A5 = 880 As5 = 932 Bb5 = 932 B5 = 987 # here's another way to express the note pitch, double the previous octave C6 = C5 * 2 Cs6 = Cs5 * 2 Db6 = Db5 * 2 D6 = D5 * 2 Ds6 = Ds5 * 2 Eb6 = Eb5 * 2 E6 = E5 * 2 F6 = F5 * 2 Fs6 = Fs5 * 2 Gb6 = Gb5 * 2 G6 = G5 * 2 Gs6 = Gs5 * 2 Ab6 = Ab5 * 2 A6 = A5 * 2 As6 = As5 * 2 Bb6 = Bb5 * 2 B6 = B5 * 2 rst = 24000 # rest is just a tone out of normal hearing range Bond01 = [[B3, half_note], [C4, half_note], [Cs4, half_note], [C4, half_note]] Bond02 = [[E3, eighth_note], [Fs3, sixteenth_note], [Fs3, sixteenth_note], [Fs3, eighth_note], [Fs3, eighth_note], [Fs3, eighth_note], [E3, eighth_note], [E3, eighth_note], [E3, eighth_note]] Bond03 = [[E3, eighth_note], [G3, sixteenth_note], [G3, sixteenth_note], [G3, eighth_note], [G3, eighth_note], [G3, eighth_note], [Fs3, eighth_note], [Fs3, eighth_note], [Fs3, eighth_note]] Bond04 = [[E3, eighth_note], [G3, sixteenth_note], [G3, sixteenth_note], [G3, eighth_note], [G3, eighth_note], [G3, eighth_note], [Fs3, eighth_note], [Fs3, eighth_note], [E3, eighth_note]] Bond05 = [[Ds4, eighth_note], [D4, eighth_note], [D4, half_note], [B3, eighth_note], [A3, eighth_note], [B3, whole_note]] Bond06 = [[E4, eighth_note], [G4, quarter_note], [Ds5, eighth_note], [D5, quarter_note], [D5, eighth_note], [G4, eighth_note], [As4, eighth_note], [B4, eighth_note], [B4, half_note], [B4, quarter_note]] Bond07 = [[G4, quarter_note], [A4, sixteenth_note], [G4, sixteenth_note], [Fs4, quarter_note], [Fs4, eighth_note], [B3, eighth_note], [E4, eighth_note], [Cs4, eighth_note], [Cs4, whole_note]] Bond08 = [[G4, quarter_note], [A4, sixteenth_note], [G4, sixteenth_note], [Fs4, quarter_note], [Fs4, eighth_note], [B3, eighth_note], [Ds4, eighth_note], [E4, eighth_note], [E4, whole_note]] Bond09 = [[E4, eighth_note], [E4, quarter_note], [E4, eighth_note], [Fs4, eighth_note], [Fs4, sixteenth_note], [E4, eighth_note], [Fs4, quarter_note]] Bond10 = [ [G4, eighth_note], [G4, quarter_note], [G4, eighth_note], [Fs4, eighth_note], [Fs4, sixteenth_note], [G4, eighth_note], [Fs4, quarter_note]] Bond11 = [[B4, eighth_note], [B4, eighth_note], [rst, eighth_note], [B3, eighth_note], [B3, quarter_note], [B4, eighth_note], [B4, eighth_note], [rst, eighth_note], [B3, eighth_note], [B3, quarter_note], [B4, sixteenth_note], [B4, eighth_note], [B4, sixteenth_note], [B4, eighth_note], [B4, eighth_note]] Bond12 = [[E3, eighth_note], [G3, quarter_note], [Ds4, eighth_note], [D4, quarter_note], [G3, eighth_note], [B3, quarter_note], [Fs4, eighth_note], [F4, quarter_note], [B3, eighth_note], [D4, quarter_note], [As4, eighth_note], [A4, quarter_note], [F4, eighth_note], [A4, quarter_note], [Ds5, eighth_note], [D5, quarter_note], [rst, eighth_note], [rst, quarter_note], [Fs4, whole_note]] def song_playback(song): for note in song: piezo.frequency = (note[0]) piezo.duty_cycle = 65536 // 2 # on 50% time.sleep(note[1]) # note duration piezo.duty_cycle = 0 # off time.sleep(0.01) # this plays the full song roadmap song_playback(Bond01) song_playback(Bond01) song_playback(Bond02) song_playback(Bond03) song_playback(Bond02) song_playback(Bond03) song_playback(Bond02) song_playback(Bond04) song_playback(Bond05) song_playback(Bond06) song_playback(Bond07) song_playback(Bond06) song_playback(Bond08) song_playback(Bond09) song_playback(Bond10) song_playback(Bond09) song_playback(Bond10) song_playback(Bond11) song_playback(Bond01) song_playback(Bond01) song_playback(Bond01) song_playback(Bond01) song_playback(Bond05) song_playback(Bond12)
Here's another fun one -- Where in the World is Carmen Sandiego:
# SPDX-FileCopyrightText: 2018 John Edgar Park for Adafruit Industries # # SPDX-License-Identifier: MIT """ Plays the Carmen Sandiego theme song Gemma M0 with Piezo on D0 and GND """ import time import board import pwmio piezo = pwmio.PWMOut(board.D0, duty_cycle=0, frequency=440, variable_frequency=True) tempo = 1.6 # tempo is length of whole note in seconds, e.g. 1.5 # set up time signature whole_note = tempo # adjust this to change tempo of everything dotted_whole_note = whole_note * 1.5 # these notes are fractions of the whole note half_note = whole_note / 2 dotted_half_note = half_note * 1.5 quarter_note = whole_note / 4 dotted_quarter_note = quarter_note * 1.5 eighth_note = whole_note / 8 dotted_eighth_note = eighth_note * 1.5 sixteenth_note = whole_note / 16 # set up note values A2 = 110 As2 = 117 # 's' stands for sharp: A#2 Bb2 = 117 B2 = 123 C3 = 131 Cs3 = 139 Db3 = 139 D3 = 147 Ds3 = 156 Eb3 = 156 E3 = 165 F3 = 175 Fs3 = 185 Gb3 = 185 G3 = 196 Gs3 = 208 Ab3 = 208 A3 = 220 As3 = 233 Bb3 = 233 B3 = 247 C4 = 262 Cs4 = 277 Db4 = 277 D4 = 294 Ds4 = 311 Eb4 = 311 E4 = 330 F4 = 349 Fs4 = 370 Gb4 = 370 G4 = 392 Gs4 = 415 Ab4 = 415 A4 = 440 As4 = 466 Bb4 = 466 B4 = 494 C5 = 523 Cs5 = 554 Db5 = 554 D5 = 587 Ds5 = 622 Eb5 = 622 E5 = 659 F5 = 698 Fs5 = 740 Gb5 = 740 G5 = 784 Gs5 = 831 Ab5 = 831 A5 = 880 As5 = 932 Bb5 = 932 B5 = 987 # here's another way to express the note pitch, double the previous octave C6 = C5 * 2 Cs6 = Cs5 * 2 Db6 = Db5 * 2 D6 = D5 * 2 Ds6 = Ds5 * 2 Eb6 = Eb5 * 2 E6 = E5 * 2 F6 = F5 * 2 Fs6 = Fs5 * 2 Gb6 = Gb5 * 2 G6 = G5 * 2 Gs6 = Gs5 * 2 Ab6 = Ab5 * 2 A6 = A5 * 2 As6 = As5 * 2 Bb6 = Bb5 * 2 B6 = B5 * 2 rst = 24000 # rest is just a tone out of normal hearing range carmen01 = [[As4, quarter_note], [As4, eighth_note], [rst, eighth_note], [rst, sixteenth_note], [B4, eighth_note], [rst, sixteenth_note], [B4, eighth_note], [B4, eighth_note]] carmen02 = [[Gs4, quarter_note], [Gs4, eighth_note], [rst, eighth_note], [rst, sixteenth_note], [Gs4, eighth_note], [rst, sixteenth_note], [Gs4, eighth_note], [B4, eighth_note]] carmen03 = [[Gs4, quarter_note], [Gs4, eighth_note], [rst, eighth_note], [rst, quarter_note], [Cs4, eighth_note], [Cs4, eighth_note]] carmen04 = [[As4, eighth_note], [As4, sixteenth_note], [As4, eighth_note], [As4, eighth_note], [B4, sixteenth_note], [B4, quarter_note], [B4, eighth_note], [B4, eighth_note]] carmen05 = [[Gs4, eighth_note], [Fs4, eighth_note], [Gs4, eighth_note], [Fs4, sixteenth_note], [Cs5, sixteenth_note], [Cs5, sixteenth_note], [As4, eighth_note], [As4, sixteenth_note], [Fs4, eighth_note], [Fs4, eighth_note]] carmen06 = [[Gs4, eighth_note], [Fs4, eighth_note], [Gs4, eighth_note], [Fs4, sixteenth_note], [Gs4, sixteenth_note], [Gs4, sixteenth_note], [Gs4, eighth_note], [rst, eighth_note], [rst, eighth_note], [Fs4, eighth_note]] carmen07 = [[Gs4, eighth_note], [Fs4, eighth_note], [Gs4, eighth_note], [Fs4, sixteenth_note], [Cs5, sixteenth_note], [Cs5, sixteenth_note], [As4, eighth_note], [As4, sixteenth_note], [Gs4, eighth_note], [Fs4, eighth_note]] carmen08 = [[Fs4, eighth_note], [rst, eighth_note], [Fs4, eighth_note], [Fs4, eighth_note], [Gs4, eighth_note], [rst, eighth_note], [Gs4, eighth_note], [rst, eighth_note], [E3, eighth_note], [E3, eighth_note], [E3, eighth_note], [E3, sixteenth_note], [Fs3, eighth_note], [Fs3, eighth_note], [rst, quarter_note]] def song_playback(song): for n in range(len(song)): piezo.frequency = (song[n][0]) piezo.duty_cycle = 65536 // 2 # on 50% time.sleep(song[n][1]) # note duration piezo.duty_cycle = 0 # off time.sleep(0.01) song_playback(carmen01) song_playback(carmen02) song_playback(carmen01) song_playback(carmen03) song_playback(carmen04) song_playback(carmen05) song_playback(carmen04) song_playback(carmen06) song_playback(carmen04) song_playback(carmen07) song_playback(carmen08) song_playback(carmen08)
Text editor powered by tinymce.