Mac Lobdell / Mbed OS RubeGoldberg

Dependencies:   Adafruit_32x8matrix

Revision:
9:d70273b3133b
Parent:
8:5f5ceafa826d
Child:
10:aa7764fae417
diff -r 5f5ceafa826d -r d70273b3133b main.cpp
--- a/main.cpp	Mon Dec 11 19:23:47 2017 +0000
+++ b/main.cpp	Wed Nov 03 19:49:24 2021 +0000
@@ -14,7 +14,8 @@
  * limitations under the License.
  */
  
-#include "mbed.h"
+#include "mbed.h"       // this tells us to load mbed  related functions
+#include "tones.h"      // list of all the tones and their frequencies
  
 #include "Adafruit_32x8matrix.h"
  
@@ -27,16 +28,106 @@
 I2C i2c(D14, D15);
  
 Adafruit_32x8matrix matrix(&i2c, I2C_ADDR1, I2C_ADDR2, ROTATION1, ROTATION2, BRIGHTNESS);
+Thread displayThread;
+
+PwmOut buzzer(D3);                   // our buzzer is a PWM output (pulse-width modulation)
+
+static int BPM = 80;
+
+static void silence() {
+    buzzer.write(0.0f); // silence!
+}
+
+// this is our function that plays a tone. 
+// Takes in a tone frequency, and after duration (in ms.) we stop playing again
+static void play_tone(int tone) {
+    buzzer.period_us(1000000/(tone));
+    buzzer.write(0.10f); // 10% duty cycle, otherwise it's too loud
+}
+
+static void play_song(int notes_left, int* melody, int* duration) {
+    
+    // melody and duration are pointers, they point to the array of tones and durations we declared earlier
+    // every time we play a note we up these pointers (move one element forward)
+    // so the current tone is always the first element of melody (same for duration)
+ 
+    int length;
+ 
+    while(notes_left > 0)
+    {
+ 
+        int tone = melody[0];
+        // BPM is quarter notes per minute, so length in milliseconds is:
+        length = static_cast<int>(static_cast<float>(1000 / duration[0]) * (60000.0f / static_cast<float>(BPM * 1000)));
+ 
+        play_tone(tone);
+ 
+        // after half the length of this tone, we silence
+        wait_ms(length / 2);  
+        silence();
+ 
+        //after the full length of this tone, call next note 
+        wait_ms(length); 
+                   
+        // after the full length of this tone, we up the melody, and down the notes_left
+        
+        notes_left--;
+        melody++;
+        duration++;
+            
+    }  
+ 
+    // we're done! just finish this note and silence
+    wait_ms(length / 2);  
+    silence();   
+}
+
+void display_thread()
+{
+    char buffer [50];
+    snprintf(buffer, 50, "GO TIGERS!\0");   //pass in max chars to prevent overflow
+
+    for (int i = 0; i< 3; i++) {
+        matrix.playText(buffer,strlen(buffer), 1);
+        Thread::wait(250);
+    }
+}
  
 int main() {
-  char buffer [50];
-
-  while(1)
-  { 
-        snprintf(buffer, 50, "Hi, how are you today?\0");   //pass in max chars to prevent overflow
-        matrix.playText(buffer,strlen(buffer), 1);
-                           
-        Thread::wait(10000);
+    
+    
+    // declare a melody
+     int melody[] = {
+        NOTE_G4, NOTE_C5, NOTE_E5, NOTE_G5, NOTE_E5, NOTE_G5 
+    };
+    
+    // note durations: 4 = quarter note, 8 = eighth note, etc.:
+    // the rapid succession of 16th notes produces a twill effect
+    int duration[] = {
+        8, 8, 8, 4, 8, 2
+    };    
+    
+    
+    // melody & duration are on the heap, need to get them on the stack
+    int *m = new int[sizeof(melody) / sizeof(int)];
+    memcpy(m, melody, sizeof(melody));
+    int *d = new int[sizeof(duration) / sizeof(int)];
+    memcpy(d, duration, sizeof(duration));
+    
+        
+    if (sizeof(melody) != sizeof(duration)) {
+        printf("Melody and duration do not have same number of elements! Aborting!\r\n");
+        return 1;
     }
+   
+    for (int i = 0; i< 3; i++)
+    { 
+        displayThread.start(display_thread);
+     
+        play_song(sizeof(melody) / sizeof(int), m, d);
+                               
+        Thread::wait(100);
+    }
+    return 0;
  
 }