ECE 4180 final project. Sound and Bluetooth activated coffee maker

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

main.cpp

Committer:
nhummel3
Date:
2019-12-05
Revision:
6:e4aba042979b
Parent:
5:18b2796e4847
Child:
7:2e274cc18797

File content as of revision 6:e4aba042979b:

// example to test the mbed Lab Board lcd lib with the mbed rtos
// Pot1 changes the contrast
// Pot2 changes the speed of the sin wave

#include "mbed.h"
#include "rtos.h"
#include "Small_6.h"
#include "Small_7.h"
#include "Arial_9.h"
#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

//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(p22);
PwmOut RGBLED_b(p21);
DigitalIn user_button(p12);
Serial blue(p28,p27);

// 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 ()
{
    //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
// 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
//// 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
//// 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()
{
    // ---------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 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);
        
    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();
    }
}