2.14. Exercise: Theremin#
Navigate to the MicroPython editor https://python.microbit.org/v/3. If you already have it open, then use that existing window or tab.
Connect your micro:bit using the instructions on the previous page
Enter the following code into the editor
from microbit import *
pitch = 0
sound = audio.SoundEffect(
freq_start=pitch,
freq_end=pitch,
duration=60,
vol_start=255,
vol_end=255,
waveform=audio.SoundEffect.WAVEFORM_SQUARE,
fx=audio.SoundEffect.FX_NONE,
shape=audio.SoundEffect.SHAPE_LINEAR,
)
def clip(val, min_val=-1200, max_val=1200):
return min(max(val, min_val), max_val)
while True:
x = accelerometer.get_x()
pitch_new = int(scale(clip(x), from_=(-1200, 1200), to=(20, 400)))
print(x, pitch_new)
sound.freq_start = pitch
sound.freq_end = pitch_new
pitch = pitch_new
audio.play(sound, wait=False)
if button_a.is_pressed():
speaker.off()
elif button_b.is_pressed():
speaker.on()
sleep(50)
The code does the following:
Create a new SoundEffect object
Repeat forever:
Measure the x-axis of the accelerometer
Convert the acceleration into a pitch between 500 and 1000Hz
Set the sound effect’s starting pitch to the current value and the ending pitch to the new value
Play the sound effect
Check if any of the buttons are pressed to mute/unmute the speaker
Sleep for 100 milliseconds
Flash the code to your micro:bit.
If you get stuck ask a peer or your teacher for help!
Question 1
Extend your code so that:
The z-axis controls the volume
Solution
from microbit import *
pitch = 0
volume = 0
sound = audio.SoundEffect(
freq_start=pitch,
freq_end=pitch,
duration=60,
vol_start=volume,
vol_end=volume,
waveform=audio.SoundEffect.WAVEFORM_SQUARE,
fx=audio.SoundEffect.FX_NONE,
shape=audio.SoundEffect.SHAPE_LINEAR
)
def clip(val, min_val=-1200, max_val=1200):
return min( max(val, min_val), max_val)
while True:
x, y, z = accelerometer.get_values()
pitch_new = int(scale(clip(x), from_=(-1200, 1200), to=(20, 400)))
volume_new = int(scale(clip(y), from_=(-1200, 1200), to=(0, 255)))
print(x, pitch_new, y, volume_new)
sound.freq_start = pitch
sound.freq_end = pitch_new
pitch = pitch_new
sound.vol_start = volume
sound.vol_end = volume_new
volume = volume_new
audio.play(sound, wait=False)
if button_a.is_pressed():
speaker.off()
elif button_b.is_pressed():
speaker.on()
sleep(50)
Extension: Question 2
Make one or more of the following modifications:
The magnetomer controls the pitch
The buttons step up or down the frequency range of the theremin