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

Dependencies:   SDFileSystem beep mbed

Fork of ADXL345_I2C by Peter Swanson

Revision:
2:13d5673286e2
Parent:
0:d0adb548714f
--- a/main.cpp	Thu May 12 01:19:36 2011 +0000
+++ b/main.cpp	Thu May 01 14:58:12 2014 +0000
@@ -1,49 +1,272 @@
 #include "ADXL345_I2C.h"
+//#include "SDFileSystem.h"
+#include "beep.h"
+#include "string.h"
+#include "time.h"
+#include "mbed.h"
+
+//SDFileSystem sd(p5, p6, p7, p8, "sd"); // the pinout on the mbed Cool Components workshop board
+ADXL345_I2C accelerometer(p28, p27);
+Serial bluetooth(p9, p10);
+Serial pc(USBTX, USBRX);
+
+// pin for load sensors
+AnalogIn load1(p19);
+AnalogIn load2(p20);
+
+// pin for PowerSSRtail output
+DigitalOut SSR(p21);
+// pin for ZeroCross tail input // An external 1K pullup required
+InterruptIn zerocross(p22);
 
- ADXL345_I2C accelerometer(p28, p27);
- Serial pc(USBTX, USBRX);
+// Beep with 1Khz for 0.5 seconds
+Beep buzzer(p23);
+
+PwmOut led_dim(LED1); // light dimmer
+//DigitalOut led(LED2); // load detection
+//DigitalOut led_r(LED3); // bluetooth readable
+//DigitalOut led_w(LED4); // bluetooth writeable
+
+//use timer interrupts to control dimming
+Timeout SSRtriggerOn;
+
+// dimmer value 0.0=off and 1.0=full on
+volatile float dim;
+
+// AC power line frequency
+const float powerlinefrequency=60.000;
+
+// this interrupt routine is activated after a time delay set by dim value
+void triggerOn(){
+    SSR = 1;
+}
 
- int main() {
-       pc.baud(115200);
-     int readings[3] = {0, 0, 0};
-     
-     pc.printf("Starting ADXL345 test...\n");
-     wait(.001);
-     pc.printf("Device ID is: 0x%02x\n", accelerometer.getDeviceID());
+// this interrupt routine is activated by every AC line zero crossing
+// it is needed to synchronize the SCR turnon time delay to the AC line
+void dimmer()
+{
+    // turn off SSR at zero crossing
+    SSR = 0;
+    // compute time delay using dim value and set timer interrupt
+    // triggers SSR after a small post zero crossing time delay
+    SSRtriggerOn.attach(&triggerOn,(1.001-dim)/(2*powerlinefrequency));
+}
+
+int main() {
+    char sysStart,sysAck;
+    char readBuf[] = "00000";
+    char writeBuf[] = "000.00T";
+    
+    int readings[3] = {0, 0, 0};
+    int16_t offsetXsum = 0, offsetYsum = 0, offsetZsum = 0;
+    double offsetX, offsetY, offsetZ;
+    double moveCurr, moveAccu, moveMax, moveAve;
+    int dataCount = 0;
+    double wakeThresh = 15;
+    char wakeDetect = 'F'; // set to 'T' if the user is already awake
+    char loadDetect = 'F'; // set to 'T' if the user is still in bed
+    
+    int trackTime = 300;  // time duration of tracking sleep data. Default 6 hours (21600), should be set by Android.
+    int intvTime = 5; // time interval of sending data to Android. Default is 60, here set to 5 for demo.
+    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.
+    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.
+    
+    // set up timer to track system running time
+    time_t tStart;
+    set_time(1256729737);
+    
+// ====================================== HARDWARE SETUP ============================================================    
+    pc.printf("\n\n\nStarting smart alarm...\n");
+    wait(.001);
+    
+    // Get accelerometer device address
+    pc.printf("ADXL345 Device ID is: 0x%02x\n", accelerometer.getDeviceID());
+    wait(.001);
+    
+    // These are here to test whether any of the initialization fails. It will print the failure
+    if (accelerometer.setPowerControl(0x00)){
+         pc.printf("fail to intitialize power control\n"); 
+         return 0;  }
+    // Full resolution, +/-16g, 4mg/LSB.
     wait(.001);
     
-     // These are here to test whether any of the initialization fails. It will print the failure
-    if (accelerometer.setPowerControl(0x00)){
-         pc.printf("didn't intitialize power control\n"); 
-         return 0;  }
-     //Full resolution, +/-16g, 4mg/LSB.
-     wait(.001);
+    if(accelerometer.setDataFormatControl(0x0B)){
+        pc.printf("fail to set data format\n");
+        return 0;  }
+    wait(.001);
      
-     if(accelerometer.setDataFormatControl(0x0B)){
-        pc.printf("didn't set data format\n");
-        return 0;  }
-     wait(.001);
-     
-     //3.2kHz data rate.
-     if(accelerometer.setDataRate(ADXL345_3200HZ)){
-        pc.printf("didn't set data rate\n");
+    // 3.2kHz data rate.
+    if(accelerometer.setDataRate(ADXL345_3200HZ)){
+        pc.printf("fail to set data rate\n");
         return 0;    }
-     wait(.001);
+    wait(.001);
      
-     //Measurement mode.
-     
-     if(accelerometer.setPowerControl(MeasurementMode)) {
-        pc.printf("didn't set the power control to measurement\n"); 
+    // Measurement mode.
+    
+    if(accelerometer.setPowerControl(MeasurementMode)) {
+        pc.printf("fail to set the power control to measurement\n"); 
         return 0;   } 
- 
-     while (1) {
-     
-         wait(0.1);
-         
-         accelerometer.getOutput(readings);
-         
+    
+    // Calibrate the accelerometer
+    for (int oi = 0; oi < 10; oi++) {
+        accelerometer.getOutput(readings);
+        pc.printf("Offset: %5i, %5i, %5i\n", (int16_t)readings[0], (int16_t)readings[1], (int16_t)readings[2]);
+        offsetXsum += (int16_t)readings[0];
+        offsetYsum += (int16_t)readings[1];
+        offsetZsum += (int16_t)readings[2];
+        wait(0.001);
+    }
+    offsetX = offsetXsum/10.0;
+    offsetY = offsetYsum/10.0;
+    offsetZ = offsetZsum/10.0;
+    pc.printf("Average: %5.2f, %5.2f, %5.2f\n",offsetX,offsetY,offsetZ);
+    
+    // Bluetooth setup
+    bluetooth.baud(115200);
+    wait(0.05);
+    
+    // Set up interrupt routine to detect AC line zero crossings
+    dim = 1.0; led_dim = dim;
+    zerocross.mode(PullNone);
+    wait(0.2);
+    zerocross.rise(&dimmer);
+       
+// ====================================== SYSTEM START ==============================================================
+    sysAck = 'A';
+    while(1){
+        if (!bluetooth.readable()){;}
+        else{
+            sysStart = bluetooth.getc(); // read start signal
+            pc.printf("start? %c\n",sysStart);
+            if (sysStart=='S'){
+                time(&tStart); // record starting time
+                wait(0.1);
+                if (bluetooth.writeable()){//;}
+                //else{
+                    bluetooth.putc(sysAck); // send acknowledge signal
+                    pc.printf("ack? %c\n",sysAck);
+                    wait(1);
+                    for (int ri=0;ri<5;ri++){ // read trackTime value (seconds - 5 bits)
+                        if (bluetooth.readable()){//;}
+                        //else{
+                            readBuf[ri] = bluetooth.getc();
+                            pc.printf("Bits received: %c\n",readBuf[ri]);
+                            wait(0.01);
+                        }   
+                    }
+                    break;
+                }
+            }
+        }
+    }
+    sscanf (readBuf,"%d",&trackTime);
+    pc.printf("Received tracking time: %5d\n\n",trackTime);
+    if (trackTime==0) trackTime=100;
+    
+    // dim light
+    for(dim = 1.0; dim >= 0.0; dim -= 0.02) {
+        led_dim = dim;
+        wait(0.1);
+    }
+    dim = 0.0; led_dim = dim;
+
+// ====================================== SLEEP TRACKING ============================================================
+//    mkdir("/sd/sleepdata", 0777);
+    
+//    FILE *fp = fopen("/sd/sleepdata/20140430.csv", "w");
+//    if(fp == NULL) {
+//        error("Could not open file for write\n");
+//    }    
 
-        pc.printf("%i, %i, %i\n", (int16_t)readings[0], (int16_t)readings[1], (int16_t)readings[2]);
-     }
- 
- }
+    while (time(NULL)-tStart<=trackTime) {
+       //dim = 0.0;
+       pc.printf("seconds elapsed: %5d of %5d; ",time(NULL)-tStart,trackTime);
+       wakeDetect = 'F';
+       //led_r = bluetooth.readable();
+       //led_w = bluetooth.writeable();
+       
+       accelerometer.getOutput(readings); dataCount++;
+       //pc.printf("%5i, %5i, %5i; ", (int16_t)readings[0], (int16_t)readings[1], (int16_t)readings[2]);
+       moveCurr = sqrt(pow((int16_t)readings[0]-offsetX,2)+pow((int16_t)readings[1]-offsetY,2)+pow((int16_t)readings[2]-offsetZ,2));
+       pc.printf("movement: %5.2f \n",moveCurr);
+//       fprintf(fp,"%.2f\n",moveCurr);
+       
+       if (dataCount%intvTime != 0) {
+           moveAccu += moveCurr;
+           if (moveCurr > moveMax){
+               moveMax = moveCurr;
+            }
+        }
+        else {
+            moveAve = moveAccu/intvTime;
+            if ((time(NULL)-tStart+smartTime>trackTime) && (moveAve > wakeThresh)) wakeDetect = 'T';
+            pc.printf("seconds elapsed: %5d, time diff: %5d; \n",time(NULL)-tStart,time(NULL)-tStart+smartTime-trackTime);
+            
+            sprintf(writeBuf, "%6.2f%c",moveMax,wakeDetect);
+            pc.printf("Max: %.2f, Ave: %5.2f, Send: %s\n\n", moveMax, moveAve, writeBuf);
+
+            for (int wi = 0; writeBuf[wi]!='\0'; wi++){
+                if (bluetooth.writeable()){//;}
+                //else {
+                    bluetooth.putc(writeBuf[wi]);
+                    pc.printf("Bits sent: %c\n",writeBuf[wi]);
+                    wait(0.01);
+                }
+            }
+            
+            dataCount = 0;
+            moveAccu = 0;
+            moveMax = 0;
+        }
+       
+       wait(1);
+    }
+//    fclose(fp);
+    pc.printf("Tracking completed...\n\n\n");
+    
+    // turn on the light at pre-set alarm time
+    for(dim = 0.0; dim <= 1.0; dim += 0.02) {
+        led_dim = dim;
+        wait(0.1);
+    }
+    dim = 1.0; led_dim = dim;
+
+
+// ====================================== AUTO-SNOOZE ===============================================================
+    wait(10);
+    time(&tStart);
+    loadDetect = 'F';
+    while (time(NULL)-tStart<snoozeTime){
+       dim = 1.0;
+       
+       pc.printf("%5.2f, %5.2f;  ",1-load1.read(),1-load2.read());
+       if(load1.read() < 0.5 || load2.read() < 0.5) {
+            loadDetect = 'T';
+       } else {
+            loadDetect = 'F';
+       }
+       pc.printf("load detected: %c\n",loadDetect);
+       
+       if (loadDetect=='T') {
+           pc.printf("Oops...\n");
+           buzzer.beep(rand()%740+260,0.5);
+           dim = 0.5; led_dim = dim; wait(0.5);
+           dim = 1.0; led_dim = dim; wait(0.5);
+           time(&tStart);
+        }
+        else {
+            pc.printf("Good job...don't fall back...%d seconds to go...\n",snoozeTime+tStart-time(NULL));
+            wait(1);
+        }
+    }
+    pc.printf("Congrats!LOL\n");
+    
+    // turn off light when user gets up or after snooze duration
+    for(dim = 1.0; dim >= 0.0; dim -= 0.02) {
+        led_dim = dim;
+        wait(0.01);
+    }
+    dim = 0.0; led_dim = dim;
+    pc.printf("Snoozing completed...System pause...\n\n\n");
+    
+}