Instructions
FTF: Making music on a microcontroller, instructions¶
Welcome to our session at FTF! If you have any questions, please just give a shout. We are here to help.
In this session we'll work through 6 examples together. We will demonstrate everything, but this document should help you in case you're stuck. We also have optional sections in case you want to go further.
If you happen to be much faster than everyone else, help your neighbors.
Setup¶
- Connect the FRDM-K64F board to your computer. There are two micro-USB ports on the board, use the "SDAUSB" one (next to reset button)!
- The board mounts as a mass-storage device (like a USB drive). Verify that you can see it (drive name will be MBED).
- Go to http://developer.mbed.org
- Create an ARM mbed account if you do not have one.
- On the top right corner, click the Compiler button.
An IDE should open. Congratulations!
On Windows: To see debug messages, install the serial driver. (Note: this should be done already on the NXP laptops provided for FTF labs)
Debug messages: We can talk to the board via a serial port, but you might need some software. Read this doc and install required software (like PuTTY or Tera Term on Windows). (Note: NXP laptops have Tera Term 4.83 pre-installed)
Locally: If you like things locally, you can do so by exporting to a supported toolchain.
I very much recommend to just use the online IDE, as it makes it easier for us, but if you want to continue hacking in the future, this is a nice way.
1. Blinky¶
- First we need to set up our project and our target. In a new browser window, open https://developer.mbed.org/platforms/FRDM-K64F/ and click the Add to your mbed Compiler button.
- Go back to the compiler browser window and click F5 to refresh the page.
- Click the Import button, then click "Click Here to import from URL"
- Paste the URL https://developer.mbed.org/teams/MakingMusicWorkshop/code/1_blinky/
- Double click to open main.cpp
- We need to implement a function that will blink the LED.
Under ' YOUR CODE HERE' add the following code
static void blinky() { // the LED is either on or off (a 1 or a 0). We can inverse the value with the `!` (inverse operator). // the flipped value is what we write back to the LED, thus toggling the LED. red = !red; }
- Now press Compile
- A file downloads (blinky.bin)
- Drag the file to the 'MBED' disk
- The green LED next to the USB cable will flash.
- After flashing, hit the 'Reset' button (next to the USB cable) to start the program.
- Blinky runs!
Optional: We use Ticker to periodically run the blinky function. You could also use TimeOut to run a function after a specified delay.
2. Two buttons, two colors¶
- Now import https://developer.mbed.org/teams/MakingMusicWorkshop/code/2_two_buttons/
- Open main.cpp
- We want to execute a function when the button is pressed
- We already have code in place which responds when the buttons 'fall', which means the button is pressed
- Let's write similar code as before, but now with two functions (one for green, one for red)
- Under ' YOUR CODE HERE' add the following code
static void toggle_red() { red = !red; } static void toggle_green() { green = !green; }
- Hit the Compile button and flash the application. Clicking SW2 and SW3 will now toggle the LEDs. Having them both on will also allow you to create yellow.
Optional: We use `fall` currently, which triggers when the button is clicked. We can also use `rise` to get an event when the button is no longer clicked. Change the code so that the LEDs only burn when the button is pressed down.
Optional 2: When we start a periodic timer with a ticker, we can cancel the timer as well via:
<name_of_ticker>.detach();
Optional 3: Use the above pattern to combine part 1 and part 2. You could start the blinking when a button is pressed, then stop the blinking when the button is pressed a second time.
3. Sound instead of color¶
- Now import https://developer.mbed.org/teams/MakingMusicWorkshop/code/3_sound/
- We have a buzzer, which we can use instead of the color as an output
- If the buzzer is not yet connected to your board, connect it. See lab staff for help.
- We use pulse width modulation to create the square waves, the buzzer is connected to pin 3
- We have a `play_tone` function, now let's hook it up...
- Under ' YOUR CODE HERE' add the following code
static void play_note1() { play_tone(NOTE_C4, 200); } static void play_note2() { play_tone(NOTE_D4, 200); }
- Build and flash, when hitting the buttons you'll now get sound (a C and a D tone)
- Try and play with different tones and tone lengths
Optional: Currently tones have fixed length. Change the code to play a tone when the button fall's, and call silence when button rise's. This should give you the ability to play some small (two-tone) songs. The next example project, '4_accelerometer', will provide hints.
Connecting the buzzer¶
If you disconnected the buzzer by accident, no worries! Here's how you reconnect it:
Your buzzer has four pins (red, black, yellow and white). Plug the red, black and yellow cables in according to the schema above (white is unused). Always use the outer lane on the board, not the inner pins.
red=3.3V, black=GND, yellow=D3.
4. More inputs!¶
- Now import https://developer.mbed.org/teams/MakingMusicWorkshop/code/4_accelerometer/
- We're going to use the accelerometer movement detector to play a sound too, this means we can knock the board on a table and get a sound
- A new library is included which does this for you already
- At the bottom of main.cpp you'll see initialization logic for the accelerometer
- When the accelerometer triggers (movement detected), we can execute some code again
- Under ' YOUR CODE HERE' add the following code:
static void play_note3() { play_tone(NOTE_E4); tone_timeout.attach(&silence, 0.2); // setup tone_timeout to call silence after 200 duration ms }
- We manually call `silence` now to get predictable behavior
- Try and change the code to use `accel_interrupt_pin.rise` to silence instead (remove the timeout call from play_note3 as well). See what it does.
- Change the notes and play some simple melodies
Optional: You can read the data from the accelerometer (x, y, z axis) via:
static void read_accel() { SRAWDATA accel_data; SRAWDATA magnet_data; accel.get_data(&accel_data, &magnet_data); // this will show up in PuTTY printf("x=%d y=%d z=%d\r\n", accel_data.x, accel_data.y, accel_data.z); }
Use a ticker to read the data every 10 ms., then use the value from the accelerometer (e.g. `accel_data.z`) and feed it into `play_tone` function. We can now change the sound depending on how you hold the device in physical space. Allow to pause the sound by pressing one of the buttons.
You can play with the distribution of the tone. Just feeding the raw data into the algorithm doesn't generate the nicest effect.
5. Songs¶
- Now import https://developer.mbed.org/teams/MakingMusicWorkshop/code/5_songs/
- We can play tones from various inputs, but we could also play songs that we program in
- We create a simple format to write notes (in main).
- Now we need to write the code that will play this format.
- Our `play_song` function takes 3 arguments:
- The number of notes left
- The notes left (as a pointer)
- The durations left (as a pointer)
- Every time we play a note we subtract 1 from the notes left, and up the notes and durations. When we reach 0 we're done.
- We add a pause between each note as well.
- Under 'YOUR CODE HERE' insert:
// melody and duration are pointers, they point to the array of tones and durations we declared earlier // every time we play a note we up these pointers (move one element forward) // so the current tone is always the first element of melody (same for duration) int length; while(notes_left > 0) { int tone = melody[0]; // BPM is quarter notes per minute, so length in milliseconds is: length = static_cast<int>(static_cast<float>(1000 / duration[0]) * (60000.0f / static_cast<float>(BPM * 1000))); play_tone(tone); // after half the length of this tone, we silence wait_ms(length / 2); silence(); //after the full length of this tone, call next note wait_ms(length); // after the full length of this tone, we up the melody, and down the notes_left notes_left--; melody++; duration++; } // we're done! just finish this note and silence wait_ms(length / 2); silence();
- Delete the pause between the notes, what do you hear?
- Find some melody and program it in, make some of your own music. Play with the BPM as well to speed things up or slow things down.
Optional: Add some LED effects whenever songs are playing. Toggle colors (we have red, green, blue LEDs on the board) depending on the tone.
6. Songs from the cloud¶
We'll be connecting the device to the internet now. First let's build the firmware for the device.
- Now import https://developer.mbed.org/teams/MakingMusicWorkshop/code/6_songs-from-the-cloud
- Go to https://connector.mbed.com/, and sign in.
- Now click on 'Security Credentials' and click 'Get my Security Credentials'.
- Copy everything in the gray box.
- Open the file 'security.h' and paste the content in.
- Plug in an ethernet cable and hit 'Compile'.
- Flash your device. After a couple of seconds the GREEN led should turn on.
- Go to https://connector.mbed.com/#endpoints, a device should have appeared.
- Hurray, your device is connected to the internet!
Now we want to start a web application which can talk back to the device.
- Click on this link.
- Choose 'ARM mbed' as the template and click 'Create Workspace'
- Open `ftf2016/6_songs-from-the-cloud/web/server.js`.
- We need an access key (API key), go to https://connector.mbed.com/#accesskeys and get an access key.
- In server.js, fill in the key on line 1 (between the quotes), so we'll get something like `var accessKey = 'ABCDEF';`.
- In the tree, right click on the 'web' folder (under 6_songs-from-the-cloud) and choose 'Open terminal here'. A terminal window will open.
- Type `node server.js` and hit enter.
- After a few seconds a link will appear. Click on it, and select 'Open'.
- A web page opens and your device will be there. Click on the device, and on the next page click 'Play'.
- We can send new sounds to the board, f.e. via the 'Set Mario' button. Wait until you get an alert and press 'Play' again.
- You can write some new songs from JavaScript (in ftf2016/6_songs-from-the-cloud/web/views/instrument.html) now.
Optional: Look into how we send values to the cloud. Add a way of setting the BPM from the web app as well.