karine aknin / Mbed OS Nucleo_piano_final_clean

Dependencies:   TextLCD

Fork of Nucleo_piano_final by karine aknin

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers main.cpp Source File

main.cpp

00001 #include "mbed.h"
00002 #include "TextLCD.h"
00003 #include <string.h>
00004 #include <math.h>
00005  
00006 // Define screen
00007 TextLCD lcd(PA_8, PA_9, PC_7, PB_6, PA_7, PA_6, PA_5); // RS, RW, E, D4-D7
00008  
00009 // Define Bus In for Buttons (Do, Re, Mi, Fa, Sol, La, Si, Do)
00010 BusIn Bus_In(PA_0, PA_1, PA_4, PB_0, PA_10, PB_3, PB_5, PB_4);
00011 
00012 // Define the PWM speaker
00013 PwmOut speaker(PB_10);
00014 
00015 //Define Bus In for Gamme Button
00016 BusIn Bus_In_Gamme(PB_9);
00017    
00018 //Define variables for sound
00019 struct  NoteReference {
00020     char    name[4];
00021     int     mask;
00022     double  frequency;
00023     double  add[4];
00024     };
00025     
00026 NoteReference   noteReference[8] = {    {"Do", 0x1, 262.0, {0.0, -1.0, -1.5, -3.0}},
00027                                         {"Re", 0x2, 294.0, {0.0, -1.0, -1.0, -3.0 }},
00028                                         {"Mi", 0x4, 330.0, {0.0, -1.0, -1.5, -3.0}},
00029                                         {"Fa", 0x8, 349.0, {0.0, 0.5, -1.0, 2.0}},
00030                                         {"Sol", 0x10, 392.0, {0.0, 0.0, 0.0, 0.0}},
00031                                         {"La", 0x20, 440.0, {0.0, 0.0, 0.0, 0.0}},
00032                                         {"Si", 0x40, 494.0, {0.0, 0.0, -1.0, -1.0}},
00033                                         {"Do", 0x80, 523.0, {0.0, 0.0, 0.0, 0.0}}
00034                                     };
00035 volatile int    stateButtons = 0;
00036 volatile int    stateButtonGamme = 0;
00037 volatile int    gamme = 0;
00038 
00039 //Define variable for display
00040 char     bufferOutput[30] = "";
00041 
00042 //Define variables for synchronization
00043 Mutex   lockBufferOutput;
00044 Mutex   lockGamme;
00045  
00046 void    refresh_state_button()
00047 {
00048    stateButtons = Bus_In & Bus_In.mask(); // read the bus and mask out bits not being used
00049 }
00050  
00051 void        play_music(int notes, double frequency)
00052 {
00053    speaker.period(1.0 / frequency);
00054    while (stateButtons == notes) {
00055      refresh_state_button();
00056    }
00057 }
00058 
00059 double      generate_frequency(double frequency, int actualGamme)
00060 {
00061     frequency = 0.0;
00062     lockBufferOutput.lock();
00063     strcpy(bufferOutput, "");
00064     for (int i = 0; i < 8; i++) {
00065         if (!(stateButtons & noteReference[i].mask))
00066         {
00067             frequency += noteReference[i].frequency * pow(2.0, (double)actualGamme) + noteReference[i].add[actualGamme];
00068             strcat(bufferOutput, noteReference[i].name);
00069             strcat(bufferOutput, " ");
00070         }
00071     }
00072     lockBufferOutput.unlock();
00073     return (frequency);
00074 }
00075  
00076 void        check_buttons(double frequency, int actualGamme)
00077 {
00078     if (stateButtons == 0xFF)
00079     {
00080         speaker = 0;
00081         lockBufferOutput.lock();
00082         strcpy(bufferOutput, "");
00083         lockBufferOutput.unlock();
00084     }
00085     else {
00086         lockGamme.lock();
00087         actualGamme = gamme;
00088         lockGamme.unlock();
00089         frequency = generate_frequency(frequency, actualGamme);
00090         speaker = 0.5;
00091         play_music(stateButtons, frequency);
00092     }
00093 }
00094 
00095 void    run_music()
00096 {
00097     double  frequency = 0.0;
00098     int     actualGamme = 0;
00099     
00100     while (true)
00101     {
00102         refresh_state_button();
00103         check_buttons(frequency, actualGamme);
00104         Thread::wait(100);
00105     }
00106 }
00107 
00108 void    run_display()
00109 {
00110     char    old_buffer[30] = "";
00111     int     old_gamme = 0;
00112     
00113     lockBufferOutput.lock();
00114     lockGamme.lock();
00115     lcd.printf("Gamme = %d", gamme);
00116     lockGamme.unlock();
00117     lockBufferOutput.unlock();
00118     while(true)
00119     {
00120         lockBufferOutput.lock();
00121         if (strcmp(old_buffer, bufferOutput))
00122         {
00123             lcd.cls();
00124             lockGamme.lock();
00125             if (strcmp(bufferOutput, ""))
00126                 lcd.printf("%s- g[%d]", bufferOutput, gamme);
00127             else
00128                 lcd.printf("Gamme = %d", gamme);
00129             lockGamme.unlock();
00130             strcpy(old_buffer, bufferOutput);
00131         }
00132         else {
00133             lockGamme.lock();
00134             if (old_gamme != gamme)
00135             {
00136                 lcd.cls();
00137                 lcd.printf("Gamme = %d", gamme);
00138                 old_gamme = gamme;
00139             }
00140             lockGamme.unlock();
00141         }
00142         lockBufferOutput.unlock();
00143         Thread::wait(100);
00144     }
00145 }
00146 
00147 void     check_state_button_gamme()
00148 {
00149     stateButtonGamme = Bus_In_Gamme & Bus_In_Gamme.mask();
00150 }
00151 
00152 void    run_gamme()
00153 {
00154     while(true)
00155     {
00156         check_state_button_gamme();
00157         if (stateButtonGamme == 0x0)
00158         {
00159             lockGamme.lock();
00160             gamme = (gamme == 3) ? 0 : gamme + 1;
00161             lockGamme.unlock();
00162             while (stateButtonGamme == 0x0)
00163                 check_state_button_gamme();
00164         }
00165         Thread::wait(100);
00166     }
00167 }
00168 
00169 int main()
00170 {
00171     Thread  music_thread;
00172     Thread  display_thread;
00173     Thread  gamme_thread;
00174     
00175     lcd.printf("CS435 : Piano Project\n");
00176     wait(3);
00177     lcd.cls();
00178  
00179     music_thread.start(run_music);
00180     display_thread.start(run_display);
00181     gamme_thread.start(run_gamme);
00182     while(1);
00183 }