piano 4 octaves, 8 notes, 3 threads, 2 outputs, no bug, clean code, comments, remove old .h

Dependencies:   TextLCD

Fork of Nucleo_piano_CS435 by karine aknin

Committer:
aknin001
Date:
Wed Jul 04 21:47:32 2018 +0000
Revision:
8:781b03221397
Parent:
7:d2fe1a5e79ed
Child:
9:9a36b66869fa
project clean just need comments

Who changed what in which revision?

UserRevisionLine numberNew contents of line
bcostm 0:5701b41769fd 1 #include "mbed.h"
Aliened 3:ca0d5d72f842 2 #include "TextLCD.h"
aknin001 5:824785b64822 3 #include <string.h>
aknin001 5:824785b64822 4 #include <math.h>
aknin001 7:d2fe1a5e79ed 5
Aliened 3:ca0d5d72f842 6 // Define screen
Aliened 3:ca0d5d72f842 7 TextLCD lcd(PA_8, PA_9, PC_7, PB_6, PA_7, PA_6, PA_5); // RS, RW, E, D4-D7
Aliened 3:ca0d5d72f842 8
aknin001 5:824785b64822 9 // Define Bus In for Buttons (Do, Re, Mi, Fa, Sol, La, Si, Do)
aknin001 5:824785b64822 10 BusIn Bus_In(PA_0, PA_1, PA_4, PB_0, PA_10, PB_3, PB_5, PB_4);
bcostm 0:5701b41769fd 11
Aliened 3:ca0d5d72f842 12 // Define the PWM speaker
Aliened 3:ca0d5d72f842 13 PwmOut speaker(PB_10);
aknin001 7:d2fe1a5e79ed 14
aknin001 7:d2fe1a5e79ed 15 //Define Bus In for Gamme Button
aknin001 7:d2fe1a5e79ed 16 BusIn Bus_In_Gamme(PB_9);
aknin001 7:d2fe1a5e79ed 17
Aliened 3:ca0d5d72f842 18 //Define variables for sound
aknin001 5:824785b64822 19 struct NoteReference {
aknin001 5:824785b64822 20 char name[4];
aknin001 5:824785b64822 21 int mask;
aknin001 5:824785b64822 22 double frequency;
aknin001 5:824785b64822 23 double add[4];
aknin001 5:824785b64822 24 };
aknin001 7:d2fe1a5e79ed 25
aknin001 8:781b03221397 26 NoteReference noteReference[8] = { {"Do", 0x1, 262.0, {0.0, -1.0, -1.5, -3.0}},
aknin001 8:781b03221397 27 {"Re", 0x2, 294.0, {0.0, -1.0, -1.0, -3.0 }},
aknin001 8:781b03221397 28 {"Mi", 0x4, 330.0, {0.0, -1.0, -1.5, -3.0}},
aknin001 8:781b03221397 29 {"Fa", 0x8, 349.0, {0.0, 0.5, -1.0, 2.0}},
aknin001 8:781b03221397 30 {"Sol", 0x10, 392.0, {0.0, 0.0, 0.0, 0.0}},
aknin001 8:781b03221397 31 {"La", 0x20, 440.0, {0.0, 0.0, 0.0, 0.0}},
aknin001 8:781b03221397 32 {"Si", 0x40, 494.0, {0.0, 0.0, -1.0, -1.0}},
aknin001 8:781b03221397 33 {"Do", 0x80, 523.0, {0.0, 0.0, 0.0, 0.0}}
aknin001 8:781b03221397 34 };
aknin001 8:781b03221397 35 volatile int stateButtons = 0;
aknin001 8:781b03221397 36 volatile int stateButtonGamme = 0;
aknin001 5:824785b64822 37 volatile int gamme = 0;
Aliened 3:ca0d5d72f842 38
aknin001 7:d2fe1a5e79ed 39 //Define variable for display
aknin001 7:d2fe1a5e79ed 40 char bufferOutput[30] = "";
bcostm 0:5701b41769fd 41
aknin001 7:d2fe1a5e79ed 42 //Define variables for synchronization
aknin001 7:d2fe1a5e79ed 43 Mutex lockBufferOutput;
aknin001 7:d2fe1a5e79ed 44 Mutex lockGamme;
aknin001 7:d2fe1a5e79ed 45
Aliened 3:ca0d5d72f842 46 void refresh_state_button()
Aliened 3:ca0d5d72f842 47 {
aknin001 8:781b03221397 48 stateButtons = Bus_In & Bus_In.mask(); // read the bus and mask out bits not being used
Aliened 3:ca0d5d72f842 49 }
aknin001 7:d2fe1a5e79ed 50
aknin001 5:824785b64822 51 void play_music(int notes, double frequency)
Aliened 3:ca0d5d72f842 52 {
aknin001 7:d2fe1a5e79ed 53 speaker.period(1.0 / frequency);
aknin001 8:781b03221397 54 while (stateButtons == notes) {
Aliened 3:ca0d5d72f842 55 refresh_state_button();
Aliened 3:ca0d5d72f842 56 }
Aliened 3:ca0d5d72f842 57 }
aknin001 8:781b03221397 58
aknin001 8:781b03221397 59 double generate_frequency(double frequency, int actualGamme)
aknin001 8:781b03221397 60 {
aknin001 8:781b03221397 61 frequency = 0.0;
aknin001 8:781b03221397 62 lockBufferOutput.lock();
aknin001 8:781b03221397 63 strcpy(bufferOutput, "");
aknin001 8:781b03221397 64 for (int i = 0; i < 8; i++) {
aknin001 8:781b03221397 65 if (!(stateButtons & noteReference[i].mask))
aknin001 8:781b03221397 66 {
aknin001 8:781b03221397 67 frequency += noteReference[i].frequency * pow(2.0, (double)actualGamme) + noteReference[i].add[actualGamme];
aknin001 8:781b03221397 68 strcat(bufferOutput, noteReference[i].name);
aknin001 8:781b03221397 69 strcat(bufferOutput, " ");
aknin001 8:781b03221397 70 }
aknin001 8:781b03221397 71 }
aknin001 8:781b03221397 72 lockBufferOutput.unlock();
aknin001 8:781b03221397 73 return (frequency);
aknin001 8:781b03221397 74 }
aknin001 7:d2fe1a5e79ed 75
aknin001 7:d2fe1a5e79ed 76 void check_buttons(double frequency, int actualGamme)
Aliened 3:ca0d5d72f842 77 {
aknin001 8:781b03221397 78 if (stateButtons == 0xFF)
aknin001 5:824785b64822 79 {
aknin001 6:58bab17100a2 80 speaker = 0;
aknin001 7:d2fe1a5e79ed 81 lockBufferOutput.lock();
aknin001 7:d2fe1a5e79ed 82 strcpy(bufferOutput, "");
aknin001 7:d2fe1a5e79ed 83 lockBufferOutput.unlock();
aknin001 6:58bab17100a2 84 }
aknin001 6:58bab17100a2 85 else {
aknin001 7:d2fe1a5e79ed 86 lockGamme.lock();
aknin001 7:d2fe1a5e79ed 87 actualGamme = gamme;
aknin001 7:d2fe1a5e79ed 88 lockGamme.unlock();
aknin001 8:781b03221397 89 frequency = generate_frequency(frequency, actualGamme);
aknin001 6:58bab17100a2 90 speaker = 0.5;
aknin001 8:781b03221397 91 play_music(stateButtons, frequency);
Aliened 3:ca0d5d72f842 92 }
Aliened 3:ca0d5d72f842 93 }
Aliened 3:ca0d5d72f842 94
aknin001 7:d2fe1a5e79ed 95 void run_music()
aknin001 7:d2fe1a5e79ed 96 {
aknin001 7:d2fe1a5e79ed 97 double frequency = 0.0;
aknin001 7:d2fe1a5e79ed 98 int actualGamme = 0;
aknin001 7:d2fe1a5e79ed 99
aknin001 7:d2fe1a5e79ed 100 while (true)
aknin001 7:d2fe1a5e79ed 101 {
aknin001 7:d2fe1a5e79ed 102 refresh_state_button();
aknin001 7:d2fe1a5e79ed 103 check_buttons(frequency, actualGamme);
aknin001 7:d2fe1a5e79ed 104 Thread::wait(100);
aknin001 7:d2fe1a5e79ed 105 }
aknin001 7:d2fe1a5e79ed 106 }
Aliened 3:ca0d5d72f842 107
aknin001 7:d2fe1a5e79ed 108 void run_display()
aknin001 7:d2fe1a5e79ed 109 {
aknin001 7:d2fe1a5e79ed 110 char old_buffer[30] = "";
aknin001 8:781b03221397 111 int old_gamme = 0;
aknin001 7:d2fe1a5e79ed 112
aknin001 7:d2fe1a5e79ed 113 lockBufferOutput.lock();
aknin001 7:d2fe1a5e79ed 114 lockGamme.lock();
aknin001 7:d2fe1a5e79ed 115 lcd.printf("Gamme = %d", gamme);
aknin001 7:d2fe1a5e79ed 116 lockGamme.unlock();
aknin001 7:d2fe1a5e79ed 117 lockBufferOutput.unlock();
aknin001 7:d2fe1a5e79ed 118 while(true)
aknin001 7:d2fe1a5e79ed 119 {
aknin001 7:d2fe1a5e79ed 120 lockBufferOutput.lock();
aknin001 7:d2fe1a5e79ed 121 if (strcmp(old_buffer, bufferOutput))
aknin001 7:d2fe1a5e79ed 122 {
aknin001 7:d2fe1a5e79ed 123 lcd.cls();
aknin001 7:d2fe1a5e79ed 124 lockGamme.lock();
aknin001 7:d2fe1a5e79ed 125 if (strcmp(bufferOutput, ""))
aknin001 7:d2fe1a5e79ed 126 lcd.printf("%s- g[%d]", bufferOutput, gamme);
aknin001 7:d2fe1a5e79ed 127 else
aknin001 7:d2fe1a5e79ed 128 lcd.printf("Gamme = %d", gamme);
aknin001 7:d2fe1a5e79ed 129 lockGamme.unlock();
aknin001 7:d2fe1a5e79ed 130 strcpy(old_buffer, bufferOutput);
aknin001 7:d2fe1a5e79ed 131 }
aknin001 7:d2fe1a5e79ed 132 else {
aknin001 7:d2fe1a5e79ed 133 lockGamme.lock();
aknin001 7:d2fe1a5e79ed 134 if (old_gamme != gamme)
aknin001 7:d2fe1a5e79ed 135 {
aknin001 7:d2fe1a5e79ed 136 lcd.cls();
aknin001 7:d2fe1a5e79ed 137 lcd.printf("Gamme = %d", gamme);
aknin001 7:d2fe1a5e79ed 138 old_gamme = gamme;
aknin001 7:d2fe1a5e79ed 139 }
aknin001 7:d2fe1a5e79ed 140 lockGamme.unlock();
aknin001 7:d2fe1a5e79ed 141 }
aknin001 7:d2fe1a5e79ed 142 lockBufferOutput.unlock();
aknin001 7:d2fe1a5e79ed 143 Thread::wait(100);
aknin001 7:d2fe1a5e79ed 144 }
aknin001 7:d2fe1a5e79ed 145 }
aknin001 7:d2fe1a5e79ed 146
aknin001 7:d2fe1a5e79ed 147 void check_state_button_gamme()
aknin001 7:d2fe1a5e79ed 148 {
aknin001 8:781b03221397 149 stateButtonGamme = Bus_In_Gamme & Bus_In_Gamme.mask();
aknin001 7:d2fe1a5e79ed 150 }
aknin001 7:d2fe1a5e79ed 151
aknin001 7:d2fe1a5e79ed 152 void run_gamme()
aknin001 7:d2fe1a5e79ed 153 {
aknin001 7:d2fe1a5e79ed 154 while(true)
aknin001 7:d2fe1a5e79ed 155 {
aknin001 7:d2fe1a5e79ed 156 check_state_button_gamme();
aknin001 8:781b03221397 157 if (stateButtonGamme == 0x0)
aknin001 7:d2fe1a5e79ed 158 {
aknin001 7:d2fe1a5e79ed 159 lockGamme.lock();
aknin001 8:781b03221397 160 gamme = (gamme == 3) ? 0 : gamme + 1;
aknin001 7:d2fe1a5e79ed 161 lockGamme.unlock();
aknin001 8:781b03221397 162 while (stateButtonGamme == 0x0)
aknin001 7:d2fe1a5e79ed 163 check_state_button_gamme();
aknin001 7:d2fe1a5e79ed 164 }
aknin001 7:d2fe1a5e79ed 165 Thread::wait(100);
aknin001 7:d2fe1a5e79ed 166 }
aknin001 7:d2fe1a5e79ed 167 }
Aliened 3:ca0d5d72f842 168
bcostm 0:5701b41769fd 169 int main()
bcostm 0:5701b41769fd 170 {
aknin001 7:d2fe1a5e79ed 171 Thread music_thread;
aknin001 7:d2fe1a5e79ed 172 Thread display_thread;
aknin001 7:d2fe1a5e79ed 173 Thread gamme_thread;
aknin001 7:d2fe1a5e79ed 174
aknin001 7:d2fe1a5e79ed 175 lcd.printf("CS435 : Piano Project\n");
aknin001 7:d2fe1a5e79ed 176 wait(3);
aknin001 7:d2fe1a5e79ed 177 lcd.cls();
aknin001 7:d2fe1a5e79ed 178
aknin001 7:d2fe1a5e79ed 179 music_thread.start(run_music);
aknin001 7:d2fe1a5e79ed 180 display_thread.start(run_display);
aknin001 7:d2fe1a5e79ed 181 gamme_thread.start(run_gamme);
aknin001 7:d2fe1a5e79ed 182 while(1);
aknin001 7:d2fe1a5e79ed 183 }