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

Dependencies:   SDFileSystem beep mbed

Fork of ADXL345_I2C by Peter Swanson

Committer:
ivygatech
Date:
Thu May 01 14:58:12 2014 +0000
Revision:
2:13d5673286e2
Parent:
0:d0adb548714f
Source code for project Smart Alarm (Georgia Tech ECE 4180)

Who changed what in which revision?

UserRevisionLine numberNew contents of line
peterswanson87 0:d0adb548714f 1 #include "ADXL345_I2C.h"
ivygatech 2:13d5673286e2 2 //#include "SDFileSystem.h"
ivygatech 2:13d5673286e2 3 #include "beep.h"
ivygatech 2:13d5673286e2 4 #include "string.h"
ivygatech 2:13d5673286e2 5 #include "time.h"
ivygatech 2:13d5673286e2 6 #include "mbed.h"
ivygatech 2:13d5673286e2 7
ivygatech 2:13d5673286e2 8 //SDFileSystem sd(p5, p6, p7, p8, "sd"); // the pinout on the mbed Cool Components workshop board
ivygatech 2:13d5673286e2 9 ADXL345_I2C accelerometer(p28, p27);
ivygatech 2:13d5673286e2 10 Serial bluetooth(p9, p10);
ivygatech 2:13d5673286e2 11 Serial pc(USBTX, USBRX);
ivygatech 2:13d5673286e2 12
ivygatech 2:13d5673286e2 13 // pin for load sensors
ivygatech 2:13d5673286e2 14 AnalogIn load1(p19);
ivygatech 2:13d5673286e2 15 AnalogIn load2(p20);
ivygatech 2:13d5673286e2 16
ivygatech 2:13d5673286e2 17 // pin for PowerSSRtail output
ivygatech 2:13d5673286e2 18 DigitalOut SSR(p21);
ivygatech 2:13d5673286e2 19 // pin for ZeroCross tail input // An external 1K pullup required
ivygatech 2:13d5673286e2 20 InterruptIn zerocross(p22);
peterswanson87 0:d0adb548714f 21
ivygatech 2:13d5673286e2 22 // Beep with 1Khz for 0.5 seconds
ivygatech 2:13d5673286e2 23 Beep buzzer(p23);
ivygatech 2:13d5673286e2 24
ivygatech 2:13d5673286e2 25 PwmOut led_dim(LED1); // light dimmer
ivygatech 2:13d5673286e2 26 //DigitalOut led(LED2); // load detection
ivygatech 2:13d5673286e2 27 //DigitalOut led_r(LED3); // bluetooth readable
ivygatech 2:13d5673286e2 28 //DigitalOut led_w(LED4); // bluetooth writeable
ivygatech 2:13d5673286e2 29
ivygatech 2:13d5673286e2 30 //use timer interrupts to control dimming
ivygatech 2:13d5673286e2 31 Timeout SSRtriggerOn;
ivygatech 2:13d5673286e2 32
ivygatech 2:13d5673286e2 33 // dimmer value 0.0=off and 1.0=full on
ivygatech 2:13d5673286e2 34 volatile float dim;
ivygatech 2:13d5673286e2 35
ivygatech 2:13d5673286e2 36 // AC power line frequency
ivygatech 2:13d5673286e2 37 const float powerlinefrequency=60.000;
ivygatech 2:13d5673286e2 38
ivygatech 2:13d5673286e2 39 // this interrupt routine is activated after a time delay set by dim value
ivygatech 2:13d5673286e2 40 void triggerOn(){
ivygatech 2:13d5673286e2 41 SSR = 1;
ivygatech 2:13d5673286e2 42 }
peterswanson87 0:d0adb548714f 43
ivygatech 2:13d5673286e2 44 // this interrupt routine is activated by every AC line zero crossing
ivygatech 2:13d5673286e2 45 // it is needed to synchronize the SCR turnon time delay to the AC line
ivygatech 2:13d5673286e2 46 void dimmer()
ivygatech 2:13d5673286e2 47 {
ivygatech 2:13d5673286e2 48 // turn off SSR at zero crossing
ivygatech 2:13d5673286e2 49 SSR = 0;
ivygatech 2:13d5673286e2 50 // compute time delay using dim value and set timer interrupt
ivygatech 2:13d5673286e2 51 // triggers SSR after a small post zero crossing time delay
ivygatech 2:13d5673286e2 52 SSRtriggerOn.attach(&triggerOn,(1.001-dim)/(2*powerlinefrequency));
ivygatech 2:13d5673286e2 53 }
ivygatech 2:13d5673286e2 54
ivygatech 2:13d5673286e2 55 int main() {
ivygatech 2:13d5673286e2 56 char sysStart,sysAck;
ivygatech 2:13d5673286e2 57 char readBuf[] = "00000";
ivygatech 2:13d5673286e2 58 char writeBuf[] = "000.00T";
ivygatech 2:13d5673286e2 59
ivygatech 2:13d5673286e2 60 int readings[3] = {0, 0, 0};
ivygatech 2:13d5673286e2 61 int16_t offsetXsum = 0, offsetYsum = 0, offsetZsum = 0;
ivygatech 2:13d5673286e2 62 double offsetX, offsetY, offsetZ;
ivygatech 2:13d5673286e2 63 double moveCurr, moveAccu, moveMax, moveAve;
ivygatech 2:13d5673286e2 64 int dataCount = 0;
ivygatech 2:13d5673286e2 65 double wakeThresh = 15;
ivygatech 2:13d5673286e2 66 char wakeDetect = 'F'; // set to 'T' if the user is already awake
ivygatech 2:13d5673286e2 67 char loadDetect = 'F'; // set to 'T' if the user is still in bed
ivygatech 2:13d5673286e2 68
ivygatech 2:13d5673286e2 69 int trackTime = 300; // time duration of tracking sleep data. Default 6 hours (21600), should be set by Android.
ivygatech 2:13d5673286e2 70 int intvTime = 5; // time interval of sending data to Android. Default is 60, here set to 5 for demo.
ivygatech 2:13d5673286e2 71 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.
ivygatech 2:13d5673286e2 72 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.
ivygatech 2:13d5673286e2 73
ivygatech 2:13d5673286e2 74 // set up timer to track system running time
ivygatech 2:13d5673286e2 75 time_t tStart;
ivygatech 2:13d5673286e2 76 set_time(1256729737);
ivygatech 2:13d5673286e2 77
ivygatech 2:13d5673286e2 78 // ====================================== HARDWARE SETUP ============================================================
ivygatech 2:13d5673286e2 79 pc.printf("\n\n\nStarting smart alarm...\n");
ivygatech 2:13d5673286e2 80 wait(.001);
ivygatech 2:13d5673286e2 81
ivygatech 2:13d5673286e2 82 // Get accelerometer device address
ivygatech 2:13d5673286e2 83 pc.printf("ADXL345 Device ID is: 0x%02x\n", accelerometer.getDeviceID());
ivygatech 2:13d5673286e2 84 wait(.001);
ivygatech 2:13d5673286e2 85
ivygatech 2:13d5673286e2 86 // These are here to test whether any of the initialization fails. It will print the failure
ivygatech 2:13d5673286e2 87 if (accelerometer.setPowerControl(0x00)){
ivygatech 2:13d5673286e2 88 pc.printf("fail to intitialize power control\n");
ivygatech 2:13d5673286e2 89 return 0; }
ivygatech 2:13d5673286e2 90 // Full resolution, +/-16g, 4mg/LSB.
peterswanson87 0:d0adb548714f 91 wait(.001);
peterswanson87 0:d0adb548714f 92
ivygatech 2:13d5673286e2 93 if(accelerometer.setDataFormatControl(0x0B)){
ivygatech 2:13d5673286e2 94 pc.printf("fail to set data format\n");
ivygatech 2:13d5673286e2 95 return 0; }
ivygatech 2:13d5673286e2 96 wait(.001);
peterswanson87 0:d0adb548714f 97
ivygatech 2:13d5673286e2 98 // 3.2kHz data rate.
ivygatech 2:13d5673286e2 99 if(accelerometer.setDataRate(ADXL345_3200HZ)){
ivygatech 2:13d5673286e2 100 pc.printf("fail to set data rate\n");
peterswanson87 0:d0adb548714f 101 return 0; }
ivygatech 2:13d5673286e2 102 wait(.001);
peterswanson87 0:d0adb548714f 103
ivygatech 2:13d5673286e2 104 // Measurement mode.
ivygatech 2:13d5673286e2 105
ivygatech 2:13d5673286e2 106 if(accelerometer.setPowerControl(MeasurementMode)) {
ivygatech 2:13d5673286e2 107 pc.printf("fail to set the power control to measurement\n");
peterswanson87 0:d0adb548714f 108 return 0; }
ivygatech 2:13d5673286e2 109
ivygatech 2:13d5673286e2 110 // Calibrate the accelerometer
ivygatech 2:13d5673286e2 111 for (int oi = 0; oi < 10; oi++) {
ivygatech 2:13d5673286e2 112 accelerometer.getOutput(readings);
ivygatech 2:13d5673286e2 113 pc.printf("Offset: %5i, %5i, %5i\n", (int16_t)readings[0], (int16_t)readings[1], (int16_t)readings[2]);
ivygatech 2:13d5673286e2 114 offsetXsum += (int16_t)readings[0];
ivygatech 2:13d5673286e2 115 offsetYsum += (int16_t)readings[1];
ivygatech 2:13d5673286e2 116 offsetZsum += (int16_t)readings[2];
ivygatech 2:13d5673286e2 117 wait(0.001);
ivygatech 2:13d5673286e2 118 }
ivygatech 2:13d5673286e2 119 offsetX = offsetXsum/10.0;
ivygatech 2:13d5673286e2 120 offsetY = offsetYsum/10.0;
ivygatech 2:13d5673286e2 121 offsetZ = offsetZsum/10.0;
ivygatech 2:13d5673286e2 122 pc.printf("Average: %5.2f, %5.2f, %5.2f\n",offsetX,offsetY,offsetZ);
ivygatech 2:13d5673286e2 123
ivygatech 2:13d5673286e2 124 // Bluetooth setup
ivygatech 2:13d5673286e2 125 bluetooth.baud(115200);
ivygatech 2:13d5673286e2 126 wait(0.05);
ivygatech 2:13d5673286e2 127
ivygatech 2:13d5673286e2 128 // Set up interrupt routine to detect AC line zero crossings
ivygatech 2:13d5673286e2 129 dim = 1.0; led_dim = dim;
ivygatech 2:13d5673286e2 130 zerocross.mode(PullNone);
ivygatech 2:13d5673286e2 131 wait(0.2);
ivygatech 2:13d5673286e2 132 zerocross.rise(&dimmer);
ivygatech 2:13d5673286e2 133
ivygatech 2:13d5673286e2 134 // ====================================== SYSTEM START ==============================================================
ivygatech 2:13d5673286e2 135 sysAck = 'A';
ivygatech 2:13d5673286e2 136 while(1){
ivygatech 2:13d5673286e2 137 if (!bluetooth.readable()){;}
ivygatech 2:13d5673286e2 138 else{
ivygatech 2:13d5673286e2 139 sysStart = bluetooth.getc(); // read start signal
ivygatech 2:13d5673286e2 140 pc.printf("start? %c\n",sysStart);
ivygatech 2:13d5673286e2 141 if (sysStart=='S'){
ivygatech 2:13d5673286e2 142 time(&tStart); // record starting time
ivygatech 2:13d5673286e2 143 wait(0.1);
ivygatech 2:13d5673286e2 144 if (bluetooth.writeable()){//;}
ivygatech 2:13d5673286e2 145 //else{
ivygatech 2:13d5673286e2 146 bluetooth.putc(sysAck); // send acknowledge signal
ivygatech 2:13d5673286e2 147 pc.printf("ack? %c\n",sysAck);
ivygatech 2:13d5673286e2 148 wait(1);
ivygatech 2:13d5673286e2 149 for (int ri=0;ri<5;ri++){ // read trackTime value (seconds - 5 bits)
ivygatech 2:13d5673286e2 150 if (bluetooth.readable()){//;}
ivygatech 2:13d5673286e2 151 //else{
ivygatech 2:13d5673286e2 152 readBuf[ri] = bluetooth.getc();
ivygatech 2:13d5673286e2 153 pc.printf("Bits received: %c\n",readBuf[ri]);
ivygatech 2:13d5673286e2 154 wait(0.01);
ivygatech 2:13d5673286e2 155 }
ivygatech 2:13d5673286e2 156 }
ivygatech 2:13d5673286e2 157 break;
ivygatech 2:13d5673286e2 158 }
ivygatech 2:13d5673286e2 159 }
ivygatech 2:13d5673286e2 160 }
ivygatech 2:13d5673286e2 161 }
ivygatech 2:13d5673286e2 162 sscanf (readBuf,"%d",&trackTime);
ivygatech 2:13d5673286e2 163 pc.printf("Received tracking time: %5d\n\n",trackTime);
ivygatech 2:13d5673286e2 164 if (trackTime==0) trackTime=100;
ivygatech 2:13d5673286e2 165
ivygatech 2:13d5673286e2 166 // dim light
ivygatech 2:13d5673286e2 167 for(dim = 1.0; dim >= 0.0; dim -= 0.02) {
ivygatech 2:13d5673286e2 168 led_dim = dim;
ivygatech 2:13d5673286e2 169 wait(0.1);
ivygatech 2:13d5673286e2 170 }
ivygatech 2:13d5673286e2 171 dim = 0.0; led_dim = dim;
ivygatech 2:13d5673286e2 172
ivygatech 2:13d5673286e2 173 // ====================================== SLEEP TRACKING ============================================================
ivygatech 2:13d5673286e2 174 // mkdir("/sd/sleepdata", 0777);
ivygatech 2:13d5673286e2 175
ivygatech 2:13d5673286e2 176 // FILE *fp = fopen("/sd/sleepdata/20140430.csv", "w");
ivygatech 2:13d5673286e2 177 // if(fp == NULL) {
ivygatech 2:13d5673286e2 178 // error("Could not open file for write\n");
ivygatech 2:13d5673286e2 179 // }
peterswanson87 0:d0adb548714f 180
ivygatech 2:13d5673286e2 181 while (time(NULL)-tStart<=trackTime) {
ivygatech 2:13d5673286e2 182 //dim = 0.0;
ivygatech 2:13d5673286e2 183 pc.printf("seconds elapsed: %5d of %5d; ",time(NULL)-tStart,trackTime);
ivygatech 2:13d5673286e2 184 wakeDetect = 'F';
ivygatech 2:13d5673286e2 185 //led_r = bluetooth.readable();
ivygatech 2:13d5673286e2 186 //led_w = bluetooth.writeable();
ivygatech 2:13d5673286e2 187
ivygatech 2:13d5673286e2 188 accelerometer.getOutput(readings); dataCount++;
ivygatech 2:13d5673286e2 189 //pc.printf("%5i, %5i, %5i; ", (int16_t)readings[0], (int16_t)readings[1], (int16_t)readings[2]);
ivygatech 2:13d5673286e2 190 moveCurr = sqrt(pow((int16_t)readings[0]-offsetX,2)+pow((int16_t)readings[1]-offsetY,2)+pow((int16_t)readings[2]-offsetZ,2));
ivygatech 2:13d5673286e2 191 pc.printf("movement: %5.2f \n",moveCurr);
ivygatech 2:13d5673286e2 192 // fprintf(fp,"%.2f\n",moveCurr);
ivygatech 2:13d5673286e2 193
ivygatech 2:13d5673286e2 194 if (dataCount%intvTime != 0) {
ivygatech 2:13d5673286e2 195 moveAccu += moveCurr;
ivygatech 2:13d5673286e2 196 if (moveCurr > moveMax){
ivygatech 2:13d5673286e2 197 moveMax = moveCurr;
ivygatech 2:13d5673286e2 198 }
ivygatech 2:13d5673286e2 199 }
ivygatech 2:13d5673286e2 200 else {
ivygatech 2:13d5673286e2 201 moveAve = moveAccu/intvTime;
ivygatech 2:13d5673286e2 202 if ((time(NULL)-tStart+smartTime>trackTime) && (moveAve > wakeThresh)) wakeDetect = 'T';
ivygatech 2:13d5673286e2 203 pc.printf("seconds elapsed: %5d, time diff: %5d; \n",time(NULL)-tStart,time(NULL)-tStart+smartTime-trackTime);
ivygatech 2:13d5673286e2 204
ivygatech 2:13d5673286e2 205 sprintf(writeBuf, "%6.2f%c",moveMax,wakeDetect);
ivygatech 2:13d5673286e2 206 pc.printf("Max: %.2f, Ave: %5.2f, Send: %s\n\n", moveMax, moveAve, writeBuf);
ivygatech 2:13d5673286e2 207
ivygatech 2:13d5673286e2 208 for (int wi = 0; writeBuf[wi]!='\0'; wi++){
ivygatech 2:13d5673286e2 209 if (bluetooth.writeable()){//;}
ivygatech 2:13d5673286e2 210 //else {
ivygatech 2:13d5673286e2 211 bluetooth.putc(writeBuf[wi]);
ivygatech 2:13d5673286e2 212 pc.printf("Bits sent: %c\n",writeBuf[wi]);
ivygatech 2:13d5673286e2 213 wait(0.01);
ivygatech 2:13d5673286e2 214 }
ivygatech 2:13d5673286e2 215 }
ivygatech 2:13d5673286e2 216
ivygatech 2:13d5673286e2 217 dataCount = 0;
ivygatech 2:13d5673286e2 218 moveAccu = 0;
ivygatech 2:13d5673286e2 219 moveMax = 0;
ivygatech 2:13d5673286e2 220 }
ivygatech 2:13d5673286e2 221
ivygatech 2:13d5673286e2 222 wait(1);
ivygatech 2:13d5673286e2 223 }
ivygatech 2:13d5673286e2 224 // fclose(fp);
ivygatech 2:13d5673286e2 225 pc.printf("Tracking completed...\n\n\n");
ivygatech 2:13d5673286e2 226
ivygatech 2:13d5673286e2 227 // turn on the light at pre-set alarm time
ivygatech 2:13d5673286e2 228 for(dim = 0.0; dim <= 1.0; dim += 0.02) {
ivygatech 2:13d5673286e2 229 led_dim = dim;
ivygatech 2:13d5673286e2 230 wait(0.1);
ivygatech 2:13d5673286e2 231 }
ivygatech 2:13d5673286e2 232 dim = 1.0; led_dim = dim;
ivygatech 2:13d5673286e2 233
ivygatech 2:13d5673286e2 234
ivygatech 2:13d5673286e2 235 // ====================================== AUTO-SNOOZE ===============================================================
ivygatech 2:13d5673286e2 236 wait(10);
ivygatech 2:13d5673286e2 237 time(&tStart);
ivygatech 2:13d5673286e2 238 loadDetect = 'F';
ivygatech 2:13d5673286e2 239 while (time(NULL)-tStart<snoozeTime){
ivygatech 2:13d5673286e2 240 dim = 1.0;
ivygatech 2:13d5673286e2 241
ivygatech 2:13d5673286e2 242 pc.printf("%5.2f, %5.2f; ",1-load1.read(),1-load2.read());
ivygatech 2:13d5673286e2 243 if(load1.read() < 0.5 || load2.read() < 0.5) {
ivygatech 2:13d5673286e2 244 loadDetect = 'T';
ivygatech 2:13d5673286e2 245 } else {
ivygatech 2:13d5673286e2 246 loadDetect = 'F';
ivygatech 2:13d5673286e2 247 }
ivygatech 2:13d5673286e2 248 pc.printf("load detected: %c\n",loadDetect);
ivygatech 2:13d5673286e2 249
ivygatech 2:13d5673286e2 250 if (loadDetect=='T') {
ivygatech 2:13d5673286e2 251 pc.printf("Oops...\n");
ivygatech 2:13d5673286e2 252 buzzer.beep(rand()%740+260,0.5);
ivygatech 2:13d5673286e2 253 dim = 0.5; led_dim = dim; wait(0.5);
ivygatech 2:13d5673286e2 254 dim = 1.0; led_dim = dim; wait(0.5);
ivygatech 2:13d5673286e2 255 time(&tStart);
ivygatech 2:13d5673286e2 256 }
ivygatech 2:13d5673286e2 257 else {
ivygatech 2:13d5673286e2 258 pc.printf("Good job...don't fall back...%d seconds to go...\n",snoozeTime+tStart-time(NULL));
ivygatech 2:13d5673286e2 259 wait(1);
ivygatech 2:13d5673286e2 260 }
ivygatech 2:13d5673286e2 261 }
ivygatech 2:13d5673286e2 262 pc.printf("Congrats!LOL\n");
ivygatech 2:13d5673286e2 263
ivygatech 2:13d5673286e2 264 // turn off light when user gets up or after snooze duration
ivygatech 2:13d5673286e2 265 for(dim = 1.0; dim >= 0.0; dim -= 0.02) {
ivygatech 2:13d5673286e2 266 led_dim = dim;
ivygatech 2:13d5673286e2 267 wait(0.01);
ivygatech 2:13d5673286e2 268 }
ivygatech 2:13d5673286e2 269 dim = 0.0; led_dim = dim;
ivygatech 2:13d5673286e2 270 pc.printf("Snoozing completed...System pause...\n\n\n");
ivygatech 2:13d5673286e2 271
ivygatech 2:13d5673286e2 272 }