Source code for project Smart Alarm (Georgia Tech ECE 4180)
Dependencies: SDFileSystem beep mbed
Fork of ADXL345_I2C by
main.cpp
- Committer:
- ivygatech
- Date:
- 2014-05-01
- Revision:
- 2:13d5673286e2
- Parent:
- 0:d0adb548714f
File content as of revision 2:13d5673286e2:
#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); // 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; } // 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); if(accelerometer.setDataFormatControl(0x0B)){ pc.printf("fail to set data format\n"); return 0; } wait(.001); // 3.2kHz data rate. if(accelerometer.setDataRate(ADXL345_3200HZ)){ pc.printf("fail to set data rate\n"); return 0; } wait(.001); // Measurement mode. if(accelerometer.setPowerControl(MeasurementMode)) { pc.printf("fail to set the power control to measurement\n"); return 0; } // 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"); // } 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"); }