ECE 4180 final project. Sound and Bluetooth activated coffee maker

Dependencies:   mbed wave_player mbed-rtos C12832_lcd 4DGL-uLCD-SE LCD_fonts SDFileSystem

Revision:
6:e4aba042979b
Parent:
5:18b2796e4847
Child:
7:2e274cc18797
--- a/main.cpp	Thu Oct 03 21:28:13 2019 +0000
+++ b/main.cpp	Thu Dec 05 15:30:50 2019 +0000
@@ -10,182 +10,303 @@
 #include "stdio.h"
 #include "C12832_lcd.h"
 #include "sound.h"
+#include "unsigned_fire_truck.h"
+#include "uLCD_4DGL.h"
+#include <mpr121.h>
 
 #define sample_freq 11025.0
 //get and set the frequency from wav conversion tool GUI
-int i=0;
 
-Ticker sampletick;
-C12832_LCD LCD;
-AnalogIn Pot1(p19);
-AnalogIn Pot2(p20);
+//set variables used to track throughout program
+int reset = 1; //check if coffee pot is reset and ready to brew again
+volatile int blink = 0; // check if blinking LED
+int tmp_blue = 0;  // check if bluetooth has been triggered at least 2 times
+int noise = 0; // check if still playing alarm
+int i=0; //index for audio array
+int d = 0; 
+volatile int trigger = 0; // check if coffeepot has been triggered via sound or bluetooth
+
+//Declarations
+Ticker sampletick; //audio interrupt
+uLCD_4DGL uLCD(p9,p10,p11);
+AnalogIn Therm0(p18);
+AnalogIn Therm1(p19);
+DigitalOut key(p20);
+
 PwmOut Speaker(p26);
 PwmOut RGBLED_r(p23);
-PwmOut RGBLED_g(p24);
-PwmOut RGBLED_b(p25);
-DigitalIn joyfire(p14);
-BusIn joy(p15,p12,p13,p16);
-BusOut leds(LED1,LED2,LED3,LED4);
+PwmOut RGBLED_g(p22);
+PwmOut RGBLED_b(p21);
+DigitalIn user_button(p12);
+Serial blue(p28,p27);
 
-// mutex to make the lcd lib thread safe
+// Mutex declarations
 Mutex lcd_mutex;
+Mutex leds_mutex;
+Mutex bmut;
+Mutex mic_mutex;
+Mutex trigger_mutex;
 
+volatile float r = 0.0;
+volatile float g = 0.0;
+volatile float b = 0.0;
+
+//Audio ISR 
 void audio_sample ()
 {
-
-    Speaker = sound_data[i]/255.0;//scale to 0.0 to 1.0 for PWM
-    i++;
-    if (i>= NUM_ELEMENTS) {
-        i = 0;
-        sampletick.detach();
+    //if noise flag set, play audio
+    if(noise){
+        Speaker = fire_truck_data[i%NUM_ELEMENTS_FIRE]/255.0;//scale to 0.0 to 1.0 for PWM
+        i++;
+    } else {
+        Speaker = 0;
     }
 }
 
+// Temporary debug variables
+int tmp = 0;
+int tmp2 = 0;
+int num_trig = 0;
+
+//Microphone class
+class microphone
+{
+public :
+    microphone(PinName pin);
+    float read();
+    operator float ();
+private :
+    AnalogIn _pin;
+};
+microphone::microphone (PinName pin):
+    _pin(pin)
+{
+}
+float microphone::read()
+{
+    return _pin.read();
+}
+inline microphone::operator float ()
+{
+    return _pin.read();
+}
+ 
+microphone mymicrophone(p16);
+ 
+
 //
-//// Thread 1
-//// print counter into first line and wait for 1 s
-//void thread1(void const *args)
-//{
-//    int i;
-//    while(true) {       // thread loop
-//        lcd_mutex.lock();
-//        LCD.locate(0,0);
-//        LCD.set_font((unsigned char*) Small_6);
-//        LCD.printf("Thread1 count: %d",i);
-//        lcd_mutex.unlock();
-//        i++;
-//        Thread::wait(1000);
-//    }
-//}
-//
-//// Thread 2
-//// print counter into third line and wait for 0,5s
-//void thread2(void const *args)
-//{
-//    int k;
-//    while(true) {       // thread loop
-//        lcd_mutex.lock();
-//        LCD.locate(0,20);
-//        LCD.set_font((unsigned char*) Arial_9);
-//        LCD.printf("Thread 2 count : %d",k);
-//        lcd_mutex.unlock();
-//        k++;
-//        Thread::wait(500); // wait 0.5s
-//    }
-//}
+// Thread 1
+// Debug thread for microphone on LCD 
+void thread1(void const *args)
+{
+    int i2;
+    while(true) {       // thread loop
+        lcd_mutex.lock();
+        
+        //uLCD.cls();
+        mic_mutex.lock();
+        tmp = int(abs((mymicrophone - (0.67/3.3)))*500.0);
+        //tmp2 = user_button;
+        mic_mutex.unlock();
+        trigger_mutex.lock();
+        uLCD.printf("%d",trigger);
+        trigger_mutex.unlock();
+        
+        lcd_mutex.unlock();
+        Thread::wait(100);
+    }
+}
 //
 //// Thread 3
-//// print a sin function in a small window
-//// the value of pot 1 changes the speed of the sine wave
-//void thread3(void const *args)
-//{
-//    int i,k,v;
-//    double s,a;
-//    k = 1;
-//    lcd_mutex.lock();
-//    LCD.rect(89,0,127,17,1);
-//    lcd_mutex.unlock();
-//    while(true) {       // thread loop
-//        v = Pot1.read_u16();  // get value of pot 1
-//        lcd_mutex.lock();
-//        for (i=90; i<127; i++) {
-//            s = 8 * sin((long double)(i+k) /5);   // pixel to print
-//            a = 8 * sin((long double)(i+k-1) /5); // old pixel to erase
-//            LCD.pixel(i,9 + (int)a ,0);           // erase pixel
-//            LCD.pixel(i,9 + (int)s ,1);           // print pixel
-//        }
-//        LCD.copy_to_lcd();  // LCD.pixel does not update the lcd
-//        lcd_mutex.unlock();
-//        k++;
-//        Thread::wait(v/100);   // value of pot1 / 100
-//    }
-//}
+//// Blink LED 
+void thread3(void const *args)
+{
+    while(1) {
+        // if blink flag is set then blink red LED with PWM fade
+        if(blink) {
+            leds_mutex.lock();
+            RGBLED_g = 0;
+            RGBLED_b = 0;
+            leds_mutex.unlock();
+            for(float j = 0.2; j<= 1.0; j+=0.1) {
+                leds_mutex.lock();
+                RGBLED_r = j;  
+                leds_mutex.unlock();
+                Thread::wait(20);
+            }   
+            Thread::wait(100);
+            for(float j = 1.0; j>= 0.2; j-=0.1) {
+                leds_mutex.lock();
+                RGBLED_r = j;  
+                leds_mutex.unlock();
+                Thread::wait(10);
+            }   
+            Thread::wait(100);   // value of pot1 / 100
+        }
+    }
+}
 //
 //// Thread 4
-//// input pot 2 and change the contrast of LCD
-//void thread4(void const *args)
-//{
-//    int k;
-//    while(true) {         // thread loop
-//        k = Pot2.read_u16();  // get the value of poti 2
-//        k = k >> 10;          // need only 6 bits for contrast
-//        lcd_mutex.lock();
-//        LCD.set_contrast(k);
-//        lcd_mutex.unlock();
-//        Thread::wait(500);    // wait 0.5s
-//    }
-//}
-//// Thread 5
-//// RGB LED
-//void thread5(void const *args)
-//{
-//    while(true) {         // thread loop
-//        RGBLED_r = 0.5 + (rand() % 11)/20.0;
-//        RGBLED_g = 0.5 + (rand() % 11)/20.0;
-//        RGBLED_b = 0.5 + (rand() % 11)/20.0;
-//        Thread::wait(1667);    // wait 1.5s
-//    }
-//}
-//// Thread 6
-//// Speaker
-//void thread6(void const *args)
-//{
-//    while(true) {
-//        //sampletick.attach(&audio_sample, 1.0 / sample_freq);
-//        /*
-//                 // thread loop
-//        Speaker.period(1.0/800.0);
-//        Speaker = 0.01;
-//        Thread::wait(1000);    // wait 1.0s
-//        Speaker.period(1.0/969.0);
-//        Speaker = 0.01;
-//        Thread::wait(1000);    // wait 1.0s
-//        */
-//    }
-//}
-//
-//// Thread 7
-//// Joystick controls onboard mbed LEDs
-//void thread7(void const *args)
-//{
-//    while(true) {         // thread loop
-//        if (joyfire) {
-//            leds = 0xf;
-//        } else {
-//            leds = joy;
-//        }
-//        Thread::wait(200);    // wait 0.25s
-//    }
-//}
-
-
+//// Microphone parser, triggers coffee pot when over certain value
+void thread4(void const *args)
+{
+    while(1) {
+//read in, subtract 0.67 DC bias, take absolute value, and scale up .1Vpp to 15 for builtin LED display
+        mic_mutex.lock();
+        tmp = int(abs((mymicrophone - (0.67/3.3)))*500.0);
+        mic_mutex.unlock();
+        if(tmp > 9) {
+            num_trig = num_trig+1;
+            //only trigger if get sample above value 3 times in a row
+            if(num_trig == 3){
+                trigger_mutex.lock();
+                trigger = 1;
+                trigger_mutex.unlock();
+                tmp = 0;
+                Thread::wait(200);
+            }
+        } else {
+            num_trig = 0;
+        }
+    }
+}
+// Thread 5
+// Bluetooth parser to trigger coffee pot
+void thread5(void const *args)
+{   
+    while(true) {         
+        //if recieve any button from bluetooth, increment tmp_blue
+        if (blue.readable()){
+            bmut.lock();
+            if (blue.getc() == '!') {
+                if (blue.getc() == 'B') {
+                    tmp_blue++;         
+                }
+            }
+            
+            bmut.unlock();
+        }
+        // if receive message from bluetooth twice in a row, trigger coffee pot
+        if(tmp_blue == 2) {
+            trigger_mutex.lock();
+            trigger = 1;         
+            trigger_mutex.unlock();
+            tmp_blue = 0;
+        } 
+    }
+}
 
 int main()
 {
-    //int j;
-    //LCD.cls();
+    // ---------Enter Initialize State---------
+    //set key to high initially to not trigger coffee pot
+    key = 1;
+    RGBLED_r  = 0.5;
+    wait(0.1);
+    //set baud rate
+    blue.baud(9600);
+    //set speaker period
     Speaker.period(1.0/250000.0);
     //Thread t1(thread1); //start thread1
-    //Thread t2(thread2); //start thread2
-    //Thread t3(thread3); //start thread3
-    //Thread t4(thread4); //start thread4
-    //Thread t5(thread5); //start thread5
-    //Thread t6(thread6); //start thread6
-    //Thread t7(thread7); //start thread7
 
-    while(true) {       // main is the next thread
-        //lcd_mutex.lock();
-        
+    Thread t3(thread3); //start thread3
+    Thread t4(thread4); //start thread4
+    Thread t5(thread5); //start thread5
+    
+    //set button mode 
+    user_button.mode(PullUp);
+    wait(0.001);
+    
+    //---------Enter Ready State---------
+    
+    //lcd_mutex.lock();
+    uLCD.cls();
+    uLCD.printf("READY");
+    //lcd_mutex.unlock();
+    
+    //attach audio interrupt
+    sampletick.attach(&audio_sample, 1.0 / sample_freq);
         
-
-        
-        sampletick.attach(&audio_sample, 1.0 / sample_freq);
-        
-        //LCD.locate(0,9);
-        //LCD.set_font((unsigned char*) Small_7);
-        //j = LCD.get_contrast();    // read the actual contrast
-        //LCD.printf("contrast : %d",j);
-        //lcd_mutex.unlock();
-//        wait(1.0 / sample_freq);   // wait 0.5s
+    while(1){
+        Thread::wait(100);
+        //set mutex lock for trigger 
+        trigger_mutex.lock();
+        //if trigger flag is set, start coffee pot
+        if(trigger) {
+            // ---------Enter Brewing State---------
+            
+            //write to LCD 
+            //lcd_mutex.lock();
+            uLCD.cls();
+            uLCD.printf("BREWING...");
+            //lcd_mutex.unlock();
+            
+            //set microphone mutex lock to prevent false trigger while running 
+            mic_mutex.lock();
+            
+            // set coffee pot trigger to low
+            key = 0;
+            //changing LED to indicate trigger
+            leds_mutex.lock();
+            RGBLED_r = 0;
+            RGBLED_b = 0;                
+            RGBLED_g  = 1;
+            leds_mutex.unlock();
+            Thread::wait(200);
+            
+            // set coffee pot trigger back to high after pulse
+            key = 1;
+            
+            // change LED to indicate running
+            leds_mutex.lock();
+            RGBLED_g = 0;
+            RGBLED_b  = 1;
+            leds_mutex.unlock();
+            wait(100);
+            
+            // ---------Enter Reset State---------
+            
+            // set noise flag high
+            noise = 1;
+            //lcd_mutex.lock();
+            uLCD.cls();
+            uLCD.printf("COFFEE READY\n\n\rPLEASE RESET\n\rMACHINE");
+            //lcd_mutex.unlock();
+            
+            // set led blink flag high
+            blink = 1;
+            
+            //wait for reset button press from user
+            while(reset) {
+                reset = user_button;
+                Thread::wait(1);
+            }
+            
+            //---------Enter Ready State---------
+            
+            // set led blink flag low
+            blink = 0;
+            //lcd_mutex.lock();
+            uLCD.cls();
+            uLCD.printf("READY");
+            //lcd_mutex.unlock();
+            
+            // set noise flag low
+            noise = 0;
+            // set reset flag high
+            reset = 1;
+            
+            // change leds to indicate ready state
+            leds_mutex.lock();
+            RGBLED_g = 0;
+            RGBLED_b = 0;
+            RGBLED_r  = 1;
+            leds_mutex.unlock();
+            
+            // set trigger flag low
+            trigger = 0;
+            mic_mutex.unlock();
+        }
+        trigger_mutex.unlock();
     }
-}
\ No newline at end of file
+}