Mac Lobdell / Mbed OS RubeGoldberg

Dependencies:   Adafruit_32x8matrix

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers main.cpp Source File

main.cpp

00001 /*
00002  * Copyright (c) 2016 ARM Limited. All rights reserved.
00003  * SPDX-License-Identifier: Apache-2.0
00004  * Licensed under the Apache License, Version 2.0 (the License); you may
00005  * not use this file except in compliance with the License.
00006  * You may obtain a copy of the License at
00007  *
00008  * http://www.apache.org/licenses/LICENSE-2.0
00009  *
00010  * Unless required by applicable law or agreed to in writing, software
00011  * distributed under the License is distributed on an AS IS BASIS, WITHOUT
00012  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00013  * See the License for the specific language governing permissions and
00014  * limitations under the License.
00015  */
00016  
00017 #include "mbed.h"       // this tells us to load mbed  related functions
00018 #include "tones.h"      // list of all the tones and their frequencies
00019  
00020 #include "Adafruit_32x8matrix.h"
00021  
00022 #define I2C_ADDR1 0x70
00023 #define I2C_ADDR2 0x71
00024 #define ROTATION1 0
00025 #define ROTATION2 2
00026 #define BRIGHTNESS 1
00027  
00028 I2C i2c(D14, D15);
00029  
00030 Adafruit_32x8matrix matrix(&i2c, I2C_ADDR1, I2C_ADDR2, ROTATION1, ROTATION2, BRIGHTNESS);
00031 Thread t1;
00032 Thread t2;
00033 InterruptIn sw(D4);
00034 EventQueue queue1(32 * EVENTS_EVENT_SIZE);
00035 EventQueue queue2(32 * EVENTS_EVENT_SIZE);
00036 
00037 PwmOut buzzer(D3);                   // our buzzer is a PWM output (pulse-width modulation)
00038 
00039 static int BPM = 80;
00040 
00041 static void silence() {
00042     buzzer.write(0.0f); // silence!
00043 }
00044 
00045 // this is our function that plays a tone. 
00046 // Takes in a tone frequency, and after duration (in ms.) we stop playing again
00047 static void play_tone(int tone) {
00048     buzzer.period_us(1000000/(tone));
00049     buzzer.write(0.10f); // 10% duty cycle, otherwise it's too loud
00050 }
00051 
00052 static void play_song(int notes_left, int* melody, int* duration) {
00053     
00054     // melody and duration are pointers, they point to the array of tones and durations we declared earlier
00055     // every time we play a note we up these pointers (move one element forward)
00056     // so the current tone is always the first element of melody (same for duration)
00057  
00058     int length;
00059  
00060     while(notes_left > 0)
00061     {
00062  
00063         int tone = melody[0];
00064         // BPM is quarter notes per minute, so length in milliseconds is:
00065         length = static_cast<int>(static_cast<float>(1000 / duration[0]) * (60000.0f / static_cast<float>(BPM * 1000)));
00066  
00067         play_tone(tone);
00068  
00069         // after half the length of this tone, we silence
00070         wait_ms(length / 2);  
00071         silence();
00072  
00073         //after the full length of this tone, call next note 
00074         wait_ms(length); 
00075                    
00076         // after the full length of this tone, we up the melody, and down the notes_left
00077         
00078         notes_left--;
00079         melody++;
00080         duration++;
00081             
00082     }  
00083  
00084     // we're done! just finish this note and silence
00085     wait_ms(length / 2);  
00086     silence();   
00087 }
00088 
00089 void start_song()
00090 {
00091     // declare a melody
00092     int melody[] = {
00093         NOTE_G4, NOTE_C5, NOTE_E5, NOTE_G5, NOTE_E5, NOTE_G5 
00094     };
00095     
00096     // note durations: 4 = quarter note, 8 = eighth note, etc.:
00097     // the rapid succession of 16th notes produces a twill effect
00098     int duration[] = {
00099         8, 8, 8, 4, 8, 2
00100     };    
00101     
00102     // melody & duration are on the heap, need to get them on the stack
00103     int *m = new int[sizeof(melody) / sizeof(int)];
00104     memcpy(m, melody, sizeof(melody));
00105     int *d = new int[sizeof(duration) / sizeof(int)];
00106     memcpy(d, duration, sizeof(duration));
00107     
00108         
00109     if (sizeof(melody) != sizeof(duration)) {
00110         printf("Melody and duration do not have same number of elements! Aborting!\r\n");
00111     }
00112    
00113     for (int i = 0; i< 3; i++)
00114     {  
00115         play_song(sizeof(melody) / sizeof(int), m, d);                        
00116         Thread::wait(100);
00117     }
00118     
00119 }
00120     
00121 void start_display()
00122 {
00123     char buffer [50];
00124     snprintf(buffer, 50, "GO TIGERS!\0");   //pass in max chars to prevent overflow
00125 
00126     for (int i = 0; i< 3; i++) {
00127         matrix.playText(buffer,strlen(buffer), 1);
00128         Thread::wait(250);
00129     }
00130 }
00131 
00132 void switch_handler(void)
00133 {
00134     queue1.call(start_song);
00135     queue2.call(start_display);
00136     
00137 } 
00138 
00139 int main() {
00140     
00141     // Start the event queues
00142     t1.start(callback(&queue1, &EventQueue::dispatch_forever));
00143     t2.start(callback(&queue2, &EventQueue::dispatch_forever));
00144     
00145     // Call handler when the switch is pressed
00146     sw.fall(switch_handler);
00147         
00148     while(1)
00149     {//chill
00150     }
00151  
00152     return 0;
00153  
00154 }