Home ←STEM HQ ← Getting Started with Arduino ← Arduino Lesson 5
Lesson 5: Making Music via BLE
Use your Chrome browser on Mac, Android or ChromeBook, the LightBlue App for iOS or Android or the WebBLE app on iPad to test these pages.
Lesson 5 - Making Music via BLE
Lesson 6 - Real world data at your fingertips: Light, Ultrasonic Motion and more...
Lesson 7 - Build your own BLE ultrasonic motion detector for under $AUD30
Sending Multiple Characters to the Board - and Making Music!
The nature of serial communication is essentially to send one character at a time. This works well for very simple situations, as we have just seen, but very soon we will need a better system. For example, suppose we wanted to send numbers like 220, and 440 (the frequencies for A3 and A4 on the musical scale)?
What we need to do is to catch each character as it is read, convert to a string, concatenate (glue) these together, until an end of string signal (like, say, a carriage return or enter key) is received. This way, instead of reading "2", then "2" then "0", we read "220".
Study the sketch below and see how this is accomplished.
Note some useful commands - like isDigit, string.toInt() and useful terms like \n (carriage return/new line). Note, too, the syntax for concatenating: inString += (char)recvChar;.
For free options to test and explore our BLE code, we can use the LightBlue App for iOS or Android, your Chrome browser on Mac, Android or ChromeBooks or the WebBLE app on iPad.
Arduino Sketch (Copy and paste into Arduino IDE)
String inString = ""; float input = 0; int noteduration = 1000; int soundpin = 4;
void setup() {
Serial.begin(9600);}void loop() {
while(Serial.available()){}}char recvChar = Serial.read(); if (isDigit(recvChar)) { // check if the input is a digit
inString += (char)recvChar; // add that character to a string}if (recvChar == '\n') { // if you get a newline, play the string
float input = inString.toInt(); // convert the string to an integer}if (input > 5500) { // Test the length of the input
input = input / 100; // if greater than 5500 divide by 100}if (input == 0 ) {
noTone(soundpin); // stop playing the tone:} else if (input < 5500) {tone(soundpin, input, noteduration); // else play that note Serial.println(input);} input = 0; inString = ""; // clear the string for new input:
So far, we have just used single characters to write to the board. This works well for simple things, but very quickly we will find that we need a better system. For example, suppose we wanted to be able to type notes such as A4, and C3, or just build a scale from one note (say, "C") to that same note one octave higher.
The sketch displayed here is very similar to those from Lesson 3 with a small but very important exception.
The line inString += (char)recvChar is designed to add characters to a string. So it will work just as well for a value such as "440" as it does for "4". All we need is a method to tell the sketch where our value ends, and for that, we use a simple newline (\n) which occurs when you press the enter key in the Serial Monitor. It is an "invisible" character so you don't see it, but it is there and can be used as a test.
So in this sketch, we wait until we sense an enter key to register our input and to play the tone.
Take note of this technique - it will become very important later when we are sending information back and forth using, not just the Serial Monitor, but Bluetooth Low Energy (BLE).
I added another test - if the value is greater than 5500, then it is divided by 100. This actually allows up to two decimal place accuracy for our tones, getting around the limitations of integer values. In this way, a note such as F6 (F in the 6th octave where middle C lies in the 4th octave) can be entered as 139691 but will be played as 1396.91.
Try for yourself!
Use your Chrome browser on Mac, Android or ChromeBook, the LightBlue App for iOS or Android or the WebBLE app on iPad to test these pages.
BLE Controls
BLE Arc Piano
Create your own Live Web Page
Explore Further...
Home ← Getting Started with Arduino ← Arduino Lesson 5