ECE 4180 final project. Sound and Bluetooth activated coffee maker

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

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers main.cpp Source File

main.cpp

00001 // example to test the mbed Lab Board lcd lib with the mbed rtos
00002 // Pot1 changes the contrast
00003 // Pot2 changes the speed of the sin wave
00004 
00005 #include "mbed.h"
00006 #include "rtos.h"
00007 #include "Small_6.h"
00008 #include "Small_7.h"
00009 #include "Arial_9.h"
00010 #include "stdio.h"
00011 #include "C12832_lcd.h"
00012 #include "sound.h"
00013 #include "unsigned_fire_truck.h"
00014 #include "uLCD_4DGL.h"
00015 #include <mpr121.h>
00016 
00017 #define sample_freq 11025.0
00018 //get and set the frequency from wav conversion tool GUI
00019 
00020 //set variables used to track throughout program
00021 int reset = 1; //check if coffee pot is reset and ready to brew again
00022 volatile int blink = 0; // check if blinking LED
00023 int tmp_blue = 0;  // check if bluetooth has been triggered at least 2 times
00024 int noise = 0; // check if still playing alarm
00025 int i=0; //index for audio array
00026 int d = 0; 
00027 volatile int trigger = 0; // check if coffeepot has been triggered via sound or bluetooth
00028 volatile int menu = 1; // check if coffeepot has been triggered via sound or bluetooth
00029 int coffee = 0;
00030 int tolerance = 600;
00031 int brew_count = 0;
00032 
00033 //Declarations
00034 Ticker sampletick; //audio interrupt
00035 uLCD_4DGL uLCD(p9,p10,p11);
00036 AnalogIn Therm0(p18);
00037 AnalogIn Therm1(p19);
00038 DigitalOut key(p20);
00039 
00040 Serial pc(USBTX,USBRX);
00041 PwmOut Speaker(p26);
00042 PwmOut RGBLED_r(p23);
00043 PwmOut RGBLED_g(p22);
00044 PwmOut RGBLED_b(p21);
00045 DigitalIn user_button(p12);
00046 Serial blue(p28,p27);
00047 
00048 PwmOut pump(p24);
00049 DigitalOut heater(p14); //inverted logic
00050 AnalogIn therm_out(p18);
00051 AnalogIn therm_heater(p19);
00052 
00053 // Mutex declarations
00054 Mutex lcd_mutex;
00055 Mutex leds_mutex;
00056 Mutex bmut;
00057 Mutex mic_mutex;
00058 Mutex trigger_mutex;
00059 
00060 int out_temp;
00061 int heater_temp;
00062 int out_therm;
00063 int heater_therm;
00064 int target_temp = 190;
00065 
00066 volatile float r = 0.0;
00067 volatile float g = 0.0;
00068 volatile float b = 0.0;
00069 
00070 float a_coeff = 93.6469;
00071 float b_coeff = 4681.5;
00072 
00073 int therm_to_temp(int therm) {
00074     return int(a_coeff*log(therm/b_coeff));
00075 }
00076 
00077 int temp_to_therm(int temp) {
00078     return int(b_coeff*exp((temp)/a_coeff));
00079 }
00080 
00081 //Audio ISR 
00082 void audio_sample ()
00083 {
00084     //if noise flag set, play audio
00085     if(noise){
00086         Speaker = fire_truck_data[i%NUM_ELEMENTS_FIRE]/255.0;//scale to 0.0 to 1.0 for PWM
00087         i++;
00088     } else {
00089         Speaker = 0;
00090     }
00091 }
00092 
00093 // Temporary debug variables
00094 int tmp = 0;
00095 int tmp_button = 0;
00096 int tmp2 = 0;
00097 int tmp0 = 0;
00098 int tmp1 = 0;
00099 int tmpM = 0;
00100 
00101 int num_trig = 0;
00102 
00103 //Microphone class
00104 class microphone
00105 {
00106 public :
00107     microphone(PinName pin);
00108     float read();
00109     operator float ();
00110 private :
00111     AnalogIn _pin;
00112 };
00113 microphone::microphone (PinName pin):
00114     _pin(pin)
00115 {
00116 }
00117 float microphone::read()
00118 {
00119     return _pin.read();
00120 }
00121 inline microphone::operator float ()
00122 {
00123     return _pin.read();
00124 }
00125  
00126 microphone mymicrophone(p16);
00127  
00128 
00129 //
00130 // Thread 1
00131 // Debug thread for microphone on LCD 
00132 void thread1(void const *args)
00133 {
00134     lcd_mutex.lock();
00135     uLCD.filled_rectangle(0, 32, 128, 64, 0x00FF00);
00136     uLCD.locate(0,4);
00137     uLCD.color(WHITE);
00138     uLCD.textbackground_color(BLUE);
00139     uLCD.set_font(FONT_7X8);
00140     uLCD.text_mode(OPAQUE);
00141     uLCD.printf("Sensor Readings:\n\rMic:\n\rT0: \n\rT1: ");
00142     lcd_mutex.unlock();
00143     while(true) {       // thread loop
00144         //uLCD.cls();
00145         mic_mutex.lock();
00146         tmpM = int(abs((mymicrophone - (0.67/3.3)))*500.0);
00147         tmp0 = therm_to_temp(Therm0.read_u16());
00148         tmp1 = therm_to_temp(Therm1.read_u16());
00149         //tmp2 = user_button;
00150         mic_mutex.unlock();
00151         lcd_mutex.lock();
00152         
00153         uLCD.filled_rectangle(32, 40, 72, 63, 0x00FF00);
00154         uLCD.locate(4,5);
00155         uLCD.printf("%d",tmpM);
00156         uLCD.locate(4,6);
00157         uLCD.printf("%d", tmp0);
00158         uLCD.locate(4,7);
00159         uLCD.printf("%d", tmp1);
00160         
00161         lcd_mutex.unlock();
00162         Thread::wait(100);
00163     }
00164 }
00165 
00166 //
00167 // Thread 2
00168 // Debug thread for microphone on LCD 
00169 void thread2(void const *args)
00170 {
00171     lcd_mutex.lock();
00172     uLCD.filled_rectangle(0, 0, 128, 31, 0x00FF00);
00173     uLCD.locate(0,0);
00174     uLCD.color(WHITE);
00175     uLCD.textbackground_color(BLUE);
00176     uLCD.set_font(FONT_7X8);
00177     uLCD.text_mode(OPAQUE);
00178     uLCD.printf("Select Mode:");
00179     uLCD.locate(0,1);
00180     uLCD.printf(">COFFEE\n\r TEA");
00181     lcd_mutex.unlock();
00182     while(true) {       // thread loop
00183         if(menu) {
00184             if(user_button == 0) {
00185                 coffee = !coffee;
00186                 if(coffee) {
00187                     lcd_mutex.lock();
00188                     uLCD.filled_rectangle(0, 8, 7, 31, 0x00FF00);
00189                     uLCD.locate(0,1);
00190                     uLCD.color(WHITE);
00191                     uLCD.textbackground_color(BLUE);
00192                     uLCD.set_font(FONT_7X8);
00193                     uLCD.text_mode(OPAQUE);
00194                     uLCD.printf(">\n\r ");
00195                     lcd_mutex.unlock();
00196                     Thread::wait(500);
00197                 } else {
00198                     lcd_mutex.lock();
00199                     uLCD.filled_rectangle(0, 8, 7, 31, 0x00FF00);
00200                     uLCD.locate(0,1);
00201                     uLCD.color(WHITE);
00202                     uLCD.textbackground_color(BLUE);
00203                     uLCD.set_font(FONT_7X8);
00204                     uLCD.text_mode(OPAQUE);
00205                     uLCD.printf(" \n\r>");
00206                     lcd_mutex.unlock();
00207                     Thread::wait(500);
00208                 }
00209             }
00210         }
00211     }
00212 }
00213 
00214 
00215 // Thread 3
00216 // Blink LED 
00217 void thread3(void const *args)
00218 {
00219     while(1) {
00220         // if blink flag is set then blink red LED with PWM fade
00221         if(blink) {
00222             leds_mutex.lock();
00223             RGBLED_g = 0;
00224             RGBLED_b = 0;
00225             leds_mutex.unlock();
00226             for(float j = 0.2; j<= 1.0; j+=0.1) {
00227                 leds_mutex.lock();
00228                 RGBLED_r = j;  
00229                 leds_mutex.unlock();
00230                 Thread::wait(20);
00231             }   
00232             Thread::wait(100);
00233             for(float j = 1.0; j>= 0.2; j-=0.1) {
00234                 leds_mutex.lock();
00235                 RGBLED_r = j;  
00236                 leds_mutex.unlock();
00237                 Thread::wait(10);
00238             }   
00239             Thread::wait(100);   // value of pot1 / 100
00240         }
00241     }
00242 }
00243 //
00244 //// Thread 4
00245 //// Microphone parser, triggers coffee pot when over certain value
00246 void thread4(void const *args)
00247 {
00248     while(1) {
00249 //read in, subtract 0.67 DC bias, take absolute value, and scale up .1Vpp to 15 for builtin LED display
00250         mic_mutex.lock();
00251         tmp = int(abs((mymicrophone - (0.67/3.3)))*500.0);
00252         mic_mutex.unlock();
00253         if(tmp > 15) {
00254             num_trig = num_trig+1;
00255             //only trigger if get sample above value 3 times in a row
00256             if(num_trig == 2) {
00257                 trigger_mutex.lock();
00258                 trigger = 1;
00259                 trigger_mutex.unlock();
00260                 tmp = 0;
00261                 Thread::wait(200);
00262             }
00263         } else {
00264             num_trig = 0;
00265         }
00266     }
00267 }
00268 // Thread 5
00269 // Bluetooth parser to trigger coffee pot
00270 void thread5(void const *args)
00271 {   
00272     while(true) {         
00273         //if recieve any button from bluetooth, increment tmp_blue
00274         if (blue.readable()){
00275             bmut.lock();
00276             if (blue.getc() == '!') {
00277                 if (blue.getc() == 'B') {
00278                     tmp_blue++;         
00279                 }
00280             }
00281             
00282             bmut.unlock();
00283         }
00284         // if receive message from bluetooth twice in a row, trigger coffee pot
00285         if(tmp_blue == 2) {
00286             trigger_mutex.lock();
00287             trigger = 1;         
00288             trigger_mutex.unlock();
00289             tmp_blue = 0;
00290         } 
00291     }
00292 }
00293 
00294 void brew() {
00295     if(coffee) {
00296         target_temp = 190;
00297     } else {
00298         target_temp = 180;
00299     }
00300     brew_count = 0;
00301     while(1) {
00302         out_therm = therm_out.read_u16();
00303         heater_therm = therm_heater.read_u16();
00304         //pc.printf("Iteration:%d; Output Temp:%d, Heater Temp:%d\n\r", i, therm_to_temp(out_therm), therm_to_temp(heater_therm));
00305         if(brew_count > 20 && out_therm > 40600) {
00306             //Done
00307             heater = 1;
00308             pump = 1;
00309             wait(3);
00310             pump = 0;
00311             return;   
00312         } else {
00313             if(out_therm - temp_to_therm(target_temp) > tolerance) {
00314                 //cool down
00315                 pump = 0.8;
00316                 heater = 1; //off bc inverted
00317             } else if(out_therm - temp_to_therm(target_temp) < tolerance) {
00318                 //heat up
00319                 pump = 0.25;
00320                 heater = 0; //on
00321             } else {
00322                 pump = 0.4;
00323                 heater = 0; //on
00324             }
00325             wait(0.5);
00326         }
00327     brew_count++;
00328     }
00329 }
00330 
00331 int main()
00332 {
00333     // ---------Enter Initialize State---------
00334     //set key to high initially to not trigger coffee pot
00335     key = 1;
00336     pump = 0;
00337     heater = 0;
00338     RGBLED_r  = 0.5;
00339     wait(0.1);
00340     //set baud rate
00341     blue.baud(9600);
00342     //set speaker period
00343     Speaker.period(1.0/250000.0);
00344     Thread t1(thread1); //start thread1
00345     Thread t2(thread2); //start thread3
00346     Thread t3(thread3); //start thread3
00347     Thread t4(thread4); //start thread4
00348     Thread t5(thread5); //start thread5
00349     
00350     //set button mode 
00351     user_button.mode(PullUp);
00352     wait(0.001);
00353     
00354     //---------Enter Ready State---------
00355     lcd_mutex.lock();
00356     uLCD.cls();
00357     uLCD.filled_rectangle(0, 79, 128, 112, 0x00FF00);
00358     uLCD.locate(0,10);
00359     uLCD.color(WHITE);
00360     uLCD.textbackground_color(BLUE);
00361     uLCD.set_font(FONT_7X8);
00362     uLCD.text_mode(OPAQUE);
00363     uLCD.printf("State:");
00364     uLCD.locate(0,11);
00365     uLCD.printf("READY");
00366     lcd_mutex.unlock();
00367     
00368     //attach audio interrupt
00369     sampletick.attach(&audio_sample, 1.0 / sample_freq);
00370         
00371     while(1){
00372         Thread::wait(50);
00373         //set mutex lock for trigger 
00374         //pc.printf("%d\n\n\r",Therm0.read_u16());
00375         //if trigger flag is set, start coffee pot
00376         if(trigger) {
00377             // ---------Enter Brewing State---------
00378             menu = 0;
00379             trigger_mutex.lock();
00380             //write to LCD 
00381             lcd_mutex.lock();
00382             uLCD.filled_rectangle(0, 88, 100, 111, 0x00FF00);
00383             uLCD.locate(0,11);
00384             uLCD.printf("BREWING...");
00385             lcd_mutex.unlock();
00386             
00387             //set microphone mutex lock to prevent false trigger while running 
00388             mic_mutex.lock();
00389             
00390             // set coffee pot trigger to low
00391             //key = 0;
00392             //changing LED to indicate trigger
00393             leds_mutex.lock();
00394             RGBLED_r = 0;
00395             RGBLED_b = 0;                
00396             RGBLED_g  = 1;
00397             leds_mutex.unlock();
00398             Thread::wait(200);
00399             
00400             // set coffee pot trigger back to high after pulse
00401             //key = 1;
00402             
00403             // change LED to indicate running
00404             leds_mutex.lock();
00405             RGBLED_g = 0;
00406             RGBLED_b  = 1;
00407             leds_mutex.unlock();
00408             
00409             // Brew Drink
00410             //wait(3);
00411             brew();
00412             
00413             // ---------Enter Reset State---------
00414             
00415             // set noise flag high
00416             noise = 1;
00417             lcd_mutex.lock();
00418             uLCD.filled_rectangle(0, 88, 100, 111, 0x00FF00);
00419             uLCD.locate(0,11);
00420             uLCD.printf("COFFEE READY\n\rPLEASE PRESS\n\rRESET");
00421             lcd_mutex.unlock();
00422             
00423             // set led blink flag high
00424             blink = 1;
00425             
00426             //wait for reset button press from user
00427             while(reset) {
00428                 reset = user_button;
00429                 Thread::wait(1);
00430             }
00431             //---------Enter User Restock---------
00432             blink = 0;
00433             // set noise flag low
00434             noise = 0; 
00435             lcd_mutex.lock();
00436             uLCD.filled_rectangle(0, 88, 100, 111, 0x00FF00);
00437             uLCD.locate(0,11);
00438             uLCD.printf("Please Restock\n\rThe Machine");
00439             lcd_mutex.unlock();
00440             
00441             wait(0.5);
00442             reset = user_button;
00443             while(reset) {
00444                 reset = user_button;
00445                 Thread::wait(1);
00446             }
00447             
00448             //---------Enter Ready State---------
00449             
00450             // set led blink flag low
00451             blink = 0;
00452             lcd_mutex.lock();
00453             uLCD.filled_rectangle(0, 88, 100, 111, 0x00FF00);
00454             uLCD.locate(0,11);
00455             uLCD.printf("READY");
00456             lcd_mutex.unlock();
00457             
00458             // set noise flag low
00459             noise = 0;
00460             // set reset flag high
00461             reset = 1;
00462             
00463             // change leds to indicate ready state
00464             leds_mutex.lock();
00465             RGBLED_g = 0;
00466             RGBLED_b = 0;
00467             RGBLED_r  = 1;
00468             leds_mutex.unlock();
00469             
00470             // set trigger flag low
00471             trigger = 0;
00472             wait(0.4);
00473             mic_mutex.unlock();
00474             trigger_mutex.unlock();
00475             menu = 1;
00476         }
00477     }
00478 }