Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: SDFileSystem mbed
Revision 0:660f0e3ac256, committed 2016-04-30
- Comitter:
- mvanderpohl
- Date:
- Sat Apr 30 14:12:06 2016 +0000
- Commit message:
- initial commit
Changed in this revision
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/SDFileSystem.lib Sat Apr 30 14:12:06 2016 +0000 @@ -0,0 +1,1 @@ +http://developer.mbed.org/teams/mbed/code/SDFileSystem/#7b35d1709458
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp Sat Apr 30 14:12:06 2016 +0000
@@ -0,0 +1,497 @@
+//libraries
+#include "mbed.h"
+#include "SDFileSystem.h" // SD File System functions
+
+PwmOut tone(PTC2); //create a PWM pin
+Serial pc(USBTX,USBRX); //create a COM port
+SDFileSystem sd(PTE3, PTE1, PTE2, PTE4, "sd"); //MOSI, MISO, clk, CS
+//switches
+DigitalIn sw2(SW2); //playback recording
+DigitalIn sw4(PTD1); //play a song
+DigitalIn sw5(PTD3); //start/end recording
+DigitalIn sw6(PTD2); //play a song
+//LEDs
+DigitalOut led1(LED_RED);
+DigitalOut led2(LED_GREEN);
+DigitalOut led3(LED_BLUE);
+DigitalOut recordLight(PTA2);
+//interrupts
+InterruptIn Interrupt1(SW3); //change the octave
+//defines
+#define MAXRECORDLENGTH 100
+#define ODE2JOYLENGTH 62
+#define JINGLELENGTH 51
+
+//vars
+int tonelevel = 4; //Default octave 4
+int mode = 0; //mode=0 play //mode=1 record
+int recordLength = 0; //keep track of the actual length vs. the max length
+float record[MAXRECORDLENGTH]; //array for storing recorded tone
+
+//determine which song is playing
+bool jingleSet = false;
+bool odeSet = false;
+
+ //#######################################################################################################
+float octave[7][12]={
+ {55.0,62.0,33.0,37.0,41.0,44.0,49.0,58.0,35.0,39.0,46.0,52.0}, //1
+ {110.0,123.0,65.0,73.0,82.0,87.0,98.0,117.0,69.0,78.0,93.0,104.0}, //2
+ {220.0,247.0,131.0,147.0,165.0,175.0,196.0,233.0,139.0,156.0,185.0,208.0}, //3
+ {440.0,494.0,262.0,294.0,330.0,349.0,392.0,466.0,277.0,311.0,370.0,415.0}, //4
+ {880.0,988.0,523.0,587.0,659.0,698.0,784.0,932.0,554.0,622.0,740.0,831.0}, //5
+ {1760.0,1976.0,1047.0,1175.0,1319.0,1397.0,1568.0,1865.0,1109.0,1245.0,1480.0,1661.0}, //6
+ {3520.0,3951.0,2093.0,2349.0,2637.0,2794.0,3136.0,3729.0,2217.0,2489.0,2960.0,3322.0} //7
+ };
+ //#######################################################################################################
+float starwars[]={octave[2][2],octave[2][6],octave[2][5],octave[2][4],octave[2][3],octave[3][2],
+ octave[2][2],octave[2][6],octave[2][5],octave[2][4],octave[2][3],octave[3][2],
+ octave[2][6],octave[2][5],octave[2][4],octave[2][5],octave[2][3]
+ };
+ //#######################################################################################################
+float ode2joy[]= {octave[tonelevel][4],octave[tonelevel][4],octave[tonelevel][5],octave[tonelevel][6],octave[tonelevel][6],octave[tonelevel][5],octave[tonelevel][4],octave[tonelevel][3],octave[tonelevel][2],octave[tonelevel][2],octave[tonelevel][3],octave[tonelevel][4],octave[tonelevel][4],octave[tonelevel][3],octave[tonelevel][3],
+ octave[tonelevel][4],octave[tonelevel][4],octave[tonelevel][5],octave[tonelevel][6],octave[tonelevel][6],octave[tonelevel][5],octave[tonelevel][4],octave[tonelevel][3],octave[tonelevel][2],octave[tonelevel][2],octave[tonelevel][3],octave[tonelevel][4],octave[tonelevel][3],octave[tonelevel][2],octave[tonelevel][2],
+ octave[tonelevel][3],octave[tonelevel][3],octave[tonelevel][4],octave[tonelevel][2],octave[tonelevel][3],octave[tonelevel][4],octave[tonelevel][5],octave[tonelevel][4],octave[tonelevel][2],octave[tonelevel][3],octave[tonelevel][4],octave[tonelevel][5],octave[tonelevel][4],octave[tonelevel][3],octave[tonelevel][2],octave[tonelevel][3],octave[tonelevel][2],
+ octave[tonelevel][4],octave[tonelevel][4],octave[tonelevel][5],octave[tonelevel][6],octave[tonelevel][6],octave[tonelevel][5],octave[tonelevel][4],octave[tonelevel][3],octave[tonelevel][2],octave[tonelevel][2],octave[tonelevel][3],octave[tonelevel][4],octave[tonelevel][3],octave[tonelevel][2],octave[tonelevel][2]};
+ //#######################################################################################################
+float jingle[]={octave[tonelevel][4],octave[tonelevel][4],octave[tonelevel][4],octave[tonelevel][4],octave[tonelevel][4],octave[tonelevel][4],octave[tonelevel][4],octave[tonelevel][6],octave[tonelevel][2],octave[tonelevel][3],octave[tonelevel][4],
+ octave[tonelevel][5],octave[tonelevel][5],octave[tonelevel][5],octave[tonelevel][5],octave[tonelevel][5],octave[tonelevel][4],octave[tonelevel][4],octave[tonelevel][4],octave[tonelevel][4],
+ octave[tonelevel][4],octave[tonelevel][3],octave[tonelevel][3],octave[tonelevel][4],octave[tonelevel][3],octave[tonelevel][6],
+ octave[tonelevel][4],octave[tonelevel][4],octave[tonelevel][4],octave[tonelevel][4],octave[tonelevel][4],octave[tonelevel][4],octave[tonelevel][4],octave[tonelevel][6],octave[tonelevel][2],octave[tonelevel][3],octave[tonelevel][4],
+ octave[tonelevel][5],octave[tonelevel][5],octave[tonelevel][5],octave[tonelevel][5],octave[tonelevel][5],octave[tonelevel][4],octave[tonelevel][4],octave[tonelevel][4],octave[tonelevel][4],
+ octave[tonelevel][6],octave[tonelevel][6],octave[tonelevel][5],octave[tonelevel][3],octave[tonelevel][2]};
+ //#######################################################################################################
+ int ode2joyNotes[] = {4,4,5,6,6,5,4,3,2,2,3,4,4,3,3,4,4,5,6,6,5,4,3,2,2,3,4,3,2,2,3,3,4,2,3,4,5,4,2,3,4,5,4,3,2,3,2,4,4,5,6,6,5,4,3,2,2,3,4,3,2,2};
+ //#######################################################################################################
+ int jingleNotes[] = {4,4,4,4,4,4,4,6,2,3,4,5,5,5,5,5,4,4,4,4,4,3,3,4,3,6,4,4,4,4,4,4,4,6,2,3,4,5,5,5,5,5,4,4,4,4,6,6,5,3,2};
+ //#######################################################################################################
+int tempo[]={600,400,400,400,500,600,400,400,400,500,600,400,400,400,400,400,1000};
+ //#######################################################################################################
+int tempo2[]={400,400,400,400,400,400,400,400,400,400,400,400,600,200,650,
+ 400,400,400,400,400,400,400,400,400,400,400,400,600,200,650,
+ 400,400,400,400,400,200,200,400,400,400,200,200,400,400,400,400,650,
+ 400,400,400,400,400,400,400,400,400,400,400,400,600,200,1000};
+ //#######################################################################################################
+int tempo3[]={400,400,500,350,350,500,350,350,350,350,700,
+ 400,400,400,350,350,350,400,150,600,
+ 400,400,400,400,450,600,
+ 400,400,500,350,350,500,350,350,350,350,700,
+ 400,400,400,350,350,350,400,150,600,
+ 400,400,400,400,600};
+ //#######################################################################################################
+
+//function prototypes
+void changeOctave(void);
+bool writeSD(void);
+bool readSD(void);
+bool removeFile(void);
+
+int main()
+{
+//INITIALIZATIONS
+ tone = 0; //volume (duty cycle)
+ int recordCounter = 0; //used to count up to max number of notes
+
+ led1 = 1; //turn all LEDs off
+ led2 = 1;
+ led3 = 1;
+ recordLight = 0;
+
+ pc.baud(9600); //set baud
+
+ Interrupt1.fall(&changeOctave); //detect interrupt on falling edge and call ISR
+
+//BEGIN LOOP
+ while (true)
+ {
+ //CHECK SW4 -- determine if we should play this song
+ if(sw4 == 1)
+ {
+ led3 = !led3;
+ odeSet = true;
+ for(int i=0;i<ODE2JOYLENGTH;i++)
+ {
+ tone=0.5;
+ tone.period(1/ode2joy[i]);
+ wait_ms(tempo2[i]);
+ }
+ odeSet = false;
+ tone=0;
+ }//end sw4
+
+ //CHECK SW6 -- determine if we should play this song
+ if(sw6 == 1)
+ {
+ led2 = !led2;
+ jingleSet = true;
+ for(int i=0;i<JINGLELENGTH;i++)
+ {
+ tone=0.5;
+ tone.period(1/jingle[i]);
+ wait_ms(tempo2[i]);
+ }
+ jingleSet = false;
+ tone=0;
+ }//end sw6
+
+ //mode 0 just recieves a character from the COM port, looks up the corresponding node
+ //and plays it over the speaker at a 50% duty cycle (loudest volume available)
+ if(mode==0 && pc.readable())
+ {
+ switch(pc.getc()) //Note selection
+ {
+ case 'a':
+ tone=0.5;
+ tone.period(1/octave[tonelevel][0]);
+ break;
+ case 'b':
+ tone=0.5;
+ tone.period(1/octave[tonelevel][1]);
+ break;
+ case 'c':
+ tone=0.5;
+ tone.period(1/octave[tonelevel][2]);
+ break;
+ case 'd':
+ tone=0.5;
+ tone.period(1/octave[tonelevel][3]);
+ break;
+ case 'e':
+ tone=0.5;
+ tone.period(1/octave[tonelevel][4]);
+ break;
+ case 'f':
+ tone=0.5;
+ tone.period(1/octave[tonelevel][5]);
+ break;
+ case 'g':
+ tone=0.5;
+ tone.period(1/octave[tonelevel][6]);
+ break;
+ case 'h':
+ tone=0.5;
+ tone.period(1/octave[tonelevel][7]);
+ break;
+ case 'i':
+ tone=0.5;
+ tone.period(1/octave[tonelevel][8]);
+ break;
+ case 'j':
+ tone=0.5;
+ tone.period(1/octave[tonelevel][9]);
+ break;
+ case 'k':
+ tone=0.5;
+ tone.period(1/octave[tonelevel][10]);
+ break;
+ case 'l':
+ tone=0.5;
+ tone.period(1/octave[tonelevel][11]);
+ break;
+ case 'm':
+ tone=0.5;
+ tone.period(1/octave[tonelevel][11]);
+ break;
+ default: //in the default case mute the sound
+ tone=0;
+ }//end switch
+
+ }//end if mode 0
+
+
+ //CHECK SW5 -- Go to recording mode
+ if(sw5 == 1)
+ {
+ while(sw5 == 1);
+ mode = 1;
+ led1 = !led1;
+ //reset length when we record a new song
+ recordLength = 0;
+ //delete the current recording before storing a new one
+ removeFile();
+ }
+
+
+ //record notes and set mode back to 0
+ if(mode==1)
+ {
+ tone=0.5;
+ //play a tone to let user know they can record
+ tone.period(1/octave[3][6]);
+ wait_ms(500);
+ tone.period(1/octave[5][6]);
+ wait_ms(500);
+ tone.period(1/octave[3][6]);
+ wait_ms(500);
+ tone.period(1/octave[5][6]);
+ wait_ms(500);
+ tone=0;
+
+ //read until we have reached max record length
+ while(recordCounter < MAXRECORDLENGTH )
+ {
+ switch(pc.getc()) //Note selection
+ {
+ case 'a':
+ record[recordCounter]=octave[tonelevel][0];
+ tone=0.5;
+ tone.period(1/octave[tonelevel][0]);
+
+ break;
+ case 'b':
+ record[recordCounter]=octave[tonelevel][1];
+ tone=0.5;
+ tone.period(1/octave[tonelevel][1]);
+
+ break;
+ case 'c':
+ record[recordCounter]=octave[tonelevel][2];
+ tone=0.5;
+ tone.period(1/octave[tonelevel][2]);
+
+ break;
+ case 'd':
+ record[recordCounter]=octave[tonelevel][3];
+ tone=0.5;
+ tone.period(1/octave[tonelevel][3]);
+ break;
+ case 'e':
+ record[recordCounter]=octave[tonelevel][4];
+ tone=0.5;
+ tone.period(1/octave[tonelevel][4]);
+
+ break;
+ case 'f':
+ record[recordCounter]=octave[tonelevel][5];
+ tone=0.5;
+ tone.period(1/octave[tonelevel][5]);
+
+ break;
+ case 'g':
+ record[recordCounter]=octave[tonelevel][6];
+ tone=0.5;
+ tone.period(1/octave[tonelevel][6]);
+
+ break;
+ case 'h':
+ record[recordCounter]=octave[tonelevel][7];
+ tone=0.5;
+ tone.period(1/octave[tonelevel][7]);
+
+ break;
+ case 'i':
+ record[recordCounter]=octave[tonelevel][8];
+ tone=0.5;
+ tone.period(1/octave[tonelevel][8]);
+
+ break;
+ case 'j':
+ record[recordCounter]=octave[tonelevel][9];
+ tone=0.5;
+ tone.period(1/octave[tonelevel][9]);
+
+ break;
+ case 'k':
+ record[recordCounter]=octave[tonelevel][10];
+ tone=0.5;
+ tone.period(1/octave[tonelevel][10]);
+ tone=0;
+ break;
+ case 'l':
+ record[recordCounter]=octave[tonelevel][11];
+ tone=0.5;
+ tone.period(1/octave[tonelevel][11]);
+
+ break;
+ case 'm':
+ record[recordCounter]=octave[tonelevel][11];
+ tone=0.5;
+ tone.period(1/octave[tonelevel][11]);
+
+ break;
+ default: //use a dummy note that will never get played in the default case
+ record[recordCounter]=octave[6][6];
+ tone=0;
+ }//end switch
+
+ recordCounter++;
+ recordLight = !recordLight;
+
+ //CHECK SW5 -- start or end recording
+ if(sw5 == 1)
+ {
+ while(sw5 == 1);
+ mode=1;
+ led1 = !led1;
+ recordLength = recordCounter;
+ break;
+ }
+
+ }//end while
+ recordCounter = 0;
+ mode = 0;
+ recordLight = 0;
+
+ //play a tone to let user know they are done
+ tone=0.5;
+ tone.period(1/octave[3][6]);
+ wait_ms(500);
+ tone.period(1/octave[5][6]);
+ wait_ms(500);
+ tone.period(1/octave[3][6]);
+ wait_ms(500);
+ tone.period(1/octave[5][6]);
+ wait_ms(500);
+ tone=0;
+ //write to the SD card after recording
+ writeSD();
+
+ }//end if
+
+ //play recored notes
+ if(mode==0 && sw2==0)
+ {
+ if(readSD() == true)
+ {
+ tone = 0.5;
+ for(int i=0;i<recordLength;i++)
+ {
+ if(record[i]==octave[6][6])
+ tone=0;
+ else
+ tone=0.5;
+
+ tone.period(1/record[i]);
+ //play the recording back a little faster than it was recorded
+ wait_ms(450);
+ }
+ led1 = !led1;
+ tone=0;
+ }
+ }//end play
+ led1 = !led1;
+ wait_ms(100);
+
+ }//end main while loop
+
+}//main closes
+
+//used to change the current octave even in the middle of playing a preset song but
+//has no effect during playback of recorded music
+void changeOctave()
+{
+ tonelevel+=1;
+ if(tonelevel > 6)
+ tonelevel = 2;
+ led2 = !led2;
+
+ //account for change in octave level
+ if(odeSet == true)
+ {
+ for(int i=0; i<ODE2JOYLENGTH; i++)
+ {
+ ode2joy[i] = octave[tonelevel][ode2joyNotes[i]];
+ }
+ }
+ else if(jingleSet == true)
+ {
+ for(int i=0; i<JINGLELENGTH; i++)
+ {
+ jingle[i]= octave[tonelevel][jingleNotes[i]];
+ }
+ }
+}//end change octave
+
+//Write to the SD card
+bool writeSD()
+{
+ FILE *fp = fopen("/sd/sdfile.txt", "w"); // open file for writing
+
+ if (fp==NULL)
+ {
+ pc.printf("Could not open file to write\n");
+ return false;
+ }
+ else
+ {
+ pc.printf("SC card opened\r\n");
+ //wait_ms(1000);
+ }
+
+ if(fprintf(fp, "%d", recordLength)) //first store the size of the array
+ pc.printf("Write of length of sucessful and it is %d\r\n\n", recordLength);
+
+ //wait_ms(1000);
+ fprintf(fp, " "); //delimit the values
+
+ for(int i=0; i<recordLength; i++) //copy all values over
+ {
+ if(fprintf(fp, "%f", record[i]))
+ {
+ fprintf(fp," "); //delimit the values
+ pc.printf("Number of tones stored is : %d\r\n\n", i+1);
+ pc.printf("The tone is %f \r\n", record[i]);
+ }
+ }
+ //wait_ms(1000);
+ fclose(fp);
+
+ return true;
+}//end write
+
+//read from a SD card
+bool readSD()
+{
+ FILE *fp = fopen("/sd/sdfile.txt", "r"); // open file for writing
+
+ if (fp==NULL)
+ {
+ pc.printf("Could not open file to write\n");
+ return false;
+ }
+ else
+ {
+ pc.printf("SC card opened\r\n");
+ //wait_ms(1000);
+ }
+
+
+
+ if(fscanf(fp, "%d", &recordLength)) //first read the size of the array
+ {
+ pc.printf("Write of length of sucessful and its value is %d\r\n\n", recordLength);
+ //wait_ms(1000);
+ }
+ else
+ return false;
+
+ for(int i=0; i<recordLength; i++) //copy all values over
+ {
+ if(fscanf(fp, "%f", &record[i]))
+ pc.printf("Tone stored is %f\r\n\n", record[i]);
+ else
+ return false;
+ }
+ //wait_ms(1000);
+ fclose(fp);
+ return true;
+}//end read
+
+//remove the file from the SD card before we create a new one
+bool removeFile()
+{
+ //create a string
+ char filename[] = "/sd/sdfile.txt";
+
+ int ret = remove(filename);
+
+ if(ret == 0)
+ {
+ pc.printf("File deleted successfully");
+ return false;
+ }
+ else
+ {
+ pc.printf("Error: unable to delete the file");
+ }
+ return true;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed.bld Sat Apr 30 14:12:06 2016 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/users/mbed_official/code/mbed/builds/99a22ba036c9 \ No newline at end of file