Source code for project Smart Alarm (Georgia Tech ECE 4180)

Dependencies:   SDFileSystem beep mbed

Fork of ADXL345_I2C by Peter Swanson

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers main.cpp Source File

main.cpp

00001 #include "ADXL345_I2C.h"
00002 //#include "SDFileSystem.h"
00003 #include "beep.h"
00004 #include "string.h"
00005 #include "time.h"
00006 #include "mbed.h"
00007 
00008 //SDFileSystem sd(p5, p6, p7, p8, "sd"); // the pinout on the mbed Cool Components workshop board
00009 ADXL345_I2C accelerometer(p28, p27);
00010 Serial bluetooth(p9, p10);
00011 Serial pc(USBTX, USBRX);
00012 
00013 // pin for load sensors
00014 AnalogIn load1(p19);
00015 AnalogIn load2(p20);
00016 
00017 // pin for PowerSSRtail output
00018 DigitalOut SSR(p21);
00019 // pin for ZeroCross tail input // An external 1K pullup required
00020 InterruptIn zerocross(p22);
00021 
00022 // Beep with 1Khz for 0.5 seconds
00023 Beep buzzer(p23);
00024 
00025 PwmOut led_dim(LED1); // light dimmer
00026 //DigitalOut led(LED2); // load detection
00027 //DigitalOut led_r(LED3); // bluetooth readable
00028 //DigitalOut led_w(LED4); // bluetooth writeable
00029 
00030 //use timer interrupts to control dimming
00031 Timeout SSRtriggerOn;
00032 
00033 // dimmer value 0.0=off and 1.0=full on
00034 volatile float dim;
00035 
00036 // AC power line frequency
00037 const float powerlinefrequency=60.000;
00038 
00039 // this interrupt routine is activated after a time delay set by dim value
00040 void triggerOn(){
00041     SSR = 1;
00042 }
00043 
00044 // this interrupt routine is activated by every AC line zero crossing
00045 // it is needed to synchronize the SCR turnon time delay to the AC line
00046 void dimmer()
00047 {
00048     // turn off SSR at zero crossing
00049     SSR = 0;
00050     // compute time delay using dim value and set timer interrupt
00051     // triggers SSR after a small post zero crossing time delay
00052     SSRtriggerOn.attach(&triggerOn,(1.001-dim)/(2*powerlinefrequency));
00053 }
00054 
00055 int main() {
00056     char sysStart,sysAck;
00057     char readBuf[] = "00000";
00058     char writeBuf[] = "000.00T";
00059     
00060     int readings[3] = {0, 0, 0};
00061     int16_t offsetXsum = 0, offsetYsum = 0, offsetZsum = 0;
00062     double offsetX, offsetY, offsetZ;
00063     double moveCurr, moveAccu, moveMax, moveAve;
00064     int dataCount = 0;
00065     double wakeThresh = 15;
00066     char wakeDetect = 'F'; // set to 'T' if the user is already awake
00067     char loadDetect = 'F'; // set to 'T' if the user is still in bed
00068     
00069     int trackTime = 300;  // time duration of tracking sleep data. Default 6 hours (21600), should be set by Android.
00070     int intvTime = 5; // time interval of sending data to Android. Default is 60, here set to 5 for demo.
00071     int smartTime = 100; // time ahead of preset alarm time to determine the user is already in light-sleep. Default is 15 minutes (900 seconds), here set to 100 for demo.
00072     int snoozeTime = 15; // time to turn off the system after the user get out off bed for a certain period. Default 15 minutes (900 seconds), here set to 15 for demo.
00073     
00074     // set up timer to track system running time
00075     time_t tStart;
00076     set_time(1256729737);
00077     
00078 // ====================================== HARDWARE SETUP ============================================================    
00079     pc.printf("\n\n\nStarting smart alarm...\n");
00080     wait(.001);
00081     
00082     // Get accelerometer device address
00083     pc.printf("ADXL345 Device ID is: 0x%02x\n", accelerometer.getDeviceID());
00084     wait(.001);
00085     
00086     // These are here to test whether any of the initialization fails. It will print the failure
00087     if (accelerometer.setPowerControl(0x00)){
00088          pc.printf("fail to intitialize power control\n"); 
00089          return 0;  }
00090     // Full resolution, +/-16g, 4mg/LSB.
00091     wait(.001);
00092     
00093     if(accelerometer.setDataFormatControl(0x0B)){
00094         pc.printf("fail to set data format\n");
00095         return 0;  }
00096     wait(.001);
00097      
00098     // 3.2kHz data rate.
00099     if(accelerometer.setDataRate(ADXL345_3200HZ)){
00100         pc.printf("fail to set data rate\n");
00101         return 0;    }
00102     wait(.001);
00103      
00104     // Measurement mode.
00105     
00106     if(accelerometer.setPowerControl(MeasurementMode)) {
00107         pc.printf("fail to set the power control to measurement\n"); 
00108         return 0;   } 
00109     
00110     // Calibrate the accelerometer
00111     for (int oi = 0; oi < 10; oi++) {
00112         accelerometer.getOutput(readings);
00113         pc.printf("Offset: %5i, %5i, %5i\n", (int16_t)readings[0], (int16_t)readings[1], (int16_t)readings[2]);
00114         offsetXsum += (int16_t)readings[0];
00115         offsetYsum += (int16_t)readings[1];
00116         offsetZsum += (int16_t)readings[2];
00117         wait(0.001);
00118     }
00119     offsetX = offsetXsum/10.0;
00120     offsetY = offsetYsum/10.0;
00121     offsetZ = offsetZsum/10.0;
00122     pc.printf("Average: %5.2f, %5.2f, %5.2f\n",offsetX,offsetY,offsetZ);
00123     
00124     // Bluetooth setup
00125     bluetooth.baud(115200);
00126     wait(0.05);
00127     
00128     // Set up interrupt routine to detect AC line zero crossings
00129     dim = 1.0; led_dim = dim;
00130     zerocross.mode(PullNone);
00131     wait(0.2);
00132     zerocross.rise(&dimmer);
00133        
00134 // ====================================== SYSTEM START ==============================================================
00135     sysAck = 'A';
00136     while(1){
00137         if (!bluetooth.readable()){;}
00138         else{
00139             sysStart = bluetooth.getc(); // read start signal
00140             pc.printf("start? %c\n",sysStart);
00141             if (sysStart=='S'){
00142                 time(&tStart); // record starting time
00143                 wait(0.1);
00144                 if (bluetooth.writeable()){//;}
00145                 //else{
00146                     bluetooth.putc(sysAck); // send acknowledge signal
00147                     pc.printf("ack? %c\n",sysAck);
00148                     wait(1);
00149                     for (int ri=0;ri<5;ri++){ // read trackTime value (seconds - 5 bits)
00150                         if (bluetooth.readable()){//;}
00151                         //else{
00152                             readBuf[ri] = bluetooth.getc();
00153                             pc.printf("Bits received: %c\n",readBuf[ri]);
00154                             wait(0.01);
00155                         }   
00156                     }
00157                     break;
00158                 }
00159             }
00160         }
00161     }
00162     sscanf (readBuf,"%d",&trackTime);
00163     pc.printf("Received tracking time: %5d\n\n",trackTime);
00164     if (trackTime==0) trackTime=100;
00165     
00166     // dim light
00167     for(dim = 1.0; dim >= 0.0; dim -= 0.02) {
00168         led_dim = dim;
00169         wait(0.1);
00170     }
00171     dim = 0.0; led_dim = dim;
00172 
00173 // ====================================== SLEEP TRACKING ============================================================
00174 //    mkdir("/sd/sleepdata", 0777);
00175     
00176 //    FILE *fp = fopen("/sd/sleepdata/20140430.csv", "w");
00177 //    if(fp == NULL) {
00178 //        error("Could not open file for write\n");
00179 //    }    
00180 
00181     while (time(NULL)-tStart<=trackTime) {
00182        //dim = 0.0;
00183        pc.printf("seconds elapsed: %5d of %5d; ",time(NULL)-tStart,trackTime);
00184        wakeDetect = 'F';
00185        //led_r = bluetooth.readable();
00186        //led_w = bluetooth.writeable();
00187        
00188        accelerometer.getOutput(readings); dataCount++;
00189        //pc.printf("%5i, %5i, %5i; ", (int16_t)readings[0], (int16_t)readings[1], (int16_t)readings[2]);
00190        moveCurr = sqrt(pow((int16_t)readings[0]-offsetX,2)+pow((int16_t)readings[1]-offsetY,2)+pow((int16_t)readings[2]-offsetZ,2));
00191        pc.printf("movement: %5.2f \n",moveCurr);
00192 //       fprintf(fp,"%.2f\n",moveCurr);
00193        
00194        if (dataCount%intvTime != 0) {
00195            moveAccu += moveCurr;
00196            if (moveCurr > moveMax){
00197                moveMax = moveCurr;
00198             }
00199         }
00200         else {
00201             moveAve = moveAccu/intvTime;
00202             if ((time(NULL)-tStart+smartTime>trackTime) && (moveAve > wakeThresh)) wakeDetect = 'T';
00203             pc.printf("seconds elapsed: %5d, time diff: %5d; \n",time(NULL)-tStart,time(NULL)-tStart+smartTime-trackTime);
00204             
00205             sprintf(writeBuf, "%6.2f%c",moveMax,wakeDetect);
00206             pc.printf("Max: %.2f, Ave: %5.2f, Send: %s\n\n", moveMax, moveAve, writeBuf);
00207 
00208             for (int wi = 0; writeBuf[wi]!='\0'; wi++){
00209                 if (bluetooth.writeable()){//;}
00210                 //else {
00211                     bluetooth.putc(writeBuf[wi]);
00212                     pc.printf("Bits sent: %c\n",writeBuf[wi]);
00213                     wait(0.01);
00214                 }
00215             }
00216             
00217             dataCount = 0;
00218             moveAccu = 0;
00219             moveMax = 0;
00220         }
00221        
00222        wait(1);
00223     }
00224 //    fclose(fp);
00225     pc.printf("Tracking completed...\n\n\n");
00226     
00227     // turn on the light at pre-set alarm time
00228     for(dim = 0.0; dim <= 1.0; dim += 0.02) {
00229         led_dim = dim;
00230         wait(0.1);
00231     }
00232     dim = 1.0; led_dim = dim;
00233 
00234 
00235 // ====================================== AUTO-SNOOZE ===============================================================
00236     wait(10);
00237     time(&tStart);
00238     loadDetect = 'F';
00239     while (time(NULL)-tStart<snoozeTime){
00240        dim = 1.0;
00241        
00242        pc.printf("%5.2f, %5.2f;  ",1-load1.read(),1-load2.read());
00243        if(load1.read() < 0.5 || load2.read() < 0.5) {
00244             loadDetect = 'T';
00245        } else {
00246             loadDetect = 'F';
00247        }
00248        pc.printf("load detected: %c\n",loadDetect);
00249        
00250        if (loadDetect=='T') {
00251            pc.printf("Oops...\n");
00252            buzzer.beep(rand()%740+260,0.5);
00253            dim = 0.5; led_dim = dim; wait(0.5);
00254            dim = 1.0; led_dim = dim; wait(0.5);
00255            time(&tStart);
00256         }
00257         else {
00258             pc.printf("Good job...don't fall back...%d seconds to go...\n",snoozeTime+tStart-time(NULL));
00259             wait(1);
00260         }
00261     }
00262     pc.printf("Congrats!LOL\n");
00263     
00264     // turn off light when user gets up or after snooze duration
00265     for(dim = 1.0; dim >= 0.0; dim -= 0.02) {
00266         led_dim = dim;
00267         wait(0.01);
00268     }
00269     dim = 0.0; led_dim = dim;
00270     pc.printf("Snoozing completed...System pause...\n\n\n");
00271     
00272 }