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: mbed mbed-rtos SDFileSystem11
Diff: main.cpp
- Revision:
- 7:dd65856c3982
- Parent:
- 6:2450dc369670
- Child:
- 8:202142fffa4e
--- a/main.cpp Mon Apr 26 22:05:32 2021 +0000 +++ b/main.cpp Sun May 02 20:07:22 2021 +0000 @@ -1,6 +1,17 @@ +/* +ECE 4180 Project - Stepper motor songs +Conner Awald and Evan Zhang + +TO-DO: The program does not exit gracefully when reaching the end of the file. +We should add a character that indicates the end of the file to the program. + +Also need to add bluetooth control so the user can select a file to play from preinstalled songs +maybe also add stop start controls? + +*/ + #include "mbed.h" #include "rtos.h" -#include "notes.h" #include "SDFileSystem.h" #include <string> #include <sstream> @@ -10,7 +21,9 @@ Thread motor; SDFileSystem sd(p5, p6, p7, p8, "sd"); Serial pc(USBTX, USBRX); // tx, rx -class Note { + +class Note { //I use this to create a note object which contains + // The pitch, starting time, and duration(stop) of the note public: int midiNote; float start; @@ -24,22 +37,28 @@ -DigitalOut led1(LED2); -DigitalOut f1(p21); +DigitalOut led1(LED2); //Used simply for debugging, could add functionailty + // So the led lights up when the corresponding motor is playing +DigitalOut f1(p21); //Flipper functions used to generate tones DigitalOut f2(p22); DigitalOut f3(p23); -DigitalOut m1e(p17); + +DigitalOut m1e(p17); //THIS ENABLES THE MOTOR DRIVER PINS. It is important to turn + // it off when the motor is not playing a note because + //the motor will waste power otherwise in the idle state DigitalOut m2e(p18); DigitalOut m3e(p19); -Ticker t1; + +Ticker t1; //These are the ticker functions that call the flip functions Ticker t2; Ticker t3; -float motor1stop; + +float motor1stop; //These are the times each motor is going to stop at in seconds float motor2stop; float motor3stop; -Timer motor1timer; - void flip1() +Timer motor1timer; //Used to keep track of the time + void flip1() //These flip the output pins, generating a pulse { f1 = !f1; } @@ -58,7 +77,7 @@ } int main() { - f1 = 0; + f1 = 0; //Initialize everything f2 = 0; f3 = 0; m1e = 0; @@ -68,11 +87,12 @@ motor2stop = 0; motor3stop = 0; - bool holdNotes = 0; //Stop reading notes file - bool holdStart = 0; //Stop reading start times + bool holdNotes = 0; //Stop reading notes file once we have the next note + bool holdStart = 0; //Stop reading start times once we have parsed the starrt bool holdFinish = 0; //Stop reading in finish times - pc.baud(115200); - const char * d; + pc.baud(115200); //Baud rate used for debugging if needed + const char * d; //This is old when I was messing around with this stuff + //But im actually not sure if I used the names later, should probably check std::string str = "123.4567"; d = str.c_str(); // convert string to float @@ -80,35 +100,37 @@ // convert string to double //pc.printf("%f\n", num_float-1.0); + pc.printf("Im Alive"); int temp = 0; pc.printf("Hello World!"); string output = ""; - FILE *fpn = fopen("/sd/notesmatrix.txt", "r"); - FILE *fpstart = fopen("/sd/notesstart.txt", "r"); - FILE *fpfinish = fopen("/sd/notesfinish.txt","r"); + FILE *fpn = fopen("/sd/notesmatrix.txt", "r"); //Fpn is a pointer to the notes file that contains the note values + FILE *fpstart = fopen("/sd/notesstart.txt", "r"); //Fpstart is a pointer to the file on the sd card that contains the start times + FILE *fpfinish = fopen("/sd/notesfinish.txt","r"); //Fpfinish is a pointer to the file on the sd card that says how long each note should last unsigned char c; //pc.printf("I'm here\n"); - Note myNote = Note(0, 0, 0); - motor1timer.start(); - while (!feof(fpn)){ // while not end of file - while(!holdNotes) { + Note myNote = Note(0, 0, 0); //Create a blank note + motor1timer.start(); //Start the timer + while (!feof(fpn)){ // while not end of file, keep goig + while(!holdNotes) { //Make sure we haven't completed the note section yet c = fgetc(fpn); // get a character/byte from the file - if(c == ','){ + if(c == ','){ //If the character is a comma, we have parsed the full note stringstream degree(output); - degree >> temp; + degree >> temp; //These are weird names I got from the example code I copied + // but basically this converts a string into a float //pc.printf("%d\n", temp); myNote.midiNote = temp; output = ""; holdNotes = 1; } else { - output += c; + output += c; //If this isn't the end of the file, lets add the character we read onto the end } } - output = ""; - while(!holdStart) { + output = ""; //Reset the output + while(!holdStart) { //Do the same thing as above but for the start times c = fgetc(fpstart); if(c == ','){ d = output.c_str(); @@ -123,7 +145,7 @@ } output = ""; - while(!holdFinish){ + while(!holdFinish){ //Do the same thing as above with durations c = fgetc(fpfinish); if(c == ','){ d = output.c_str(); @@ -136,43 +158,56 @@ output+= c; } - } //ONCE WE REACH THIS POINT ALL PARTS OF THE NOTE OBJECT SHOULD BE SET - if(motor1stop< motor1timer.read()) { + } //ONCE WE REACH THIS POINT ALL PARTS OF THE NOTE OBJECT SHOULD BE SET and USABLE + + /* + The next three functions check to see if the motors stop time has past + or will pass in the next ms. If so, it stops the motor from playing and + disables the pin. + */ + if((motor1stop-.001)< motor1timer.read()) { t1.detach(); m1e = 0; } - if(motor2stop< motor1timer.read()){ + if((motor2stop-.001)< motor1timer.read()){ t2.detach(); m2e = 0; } - if(motor3stop< motor1timer.read()) { + if((motor3stop-.001)< motor1timer.read()) { t3.detach(); m3e = 0; } + + /* + This now looks at the note object we currently have parsed in and sees + if it is time to try and assign it to a motor to be played. If it is not time, + we are simply going to keep looping until it is time. + */ if(myNote.start <= motor1timer.read()){ - if(motor1stop < motor1timer.read()) { //Check if we should add it + if(motor1stop-.002 < motor1timer.read()) { //Check to see if the motor has stopped playing or is going to stop playing t1.attach(&flip1, .5/midi2freq(myNote.midiNote)); // - motor1stop = myNote.stop+motor1timer.read(); - m1e = 1; - holdNotes = 0; + motor1stop = myNote.stop+motor1timer.read(); //Set the new stop time to be the current time plus the duration of the note + m1e = 1; //Enable the note + holdNotes = 0; //Reset the notes control to enable reading the next note holdStart = 0; holdFinish = 0; - } else if(motor2stop < motor1timer.read()) { + } else if(motor2stop-.002 < motor1timer.read()) { t2.attach(&flip2, .5/midi2freq(myNote.midiNote)); motor2stop = myNote.stop+motor1timer.read(); m2e = 1; holdNotes = 0; holdStart = 0; holdFinish = 0; - } else if(motor3stop < motor1timer.read()) { + } else if(motor3stop-.002 < motor1timer.read()) { t3.attach(&flip3, .5/midi2freq(myNote.midiNote)); motor3stop = myNote.stop+motor1timer.read(); m3e = 1; holdNotes = 0; holdStart = 0; holdFinish = 0; - } else { + } else { //If all three motors are playing something and it is time to play the new note, + // We simply do nothing with it and skip it holdNotes = 0; holdStart = 0; holdFinish = 0;