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
main.cpp
- Committer:
- cawald18
- Date:
- 2021-05-02
- Revision:
- 7:dd65856c3982
- Parent:
- 6:2450dc369670
- Child:
- 8:202142fffa4e
File content as of revision 7:dd65856c3982:
/* 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 "SDFileSystem.h" #include <string> #include <sstream> #include <iostream> #include <cstdlib> Thread motor; SDFileSystem sd(p5, p6, p7, p8, "sd"); Serial pc(USBTX, USBRX); // tx, rx 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; float stop; Note(int midi, float sta, float sto) { start = sta; stop = sto; midiNote = midi; } }; 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); //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; //These are the ticker functions that call the flip functions Ticker t2; Ticker t3; float motor1stop; //These are the times each motor is going to stop at in seconds float motor2stop; float motor3stop; Timer motor1timer; //Used to keep track of the time void flip1() //These flip the output pins, generating a pulse { f1 = !f1; } void flip2() { f2 = !f2; } void flip3(){ f3 = !f3; } /* Takes the midi number in from the array and then converts it to a frequency in hz; */ float midi2freq(float midi){ return 440.0*powf(2.0, (midi-69)/12); } int main() { f1 = 0; //Initialize everything f2 = 0; f3 = 0; m1e = 0; m2e = 0; m3e = 0; motor1stop = 0; motor2stop = 0; motor3stop = 0; 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); //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 float num_float = std::atof(d); // 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"); //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); //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 the character is a comma, we have parsed the full note stringstream degree(output); 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; //If this isn't the end of the file, lets add the character we read onto the end } } 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(); num_float = std::atof(d); //pc.printf("%f\n", num_float); output = ""; myNote.start = num_float; holdStart = 1; } else { output+= c; } } output = ""; while(!holdFinish){ //Do the same thing as above with durations c = fgetc(fpfinish); if(c == ','){ d = output.c_str(); num_float = std::atof(d); //pc.printf("%f\n", num_float); output = ""; myNote.stop = num_float; holdFinish = 1; } else { output+= c; } } //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-.001)< motor1timer.read()){ t2.detach(); m2e = 0; } 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-.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(); //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-.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-.002 < motor1timer.read()) { t3.attach(&flip3, .5/midi2freq(myNote.midiNote)); motor3stop = myNote.stop+motor1timer.read(); m3e = 1; holdNotes = 0; holdStart = 0; holdFinish = 0; } 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; } } //We have now finished assigning the note to be played led1 = !led1; } //End of while loop for playing motor1stop = 0; motor2stop = 0; motor3stop = 0; }