Arduino Basics: Serial
Showing posts with label Serial. Show all posts
Showing posts with label Serial. Show all posts

10 April 2015

Arduino BeatBox

Create your very own Arduino BeatBox !

Home-made capacitive touch sensors are used to trigger the MP3 drum sounds stored on the Grove Serial MP3 player. I have used a number of tricks to get the most out of this module, and I was quite impressed on how well it did. Over 130 sounds were loaded onto the SDHC card. Most were drum sounds, but I added some farm animal noises to provide an extra element of surprise and entertainment. You can put any sounds you want on the module and play them back quickly. We'll put the Grove Serial MP3 module through it's paces and make it into a neat little BeatBox !!


Key learning objectives

  • How to make your own beatbox
  • How to make capacitive drum pad sensors without using resistors
  • How to speed up Arduino's Analog readings for better performance
  • How to generate random numbers on your Arduino


Parts Required:

Making the drum pads



 
 

Fritzing Sketch


 


 
 

Grove Connections


 


 
 

Grove Connections (without base shield)


 


 
 

Arduino Sketch


 
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
    
/* =================================================================================================
      Project: Arduino Beatbox
       Author: Scott C
      Created: 9th April 2015
  Arduino IDE: 1.6.2
      Website: http://arduinobasics.blogspot.com/p/arduino-basics-projects-page.html
  Description: This project uses home made capacitive sensors to trigger over 130 MP3 sounds
               on the Grove Serial MP3 player. 
               
               The ADCTouch library is used to eliminate the resistors from the Capacitive sensing circuit. 
               The code used for capacitive sensing was adapted from the ADCTouch library example sketches. 
               You can find the ADCTouch library and relevant example code here:
               http://playground.arduino.cc/Code/ADCTouch
               
               "Advanced Arduino ADC" is used to improve the analogRead() speed, and enhance the
               drum pad or capacitive sensor response time. The Advanced Arduino ADC code 
               was adapted from this site:
               http://www.microsmart.co.za/technical/2014/03/01/advanced-arduino-adc/
               
               
=================================================================================================== */
  #include <ADCTouch.h>
  #include <SoftwareSerial.h>
  
  
  //Global variables
  //===================================================================================================
  int potPin = A4;                           //Grove Sliding potentiometer is connected to Analog Pin 4
  int potVal = 0;
  byte mp3Vol = 0;                           //Variable used to control the volume of the MP3 player
  byte oldVol = 0;
  
  int buttonPin = 5;                         //Grove Button is connected to Digital Pin 5
  int buttonStatus = 0;
  
  byte SongNum[4] = {0x01,0x02,0x03,0x04};  //The first 4 songs will be assigned to the drum pads upon initialisation
  byte numOfSongs = 130;                    //Total number of MP3 songs/sounds loaded onto the SDHC card
  
  long randNumber;                          //Variable used to hold the random number - used to randomise the sounds.
  
  int ledState[4];                          //Used to keep track of the status of all LEDs (on or off)
  int counter = 0;
  
  SoftwareSerial mp3(3, 4);                 // The Grove MP3 Player is connected to Arduino digital Pin 3 and 4 (Serial communication)
       
  int ref0, ref1, ref2, ref3;               //reference values to remove offset
  int threshold = 100;
      
  // Define the ADC prescalers
  const unsigned char PS_64 = (1 << ADPS2) | (1 << ADPS1);
  const unsigned char PS_128 = (1 << ADPS2) | (1 << ADPS1) | (1 << ADPS0);
  
  
  
  //Setup()
  //===================================================================================================
  void setup(){
    //Initialise the Grove MP3 Module
    delay(2500);                              //Allow the MP3 module to power up        
    mp3.begin(9600);                          //Begin Serial communication with the MP3 module
    setPlayMode(0x00);                        //0x00 = Single song - played once ie. not repeated.  (default)
    
    //Define the Grove Button as an INPUT
    pinMode(buttonPin, INPUT);
    
    //Define the 4 LED Pins as OUTPUTs
    pinMode(8, OUTPUT);                       //Green LED
    pinMode(9, OUTPUT);                       //Blue LED
    pinMode(10, OUTPUT);                      //Red LED
    pinMode(11, OUTPUT);                      //Yellow LED
    
    //Make sure each LED is OFF, and store the state of the LED into a variable.
    for(int i=8;i<12;i++){
      digitalWrite(i, LOW);
      ledState[i-8]=0;
    } 
    
    //Double our clock speed from 125 kHz to 250 kHz
    ADCSRA &= ~PS_128;   // set up the ADC
    ADCSRA |= PS_64;    // set our own prescaler to 64 
    
    //Create reference values to account for the capacitance of each pad.
    ref0 = ADCTouch.read(A0, 500);
    ref1 = ADCTouch.read(A1, 500);      //Take 500 readings
    ref2 = ADCTouch.read(A2, 500);
    ref3 = ADCTouch.read(A3, 500);
    
     //This helps to randomise the drum pads.
     randomSeed(analogRead(0));
  }
  
  
  
  // Loop()
  //===================================================================================================     
  void loop(){
     
    //Take a reading from the Grove Sliding Potentiometer, and set volume accordingly
    potVal = analogRead(potPin);
    mp3Vol = map(potVal, 0, 1023, 0,31);              // Convert the potentometer reading (0 - 1023) to fit within the MP3 player's Volume range (0 - 31)
    if((mp3Vol>(oldVol+1))|(mp3Vol<(oldVol-1))){      // Only make a change to the Volume on the Grove MP3 player when the potentiometer value changes
      oldVol = mp3Vol;
      setVolume(mp3Vol);
      delay(10);                                      // This delay is necessary with Serial communication to MP3 player
    }
    
    //Take a reading from the Pin attached to the Grove Button. If pressed, randomise the MP3 songs/sounds for each drum pad, and make the LEDs blink randomly.
    buttonStatus = digitalRead(buttonPin);
    if(buttonStatus==HIGH){
      SongNum[0]=randomSongChooser(1, 30);
      SongNum[1]=randomSongChooser(31, 60);
      SongNum[2]=randomSongChooser(61, 86);
      SongNum[3]=randomSongChooser(87, (int)numOfSongs);
      randomLEDBlink();
    }
    
    //Get the capacitive readings from each drum pad: 50 readings are taken from each pad. (default is 100) 
    int value0 = ADCTouch.read(A0,50);        //  Green drum pad
    int value1 = ADCTouch.read(A1,50);        //   Blue drum pad
    int value2 = ADCTouch.read(A2,50);        //    Red drum pad
    int value3 = ADCTouch.read(A3,50);        // Yellow drum pad
    
    //Remove the offset to account for the baseline capacitance of each pad.
    value0 -= ref0;       
    value1 -= ref1;
    value2 -= ref2;
    value3 -= ref3;
    
    
    //If any of the values exceed the designated threshold, then play the song/sound associated with that drum pad.
    //The associated LED will stay on for the whole time the drum pad is pressed, providing the value remains above the threshold. 
    //The LED will turn off when the pad is not being touched or pressed.
    if(value0>threshold){
      digitalWrite(8, HIGH);
      playSong(00,SongNum[0]);
    }else{
      digitalWrite(8,LOW);
    }
    
    if(value1>threshold){
      digitalWrite(9, HIGH);
      playSong(00,SongNum[1]);
    }else{
      digitalWrite(9,LOW);
    }
    
    if(value2>threshold){
      digitalWrite(10, HIGH);
      playSong(00,SongNum[2]);
    }else{
      digitalWrite(10,LOW);
    }
    
    if(value3>threshold){
      digitalWrite(11, HIGH);
      playSong(00,SongNum[3]);
    }else{
      digitalWrite(11,LOW);
    }
  }
      
   
  // writeToMP3: 
  // a generic function that simplifies each of the methods used to control the Grove MP3 Player
  //===================================================================================================
  void writeToMP3(byte MsgLEN, byte A, byte B, byte C, byte D, byte E, byte F){
    byte codeMsg[] = {MsgLEN, A,B,C,D,E,F};
    mp3.write(0x7E);                        //Start Code for every command = 0x7E
    for(byte i = 0; i<MsgLEN+1; i++){
      mp3.write(codeMsg[i]);                //Send the rest of the command to the GROVE MP3 player
    }
  }
  
  
  //setPlayMode: defines how each song is to be played
  //===================================================================================================
  void setPlayMode(byte playMode){
    /* playMode options:
          0x00 = Single song - played only once ie. not repeated.  (default)
          0x01 = Single song - cycled ie. repeats over and over.
          0x02 = All songs - cycled 
          0x03 = play songs randomly                                           */
    writeToMP3(0x03, 0xA9, playMode, 0x7E, 0x00, 0x00, 0x00);  
  }
  
  
  //playSong: tells the Grove MP3 player to play the song/sound, and also which song/sound to play
  //===================================================================================================
  void playSong(byte songHbyte, byte songLbyte){
    writeToMP3(0x04, 0xA0, songHbyte, songLbyte, 0x7E, 0x00, 0x00);            
    delay(100);
  }
  
  
  //setVolume: changes the Grove MP3 player's volume to the designated level (0 to 31)
  //===================================================================================================
  void setVolume(byte Volume){
    byte tempVol = constrain(Volume, 0, 31);             //Volume range = 00 (muted) to 31 (max volume)
    writeToMP3(0x03, 0xA7, tempVol, 0x7E, 0x00, 0x00, 0x00); 
  }
  
  
  //randomSongChooser: chooses a random song to play. The range of songs to choose from
  //is limited and defined by the startSong and endSong parameters.
  //===================================================================================================
  byte randomSongChooser(int startSong, int endSong){
    randNumber = random(startSong, endSong);
    return((byte) randNumber);
  }
  
  
  //randomLEDBlink: makes each LED blink randomly. The LEDs are attached to digital pins 8 to 12.
  //===================================================================================================
  void randomLEDBlink(){
   counter=8;
   for(int i=0; i<40; i++){
     int x = constrain((int)random(8,12),8,12);
     toggleLED(x);
     delay(random(50,100-i));
   }
     
    for(int i=8;i<12;i++){
      digitalWrite(i, HIGH);
    }
    delay(1000);
    for(int i=8;i<12;i++){
      digitalWrite(i, LOW);
      ledState[i-8]=0;
    }
  }
  
  
  //toggleLED: is used by the randomLEDBlink method to turn each LED on and off (randomly).
  //===================================================================================================
  void toggleLED(int pinNum){
    ledState[pinNum-8]= !ledState[pinNum-8];
    digitalWrite(pinNum, ledState[pinNum-8]);
  }
    


 

Arduino Code Discussion

You can see from the Arduino code above, that it uses the ADCTouch library. This library was chosen over the Capacitive Sensing Library to eliminate the need for a high value resistor which are commonly found in Capacitive Sensing projects).
 
To increase the speed of the Analog readings, I utilised one of the "Advanced Arduino ADC" techniques described by Guy van den Berg on this Microsmart website.
 
The readings are increased by modifying the Arduino's ADC clock speed from 125kHz to 250 kHz. I did notice an overall better response time with this modification. However, the Grove Serial MP3 player is limited by it's inability to play more than one song or sound at a time. This means that if you hit another drum pad while the current sound is playing, it will stop playing the current sound, and then play the selected sound. The speed at which it can perform this task was quite impressive. In fact it was much better than I thought it would be. But if you are looking for polyphonic playability, you will be dissapointed.
 
This Serial MP3 module makes use of a high quality MP3 audio chip known as the "WT5001". Therefore, you should be able to get some additional features and functionality from this document. Plus you may find some extra useful info from the Seeedstudio wiki. I have re-used some code from the Arduino Boombox tutorial... you will find extra Grove Serial MP3 functions on that page.
 
I will warn you... the Grove Serial MP3 player can play WAV files, however for some reason it would not play many of the sound files in this format. Once the sounds were converted to the MP3 format, I did not look back. So if you decide to take on this project, make sure your sound files are in MP3 format, you'll have a much better outcome.
 
I decided to introduce a random sound selection for each drum pad to extend the novelty of this instrument, which meant that I had to come up with a fancy way to illuminate the LEDs. I demonstrated some of my other LED sequences on my instagram account. I sometimes use instagram to show my work in progress.
 
Have a look at the video below to see this project in action, and putting the Grove Serial MP3 player through it's paces.
 

The Video


 


First there was the Arduino Boombox, and now we have the Arduino Beatbox..... who knows what will come next !
 
Whenever I create a new project, I like to improve my Arduino knowledge. Sometimes it takes me into some rather complicated topics. There is a lot I do not know about Arduino, but I am enjoying the journey. I hope you are too !! Please Google plus one this post if it helped you in any way. These tutorials are free, which means I survive on feedback and plus ones... all you have to do is just scroll a little bit more and click that button :)

 
 



If you like this page, please do me a favour and show your appreciation :

 
Visit my ArduinoBasics Google + page.
Follow me on Twitter by looking for ScottC @ArduinoBasics.
I can also be found on Pinterest and Instagram.
Have a look at my videos on my YouTube channel.


 
 

 
 
 



However, if you do not have a google profile...
Feel free to share this page with your friends in any way you see fit.

19 March 2015

Arduino Boombox

Add sound or music to your project using the "Grove Serial MP3 Player".

An Arduino UNO will be used to control the Grove Serial MP3 player by sending it specific serial commands. The Grove Base Shield allows for the easy connection of Grove sensor modules to an Arduino UNO without the need for a breadboard. A sliding potentiometer, switch and button will be connected to the Base shield along with the Serial MP3 player. A specific function will be assigned to each of the connected sensor modules to provide a useful interface:

  • Sliding Potentiometer – Volume control
  • Button – Next Song
  • Switch – On/Off (toggle)
Once the MP3 module is working the way we want, we can then build a simple enclosure for it.
Grab a shoe-box, print out your favourite design, and make your very own Arduino BOOMBOX!


 

Video

Watch the following video to see the project in action
 


 
 

Parts Required:

Optional components (for the BoomBox Enclosure):
  • Empty Shoe Box
  • Paper
  • Printer
  • Glue
If I had a 3D printer - I would have printed my own enclosure, but a shoebox seems to work just fine.


 

Putting it Together

Place the Grove Base shield onto the Arduino UNO,
and then connect each of the Grove Modules as per the table below.
 


 

If you do not have a Grove Base shield,
you can still connect the modules directly to the Arduino as per the table below:
 


 

When you are finished connecting the modules, it should look something like this:
  (ignore the battery pack):
 

As you can see from the picture above. You can cut holes out of the shoebox and stick the modules in place. Please ignore the battery pack, because you won't use it until after you have uploaded the Arduino code.


 
 

Arduino Sketch


 
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
    
    
/* ===============================================================================
      Project: Grove Serial MP3 Player overview
       Author: Scott C
      Created: 9th March 2015
  Arduino IDE: 1.6.0
      Website: http://arduinobasics.blogspot.com/p/arduino-basics-projects-page.html

  Description: The following Arduino sketch will allow you to control a Grove Serial MP3 player
               with a Grove Sliding Potentiometer (volume), a Grove button (next song), 
               and a Grove Switch (on/off). It will also show you how to retrieve some useful information from the player. 
               Some functions are not used in this sketch,but have been included for your benefit. 
               
               Additional features and functionality can be found on the WT5001 voice chip datasheet 
               which I retrieved from here: http://goo.gl/ai6oQ9
               
               The Seeedstudio wiki was a very useful resource for getting started with the various Grove modules:
               http://goo.gl/xOiSCl
=============================================================================== */

#include <SoftwareSerial.h>
SoftwareSerial mp3(2, 3);      // The Grove MP3 Player is connected to Arduino digital Pin 2 and 3 (Serial communication)
int potPin = A0;               // The Sliding Potentiometer is connected to AnalogPin 0
int potVal = 0;                // This is used to hold the value of the Sliding Potentiometer
byte mp3Vol = 0;               // mp3Vol is used to calculate the Current volume of the Grove MP3 player
byte oldVol = 0;               // oldVol is used to remember the previous volume level
int ledPin = A1;               // The Grove sliding potentiometer has an onboard LED attached to Analog pin 1.

int switchPin = 12;             // The Grove Switch(P) is connected to digital Pin 12
int switchStatus = 0;           // This is used to hold the status of the switch 
int switchChangeStatus = 0;     // Used to identify when the switch status has changed

int buttonPin = 5;              // The Grove Button is connected to digital pin 5
int buttonStatus = 0;           // This is used to hold the status of the button  



void setup(){
  //Initialise the Grove MP3 Module
  delay(2500);
  mp3.begin(9600);
  
        
  // initialize the pushbutton and switch pin as an input:
  pinMode(buttonPin, INPUT);
  pinMode(switchPin, INPUT);
  
  // set ledPin on the sliding potentiometer to OUTPUT
  pinMode(ledPin, OUTPUT);
  
  //You can view the following demostration output in the Serial Monitor
  demonstrate_GET_FUNCTIONS();     
}


void loop(){
  switchStatus = digitalRead(switchPin);
  if(switchStatus==HIGH){
    if(switchChangeStatus==LOW){             // When Arduino detects a change in the switchStatus (from LOW to HIGH) - play song      
      setPlayMode(0x02);                     // Automatically cycle to the next song when the current song ends
      playSong(00,01);                       // Play the 1st song when you switch it on
      switchChangeStatus=HIGH;
    }
    
    potVal = analogRead(potPin);                      // Analog read values from the sliding potentiometer range from 0 to 1023
    analogWrite(ledPin, potVal/4);                    // Analog write values range from 0 to 255, and will turn LED ON once potentiometer reaches about half way (or more).
    mp3Vol = map(potVal, 0, 1023, 0,31);              // Convert the potentometer reading (0 - 1023) to fit within the MP3 player's Volume range (0 - 31)
    if((mp3Vol>(oldVol+1))|(mp3Vol<(oldVol-1))){      // Only make a change to the Volume on the Grove MP3 player when the potentiometer value changes
      oldVol = mp3Vol;
      setVolume(mp3Vol);
      delay(10);                               // This delay is necessary with Serial communication to MP3 player
    }

    buttonStatus = digitalRead(buttonPin);
    if(buttonStatus==HIGH){                    // When a button press is detected - play the next song
      playNextSong();
      delay(200);                              // This delay aims to prevent a "skipped" song due to slow button presses - can modify to suit.
    }
  } else {
    if(switchChangeStatus==HIGH){              // When switchStatus changes from HIGH to LOW - stop Song.
      stopSong();
      switchChangeStatus=LOW;
    }
  } 
}


// demonstrate_GET_FUNCTIONS  will show you how to retrieve some useful information from the Grove MP3 Player (using the Serial Monitor).
void demonstrate_GET_FUNCTIONS(){
        Serial.begin(9600);
        Serial.print("Volume: ");
        Serial.println(getVolume());
        Serial.print("Playing State: ");
        Serial.println(getPlayingState());
        Serial.print("# of Files in SD Card:");
        Serial.println(getNumberOfFiles());
        Serial.println("------------------------------");
}


// writeToMP3: is a generic function that aims to simplify all of the methods that control the Grove MP3 Player

void writeToMP3(byte MsgLEN, byte A, byte B, byte C, byte D, byte E, byte F){
  byte codeMsg[] = {MsgLEN, A,B,C,D,E,F};
  mp3.write(0x7E);                        //Start Code for every command = 0x7E
  for(byte i = 0; i<MsgLEN+1; i++){
    mp3.write(codeMsg[i]);                //Send the rest of the command to the GROVE MP3 player
  }
}


/* The Following functions control the Grove MP3 Player : see datasheet for additional functions--------------------------------------------*/

void setPlayMode(byte playMode){
  /* playMode options:
        0x00 = Single song - played only once ie. not repeated.  (default)
        0x01 = Single song - cycled ie. repeats over and over.
        0x02 = All songs - cycled 
        0x03 = play songs randomly                                           */
        
  writeToMP3(0x03, 0xA9, playMode, 0x7E, 0x00, 0x00, 0x00);  
}


void playSong(byte songHbyte, byte songLbyte){                              // Plays the selected song
  writeToMP3(0x04, 0xA0, songHbyte, songLbyte, 0x7E, 0x00, 0x00);            
}


void pauseSong(){                                                           // Pauses the current song
  writeToMP3(0x02, 0xA3, 0x7E, 0x00, 0x00, 0x00, 0x00);
}


void stopSong(){                                                            // Stops the current song
  writeToMP3(0x02, 0xA4, 0x7E, 0x00, 0x00, 0x00, 0x00);
}


void playNextSong(){                                                        // Play the next song
  writeToMP3(0x02, 0xA5, 0x7E, 0x00, 0x00, 0x00, 0x00);
}


void playPreviousSong(){                                                    // Play the previous song
  writeToMP3(0x02, 0xA6, 0x7E, 0x00, 0x00, 0x00, 0x00);
}


void addSongToPlayList(byte songHbyte, byte songLbyte){
  //Repeat this function for every song you wish to stack onto the playlist (max = 10 songs)
  writeToMP3(0x04, 0xA8, songHbyte, songLbyte, 0x7E, 0x00, 0x00);
}


void setVolume(byte Volume){                                                // Set the volume
  byte tempVol = constrain(Volume, 0, 31);
  //Volume range = 00 (muted) to 31 (max volume)
  writeToMP3(0x03, 0xA7, tempVol, 0x7E, 0x00, 0x00, 0x00); 
}



/* The following functions retrieve information from the Grove MP3 player : see data sheet for additional functions--------------*/

// getData: is a generic function to simplifly the other functions for retieving information from the Grove Serial MP3 player
byte getData(byte queryVal, int dataPosition){
  byte returnVal = 0x00;
  writeToMP3(0x02, queryVal, 0x7E, 0x00, 0x00, 0x00, 0x00);
  delay(50);
  for(int x = 0; x<dataPosition; x++){
    if(mp3.available()){
      returnVal = mp3.read();
      delay(50);
    }
  }
  return(returnVal);
}

byte getVolume(){                                              //Get the volume of the Grove Serial MP3 player
  //returns value from 0 - 31
  return(getData(0xC1, 4));
}

byte getPlayingState(){                                        //Get the playing state : Play / Stopped / Paused
  //returns 1: Play,   2: Stop,   3:Paused
  return(getData(0xC2, 2));
}


byte getNumberOfFiles(){                                      //Find out how many songs are on the SD card
  //returns the number of MP3 files on SD card
  return(getData(0xC4, 3));
}
    
    

You will notice from the code, that I did not utilise every function. I decided to include them for your benifit. This Serial MP3 module makes use of a high quality MP3 audio chip known as the "WT5001". Therefore, you should be able to get some additional features and functionality from this document. Plus you may find some extra useful info from the Seeedstudio wiki.
 
IMPORTANT: You need to load your MP3 sounds or songs onto the SDHC card before you install it onto the Serial MP3 player.
 
Once the SDHC card is installed, and your code is uploaded to the Arduino, all you have to do now is connect the MP3 player to some headphones or a powered speaker. You can then power the Arduino and modules with a battery pack or some other portable power supply.
 
You can design and decorate the shoebox in any way you like. Just print out your picture, glue them on, and before you know it, you will have your very own Arduino Boombox.
 


Comments

I was very surprised by the quality of the sound that came from the MP3 module. It is actually quite good.

This tutorial was an introduction to the Grove Serial MP3 module in it's most basic form. You could just as easily use some other sensor to trigger the MP3 module. For example, you could get it to play an alert if a water leak was detected, or if a door was opened, or if the temperature got too high or too low. You could get it to play a reminder when you walk into your room. The possibilities are endless.

I really liked this module, and I am sure it will appear in a future tutorial.


 



If you like this page, please do me a favour and show your appreciation :

 
Visit my ArduinoBasics Google + page.
Follow me on Twitter by looking for ScottC @ArduinoBasics.
I can also be found on Pinterest and Instagram.
Have a look at my videos on my YouTube channel.


 
 

 
 
 



However, if you do not have a google profile...
Feel free to share this page with your friends in any way you see fit.

23 June 2014

433 MHz RF module with Arduino Tutorial 1


There are 4 parts to this tutorial:
To get the most out of this tutorial - it is best to start at tutorial Part 1, and then progress to Part 2 then Part 3 and then do Part 4 last. Doing the RF tutorials in this order will help you to understand the process better.



If you are looking for a way to communicate between Arduinos, but don't have much cash at your disposal, then look no further. These RF modules are not only affordable, but easy to use. They are much easier to set up than an XBee, plus you can use them without the need of a special shield. Before you rush out and buy a ton of these modules, make sure that you are not breaking any radio transmission laws in your country. Do your research, and buy them only if you are allowed to use them in your area. There are a few [OPTIONAL] libraries that can be used to help you and your particular project.


I will mention at this point however, that I did NOT use any libraries in this particular tutorial. That's right. I will show how easy it is to transmit data from one arduino to another using these RF modules WITHOUT libraries.

Also if you are looking for an easy way to record the signals and play them back without a computer - then jump to this tutorial.

Video





Project 1- RF Blink


Firstly we need to test if the RF modules are working. So we will design a very simple transmit and receive sketch to test their functionality. We will use the Arduino's onboard LED to show when the transmitter is transmitting, and when the other Arduino is receiving. There will be a slight delay between the two Arduinos. You can solder an antenna onto these modules, however I did not do this, I just kept the modules close together (1-2cm apart). I also found that I was getting better accuracy when I used 3V instead of 5V to power the receiver. While using 5V for VCC on the receiver, I would get a lot of interference, however with 3V, I hardly got any noise. If you find you are getting unpredictable results, I would suggest you switch to 3V on the receiver and move the transmitter and receiver modules right next to each other. Remember this is just a check... you can experiment with an antenna or a greater distance afterwards.

Here are the parts that you will need to carry out this project:
 

Parts Required



 

The Transmitter and Receiver Fritzing Sketch






The Transmitter

The transmitter has 3 pins




 Notice the pin called "ATAD". It took me a while to figure out what ATAD stood for, when I suddenly realised that this was just a word reversed. It should be DATA (not ATAD). Nevertheless, this is the pin responsible for transmitting the signal. We will make the Arduino's onboard LED illuminate when the transmitter pin is HIGH, and go off when LOW as described in the following table.

 
 



And this is the Arduino Sketch to carry out the data transmission.




Arduino sketch - Transmitter





 

The Receiver



If all goes to plan, the onboard LED on this Arduino should light up (and go off) at the same time as the onboard LED on the transmitting Arduino. There is a chance that the receiver may pick up stray signals from other transmitting devices using that specific frequency. So you may need to play around with the threshold value to eliminate the "noise". But don't make it too big, or you will eliminate the signal in this experiment. You will also notice a small delay between the two Arduinos.


 

Arduino sketch - Receiver




When a HIGH signal is transmitted to the other Arduino. It will produce an AnalogRead = 0.
When a LOW signal is transmitted, it will produce an AnalogRead = 400.
This may vary depending on on your module, and voltage used.
The signals received can be viewed using the Serial Monitor, and can be copied into a spreadsheet to create a chart like this:




You will notice that the HIGH signal (H) is constant, whereas the LOW signal (L) is getting smaller with each cycle. I am not sure why the HIGH signal produces a Analog reading of "0". I would have thought it would have been the other way around. But you can see from the results that a HIGH signal produces a 0 result and a LOW signal produces a value of 400 (roughly).





Tutorial 2

In tutorial 2, we will receive and display a signal from a Mercator RF Remote Controller for Fan/Light.


Tutorial 3

In tutorial 3 - we use the signal acquired from tutorial 2, and transmit the signal to the fan/light to turn the light on and off.


Tutorial 4

In tutorial 4 - we use the information gathered in the first 3 tutorials and do away with the need for a computer. We will listen for a signal, store the signal, and then play it back by pressing a button. Similar to a universal remote ! No libraries, no sound cards, no computer. Just record signal and play it back. Awesome !!


 
 



If you like this page, please do me a favour and show your appreciation :

  Visit my ArduinoBasics Google + page.
Follow me on Twitter by looking for ScottC @ArduinoBasics.
Have a look at my videos on my YouTube channel.


 
 

 
 
 


However, if you do not have a google profile...
Feel free to share this page with your friends in any way you see fit.




© Copyright by ScottC

8 April 2013

Serial Communication Tutorial (Part 3)





In the previous two parts of the this tutorial, we went through a number of simple sketches to get you acquainted with the way that the Arduino handles various data types when passed through the Serial COM port. Here are the main themes from part ONE:
  • Stage One:  Echoing data with the Arduino
  • Stage Two: Using Delimiters to split data.
  • Stage Three: Arduino Maths, simple addition
  • Stage Four: Sending a double to an Arduino, and then doubling it.
  • Stage Five: Sending Sensor data from the Arduino to the Serial Monitor
Here are the main themes from Part TWO:

  • Stage Six: ......A simple Processing Sketch
  • Stage Seven:  Arduino and Processing join forces for more fun
  • Stage Eight: A simple project that shows Serial communication from Arduino to Processing
In Part Three - we will reverse the direction of communication and get Processing to send data to the Arduino via a USB cable,

  • Stage Nine: A simple processing sketch that switches an LED on the Arduino
  • Stage Ten:  A processing sketch that reads from a text file
  • Stage Eleven: A processing sketch that reads data from a text file and sends to the Arduino
  • Stage Twelve: A processing sketch that trasmits data from a file to another Arduino via an XBee module.


Stage Nine - Using your computer to switch an LED

In this stage we create a simple Arduino sketch which will receive a simple command from the Processing Sketch to switch an LED. The Processing sketch will allow you to turn an LED on/off by clicking on the Processing Application window. It will detect the press of the mouse, and will send a command to the Arduino via the USB Serial COM port.

Parts Required:
  • Arduino UNO or compatible board
  • USB cable
  • Arduino and Processing IDE (on computer)
Arduino Logo The Arduino Sketch
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
/* ===================================================
Simple number reader: Written by ScottC - 07 Apr 2013
 Arduino Version: 1.04
======================================================*/

// The onboard LED is on pin # 13
int onboardLED = 13;


void setup() {
 // Begin Serial communication
 Serial.begin(9600);
 
 //Set the onboard LED to OUTPUT
 pinMode(onboardLED, OUTPUT);
}

void loop(){
 /* Read serial port, if the number is 0, then turn off LED
 if the number is 1 or greater, turn the LED on. */
 while (Serial.available() > 0) {
 int num=Serial.read()-'0';
 if(num<1){
 digitalWrite(onboardLED, LOW); //Turn Off LED
 } else{ 
 digitalWrite(onboardLED, HIGH); //Turn On LED
 } 
 }
}


Processing icon The Processing Sketch
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
/*===========================================================
 Toggle Switch: Send Number to Arduino
 Written by Scott C on 07 Apr 2013
 Processing Version: 2.0b8
=============================================================*/

import processing.serial.*;

Serial comPort;
boolean ledState=false; //LED is off

void setup(){
 //Open COM Port for Communication
 comPort = new Serial(this, Serial.list()[0], 9600);
 background(255,0,0); //Start with a Red background
}

void draw(){
}


void mousePressed() {
 //Toggle led ON and OFF
 ledState=!ledState;
 
 //If ledState is True - then send a value=1 (ON) to Arduino
 if(ledState){
 background(0,255,0); //Change the background to green
 
 /*When the background is green, transmit
 a value=1 to the Arduino to turn ON LED */
 comPort.write('1');
 }else{
 background(255,0,0); //Change background to red
 comPort.write('0'); //Send "0" to turn OFF LED.
 }
}




The Video


Stage Ten: Reading from a Text File

We are now going to give the Arduino a rest (for a moment) and concentrate on a Processing Sketch that will read from a text file. Once we learn this skill, we can then build this Processing functionality into our Arduino Projects. Reading from a text file in Processing is actually quite easy if you use the loadStrings() method. However, it is best if you make things easy for yourself by using delimiters. The most common delimitter is a "comma". The comma allows the computer to group information according to your needs.
  • 11,22,33,44,55,66
  • 1,1,2,2,3,3,4,4,5,5,6,6
  • 112,223,334,455,566
The examples above contain the same numbers but are delimitted in different ways.
We are going to import a few different numbers/letters and store them in an array. We will then iterate through the array to display the values within.
So let us now create the text file. Copy and paste the following text into notepad and save the file, but remember where you save it, because we will need to know location and the name of the file in order to read from in.

NotepadIconCopy and Paste into Notepad:
100,200,A,B,C,10.2,0.1,wx,yz,arduinobasics
 
 
 
 

Save the file
I am going to call my file data.txt, and will be saving it to my D drive, so the file will be located here:
  • D:/data.txt

We will now create the processing sketch to read the text file and display the data on the screen.
We will use the comma delimiters to separate the data so that it displays in the following way:




Processing icon The Processing Sketch
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
/* =============================================================
 ReadTextFile and Display on Screen:
 Written by ScottC on 15th April 2013 using 
 Processing version 2.0b8
 
 Website: http://arduinobasics.blogspot.com/
 Projects: http://arduinobasics.blogspot.com/p/arduino-basics-projects-page.html
 
 References:
 Displaying Text: http://processing.org/reference/text_.html
 Reading Text File: http://processing.org/reference/loadStrings_.html
=================================================================*/

void setup(){
 size(180,250);
 background(255);
 
 /* Read the text file */
 String[] lines = loadStrings("D:/data.txt");
 int numOfLines=lines.length;
 for(int i=0;i<numOfLines;i++){
 
 /* Split the data based on a "," delimiter. */
 String[] data = splitTokens(lines[i], ",");
 int dataCount = data.length;
 
 for(int j=0; j<dataCount; j++){
 /* Set the size and colour of the text */
 textSize(16);
 fill(100,100,255,50+(j*20));
 
 /* Display the text on the screen */
 text(data[j],10,16+(16*j));
 }
 }
}


void draw(){
}

The code above has the ability to display data from multiple lines within the text file, however for simplicity, I have chosen to use a single line. If I wanted to display more than one line, I would have to change the "for-loops".



Stage Eleven: Read Text File and send to Arduino

In stage 10 we used the Processing  programming language to import a line of data from a text file, break-up the line into pieces (based on comma delimiters) and then displayed the data on the Computer Screen. We will now use this knowledge and take it one step further. We will create a text file, import the data using processing, but this time we will send the data to the Arduino. Meanwhile the Arduino will be waiting patiently for this data, and once it receives the data, it will react according to our needs. We are going to keep this simple. The goal is to send two different letters from the Computer to the Arduino. One letter will turn an LED on, and the other letter will turn the LED off. We will also send an integer to tell the Arduino how long to keep the LED on or off.

GOAL:  Turn an LED on and off by reading a text file.
Our first step in this process is to create a text file that will store our important data. We will store two variables in this file. The first variable will be used to tell the Arduino whether we want to turn the LED on or whether we want to turn the LED off. We will use the letter "O" to turn the LED on, and use the letter "X" to turn the LED off.
The second variable will be a time based variable. It will be used to tell the Arduino "how long" to keep the LED on or off. We will store this variable as an integer and will represent time in "milliseconds".
  • 1000 milliseconds = 1 second
It makes sense to keep these two variables as a pair, however we will separate them using a comma delimitter. We will separate each command by putting the variables on a new line. Copy and paste the following data into notepad (or equivalent text editor), and save the file to your harddrive. I have saved this file as

  • D:/LEDdata.txt

NotepadIcon Text File Data: Here is the data to put into your text file (notepad):
X,50
O,45
X,40
O,35
X,30
O,25
X,20
O,15
X,10
O,5
X,10
O,15
X,20
O,25
X,30
O,35
X,40
O,45
X,50
O,55
X,60
O,65
X,70
O,75
X,80
O,85
X,90
O,95
X,100
O,200
X,200
O,200
X,500
O,500
X,500
O,500
X,20
O,20
X,20
O,20
X,20
O,20
X,20
O,20
X,20
O,20
X,200
O,20
X,20
O,20
X,20
O,20
X,20
O,20
X,20
O,20
X,20
O,20
X,200
O,20
X,20
O,20
X,20
O,20
X,20
O,20
X,20
O,20
X,200
O,20
X,20
O,20
X,20
O,20
X,20
O,20
X,20
O,20
X,20
O,20
X,20
O,20
X,20



We will now set up the Arduino to accept data from the Computer and react to the Letters
  • "O" to turn the LED on
  • "X" to turn the LED off
  • "E" will be used to test for a successful Serial connection.
We will also get the Arduino to interpret the second variable which will be used to set the amount of time to keep the LED on or off.


Arduino LogoArduino Code:
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
/* Read TextFile Data: Written by ScottC on 24 April 2013
 Arduino IDE version: 1.0.4
 http://arduinobasics.blogspot.com.au/2013/04/serial-communication-tutorial-part-3.html
*/

/* Global Variables */
byte byteRead; //Used to receive data from computer.
int timeDelay; //time that the LED is On or Off
int maxtimeDelay=10000; //Maximum time delay = 10 seconds
int ledPin=13; //LED connected to pin 13 on Arduino UNO.

void setup() { 
//Set pin 13 (ledPin) as an output 
 pinMode(ledPin, OUTPUT); 
// Turn the Serial Protocol ON
 Serial.begin(9600);
}

void loop() {
 /* check if data has been sent from the computer: */
 if (Serial.available()) {
 /* read the most recent byte */
 byteRead = Serial.read();
 
 switch (byteRead) {
 case 69: //This is an enquiry, send an acknowledgement
 Serial.println("A");
 break;
 case 79: //This is an "O" to turn the LED on
 digitalWrite(ledPin, HIGH);
 break;
 case 88: //This is an "X" to turn the LED off
 digitalWrite(ledPin, LOW);
 break;
 case 46: //End of line
 //Make sure time delay does not exceed maximum.
 if(timeDelay > maxtimeDelay){ 
 timeDelay=maxtimeDelay;
 }
 //Set the time for LED to be ON or OFF
 delay(timeDelay);
 Serial.println("S");
 timeDelay=0; //Reset timeDelay;
 break;
 default: 
 //listen for numbers between 0-9
 if(byteRead>47 && byteRead<58){
 //number found, use this to construct the time delay.
 timeDelay=(timeDelay*10)+(byteRead-48);
 }
 } 
 }
}

Our next step is to import the data in the text file into Processing and then send the data to the Arduino. You may want to review Stage 10 of this tutorial for another example of importing text file data into Processing. You may also want to review stage 7 which shows how to receive data from an Arduino.
We will import all of the data from the file when we push a button on the Processing Window, and send this data to the Arduino via the USB cable that is connected to the computer. We are going to use the same COM port that the Computer uses to upload Arduino Sketches, therefore it is important that you close the Arduino Serial Monitor before you run the processing sketch, otherwise you will get an error which states that the COM port is not available.


Processing icon Processing Code:
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
/* TextFile Data sender (Stage 11) 
 Written by ScottC on 24th April 2013
 using Processing Version 2.0b8 
 
 The full tutorial can be found here:
 http://arduinobasics.blogspot.com/2013/04/serial-communication-tutorial-part-3.html
*/

import processing.serial.*;

Serial comPort; //The com port used between the computer and Arduino
int counter=0; // Helps to keep track of values sent.
int numItems=0; //Keep track of the number of values in text file
String comPortString; //String received From Arduino
String textFileLines[]; //Array of text file lines
String lineItems[]; //Array of line items

void setup(){
 comPort = new Serial(this, Serial.list()[0], 9600); //Setup the COM port 
 comPort.bufferUntil('\n'); //Generate a SerialEvent when a newline is received
 background(255,0,0); //Start with a Red background
}

/* Draw method is not used in this sketch */
void draw(){
}

//When the mouse is pressed, write an "E" to COM port. 
//The Arduino should send back an "A" in return. This will 
//generate a serialEvent - see below.
void mousePressed() {
 comPort.write("E"); 
}

void serialEvent(Serial cPort){
 comPortString = cPort.readStringUntil('\n');
 if(comPortString != null) {
 comPortString=trim(comPortString);
 
 /*If the String received = A, then import the text file
 change the background to Green, and start by sending the
 first line of the text file to the Arduino */
 if(comPortString.equals("A")){
 textFileLines=loadStrings("D:/LEDdata.txt");
 background(0,255,0);
 sendLineNum(counter);
 }
 
 /*If the the String received = S, then increment the counter
 which will allow us to send the next line in the text file.
 If we have reached the end of the file, then reset the counter
 and change the background colour back to red. */
 if(comPortString.equals("S")){
 counter++;
 if(counter > (textFileLines.length-1)){
 background(255,0,0);
 counter=0;
 } else { 
 sendLineNum(counter);
 }
 }
 }
}


/*The sendLineNum method is used to send a specific line
 from the imported text file to the Arduino. The first
 line item tells the Arduino to either switch the LED on or off.
 The second line item, tells the Arduino how long to keep the
 LED on or off. The full-stop is sent to the Arduino to indicate
 the end of the line. */
 
void sendLineNum(int lineNumber){
 lineItems=splitTokens(textFileLines[lineNumber],",");
 comPort.write(lineItems[0]);
 comPort.write(lineItems[1]);
 comPort.write(".");
}


Stage Twelve: To be continued..


I need to finish my XBee tutorial before doing this stage. But am just about to start studying again. So this stage probably won't get completed for another couple of months. But I hope there is enough content to keep you satisfied for the time being.