GR Peach based smart health monitor with IoT for Elder people mbed project Released Under Creative Commons Attribution-ShareAlike 3.0 Unported Licence

Dependencies:   ADT7320_SPI mbed

Committer:
rcele_85
Date:
Fri Jan 13 18:39:18 2017 +0000
Revision:
0:ea069e8429ef
GR Peach Smart Health Monitor with IoT for elder people mbed project;

Who changed what in which revision?

UserRevisionLine numberNew contents of line
rcele_85 0:ea069e8429ef 1 #include "mbed.h"
rcele_85 0:ea069e8429ef 2 #include "ADT7320_SPI.h"
rcele_85 0:ea069e8429ef 3 #include "math.h"
rcele_85 0:ea069e8429ef 4 #include "ADXL345_I2C.h"
rcele_85 0:ea069e8429ef 5
rcele_85 0:ea069e8429ef 6 #define ESP_RXBUF_LEN 20
rcele_85 0:ea069e8429ef 7
rcele_85 0:ea069e8429ef 8
rcele_85 0:ea069e8429ef 9 // GRPEACH SMART HEALTH MONITOR WITH IOT FOR ELDER PEOPLE
rcele_85 0:ea069e8429ef 10 // Mbed Code for Renesas GR-PEACH REV-0
rcele_85 0:ea069e8429ef 11 // Released Under Creative Commons Attribution-ShareAlike 3.0 Unported Licence
rcele_85 0:ea069e8429ef 12 Serial pc(USBTX, USBRX); // tx, rx for USB Debug on PC
rcele_85 0:ea069e8429ef 13 Serial esp(D9, D8); // tx, rx for ESP8266 Interfacing on UART
rcele_85 0:ea069e8429ef 14
rcele_85 0:ea069e8429ef 15 ADT7320_SPI adt(D11, D12, D13, D10); // mosi, miso, sclk, cs for ADT7320 Temperature Sensor
rcele_85 0:ea069e8429ef 16 Ticker acctick; // ticker for sample of adxl345 at every 10ms regardless what the loop doing
rcele_85 0:ea069e8429ef 17
rcele_85 0:ea069e8429ef 18 ADXL345_I2C accelerometer(I2C_SDA,I2C_SCL); // sda and scl for ADXL345 Temperature Sensor
rcele_85 0:ea069e8429ef 19 Timer timer; // timer for measure time interval between two heart beat Interrupts
rcele_85 0:ea069e8429ef 20
rcele_85 0:ea069e8429ef 21 InterruptIn hr_int(P1_10);
rcele_85 0:ea069e8429ef 22 DigitalOut buz(D6);
rcele_85 0:ea069e8429ef 23 DigitalIn loff(D7);
rcele_85 0:ea069e8429ef 24 DigitalIn sosconf(P1_9);
rcele_85 0:ea069e8429ef 25 AnalogIn ecg(P1_8);
rcele_85 0:ea069e8429ef 26
rcele_85 0:ea069e8429ef 27 volatile char esp_buf[ESP_RXBUF_LEN]; // Circular Buffer for ESP8266 Serial Receive As MODSERIAL not supported in GRPeach
rcele_85 0:ea069e8429ef 28 volatile uint32_t esp_pos = 0, esp_por = 0, esp_ok = 0, esp_head = 0; // Variable used for hold head and tail of Circular Buffer
rcele_85 0:ea069e8429ef 29
rcele_85 0:ea069e8429ef 30 volatile float ax,ay,az,a;
rcele_85 0:ea069e8429ef 31 volatile float aavg = 50.0f;
rcele_85 0:ea069e8429ef 32
rcele_85 0:ea069e8429ef 33 uint32_t pre_millis=0;
rcele_85 0:ea069e8429ef 34
rcele_85 0:ea069e8429ef 35 uint32_t hr = 100,hrmax = 170,hrmin = 60,bt = 35,btmax = 40,btmin = 30,ecgreq = 0,flagack = 0, hf = 0,bf = 0,ff = 0,sf = 0;
rcele_85 0:ea069e8429ef 36
rcele_85 0:ea069e8429ef 37 // >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ESP8266 UART Receive CallBack(ISR) <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
rcele_85 0:ea069e8429ef 38 void esp_callback() {
rcele_85 0:ea069e8429ef 39 esp_buf[esp_pos] = esp.getc();
rcele_85 0:ea069e8429ef 40 if(esp_buf[esp_pos]== '#')
rcele_85 0:ea069e8429ef 41 {
rcele_85 0:ea069e8429ef 42 esp_ok = 1;
rcele_85 0:ea069e8429ef 43 }
rcele_85 0:ea069e8429ef 44 esp_pos = (esp_pos+1)% ESP_RXBUF_LEN;
rcele_85 0:ea069e8429ef 45 }
rcele_85 0:ea069e8429ef 46
rcele_85 0:ea069e8429ef 47 //>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Beep on buzzer <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
rcele_85 0:ea069e8429ef 48 void beep(unsigned int _beeps, float _on, float _off)
rcele_85 0:ea069e8429ef 49 {
rcele_85 0:ea069e8429ef 50 unsigned int _i;
rcele_85 0:ea069e8429ef 51 for(_i=0 ; _i<= _beeps; _i++)
rcele_85 0:ea069e8429ef 52 {
rcele_85 0:ea069e8429ef 53 buz = 1;
rcele_85 0:ea069e8429ef 54 wait(_on);
rcele_85 0:ea069e8429ef 55 buz = 0;
rcele_85 0:ea069e8429ef 56 wait(_off);
rcele_85 0:ea069e8429ef 57
rcele_85 0:ea069e8429ef 58 }
rcele_85 0:ea069e8429ef 59
rcele_85 0:ea069e8429ef 60 }
rcele_85 0:ea069e8429ef 61
rcele_85 0:ea069e8429ef 62 // >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ADXL345 Ticker CallBack(ISR) to detect Impact <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
rcele_85 0:ea069e8429ef 63 void acctick_isr() {
rcele_85 0:ea069e8429ef 64 int accraw[3] = {0, 0, 0};
rcele_85 0:ea069e8429ef 65 accelerometer.getOutput(accraw);
rcele_85 0:ea069e8429ef 66 ax = (float)((int16_t)accraw[0])/5.2f ;
rcele_85 0:ea069e8429ef 67 ay = (float)((int16_t)accraw[1])/5.2f ;
rcele_85 0:ea069e8429ef 68 az = (float)((int16_t)accraw[2])/5.2f ;
rcele_85 0:ea069e8429ef 69 a = sqrt(pow(ax,2.0f) + pow(ay,2.0f) + pow(az,2.0f));
rcele_85 0:ea069e8429ef 70 aavg = aavg*0.85f + a*0.15f;
rcele_85 0:ea069e8429ef 71 if(aavg < 30.0f)
rcele_85 0:ea069e8429ef 72 {
rcele_85 0:ea069e8429ef 73 beep(2, 0.3f, 0.3f);
rcele_85 0:ea069e8429ef 74 ff = 1;
rcele_85 0:ea069e8429ef 75 }
rcele_85 0:ea069e8429ef 76 //printf("%3.1f%%\t%3.1f%%\r\n",aavg,a);
rcele_85 0:ea069e8429ef 77
rcele_85 0:ea069e8429ef 78 //printf("%d\t%d\t%d\r\n",accraw[0],accraw[1],accraw[2]);
rcele_85 0:ea069e8429ef 79 }
rcele_85 0:ea069e8429ef 80
rcele_85 0:ea069e8429ef 81 // >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ADXL435 Accelerometer Initlization <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
rcele_85 0:ea069e8429ef 82 void adxl345_init(void)
rcele_85 0:ea069e8429ef 83 {
rcele_85 0:ea069e8429ef 84 wait(.001);
rcele_85 0:ea069e8429ef 85 accelerometer.getDeviceID();
rcele_85 0:ea069e8429ef 86 wait(.001);
rcele_85 0:ea069e8429ef 87 // These are here to test whether any of the initialization fails.
rcele_85 0:ea069e8429ef 88 accelerometer.setPowerControl(0x00);
rcele_85 0:ea069e8429ef 89 //Full resolution, +/-16g, 4mg/LSB.
rcele_85 0:ea069e8429ef 90 wait(.001);
rcele_85 0:ea069e8429ef 91 accelerometer.setDataFormatControl(0x0B);
rcele_85 0:ea069e8429ef 92 wait(.001);
rcele_85 0:ea069e8429ef 93 //3.2kHz data rate.
rcele_85 0:ea069e8429ef 94 accelerometer.setDataRate(ADXL345_3200HZ);
rcele_85 0:ea069e8429ef 95 wait(.001);
rcele_85 0:ea069e8429ef 96 //Measurement mode.
rcele_85 0:ea069e8429ef 97 accelerometer.setPowerControl(MeasurementMode);
rcele_85 0:ea069e8429ef 98 }
rcele_85 0:ea069e8429ef 99
rcele_85 0:ea069e8429ef 100 // >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ESP8266 UART returns how many chars available to read <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
rcele_85 0:ea069e8429ef 101 int esp_available(void)
rcele_85 0:ea069e8429ef 102 {
rcele_85 0:ea069e8429ef 103 return ((ESP_RXBUF_LEN + esp_pos - esp_por) % ESP_RXBUF_LEN);
rcele_85 0:ea069e8429ef 104 }
rcele_85 0:ea069e8429ef 105
rcele_85 0:ea069e8429ef 106 // >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ESP8266 UART returns read one char <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
rcele_85 0:ea069e8429ef 107 char esp_read(void)
rcele_85 0:ea069e8429ef 108 {
rcele_85 0:ea069e8429ef 109 char c = esp_buf[esp_por];
rcele_85 0:ea069e8429ef 110 esp_por = (esp_por + 1)% ESP_RXBUF_LEN;
rcele_85 0:ea069e8429ef 111 return(c);
rcele_85 0:ea069e8429ef 112 }
rcele_85 0:ea069e8429ef 113
rcele_85 0:ea069e8429ef 114 // >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ESP8266 UART Flush receive Buffer <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
rcele_85 0:ea069e8429ef 115 void esp_flush(void)
rcele_85 0:ea069e8429ef 116 {
rcele_85 0:ea069e8429ef 117 esp_pos = 0;
rcele_85 0:ea069e8429ef 118 esp_por = 0;
rcele_85 0:ea069e8429ef 119 }
rcele_85 0:ea069e8429ef 120
rcele_85 0:ea069e8429ef 121 // >>>>>>>>>>>>>>>>>>>>> ESP8266 UART returns comma seperated data points encapsulated between * and # <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
rcele_85 0:ea069e8429ef 122 int esp_read_cmd()
rcele_85 0:ea069e8429ef 123 {
rcele_85 0:ea069e8429ef 124 if (esp_ok == 1 )
rcele_85 0:ea069e8429ef 125 {
rcele_85 0:ea069e8429ef 126 char tmp[60];
rcele_85 0:ea069e8429ef 127 char* temp;
rcele_85 0:ea069e8429ef 128 esp_ok = false;
rcele_85 0:ea069e8429ef 129 int _cnt = 0;
rcele_85 0:ea069e8429ef 130 while(esp_read() != '*' );
rcele_85 0:ea069e8429ef 131 tmp[_cnt] = esp_read();
rcele_85 0:ea069e8429ef 132 while(tmp[_cnt] != '#')
rcele_85 0:ea069e8429ef 133 {
rcele_85 0:ea069e8429ef 134 _cnt++;
rcele_85 0:ea069e8429ef 135 tmp[_cnt]= esp_read();
rcele_85 0:ea069e8429ef 136 }
rcele_85 0:ea069e8429ef 137 tmp[_cnt] = '\0';
rcele_85 0:ea069e8429ef 138 esp.printf("%s\r\n",tmp);
rcele_85 0:ea069e8429ef 139 temp = strtok(tmp, ",");
rcele_85 0:ea069e8429ef 140 hrmax = atoi(temp);
rcele_85 0:ea069e8429ef 141 temp = strtok(NULL, ",");
rcele_85 0:ea069e8429ef 142 hrmin = atoi(temp);
rcele_85 0:ea069e8429ef 143 temp = strtok(NULL, ",");
rcele_85 0:ea069e8429ef 144 btmax = atoi(temp);
rcele_85 0:ea069e8429ef 145 temp = strtok(NULL, ",");
rcele_85 0:ea069e8429ef 146 btmin = atoi(temp);
rcele_85 0:ea069e8429ef 147 temp = strtok(NULL, ",");
rcele_85 0:ea069e8429ef 148 ecgreq = atoi(temp);
rcele_85 0:ea069e8429ef 149 temp = strtok(NULL, ",");
rcele_85 0:ea069e8429ef 150 flagack = atoi(temp);
rcele_85 0:ea069e8429ef 151 pc.printf("%d %d %d %d %d %d\r\n",hrmax,hrmin,btmax,btmin,ecgreq,flagack);
rcele_85 0:ea069e8429ef 152 return 1;
rcele_85 0:ea069e8429ef 153 }
rcele_85 0:ea069e8429ef 154 else return 0;
rcele_85 0:ea069e8429ef 155 }
rcele_85 0:ea069e8429ef 156
rcele_85 0:ea069e8429ef 157 //>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ECG/HR ISR <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
rcele_85 0:ea069e8429ef 158 void hr_isr()
rcele_85 0:ea069e8429ef 159 {
rcele_85 0:ea069e8429ef 160 uint32_t _hr;
rcele_85 0:ea069e8429ef 161 _hr = timer.read_ms() - pre_millis;
rcele_85 0:ea069e8429ef 162 pre_millis = timer.read_ms();
rcele_85 0:ea069e8429ef 163 //pc.printf("premillis = %d ",pre_millis);
rcele_85 0:ea069e8429ef 164 _hr = 60000/_hr;
rcele_85 0:ea069e8429ef 165 if(_hr > 31 && _hr < 200)
rcele_85 0:ea069e8429ef 166 {
rcele_85 0:ea069e8429ef 167 hr = ((hr*14) + _hr)/15;
rcele_85 0:ea069e8429ef 168 }
rcele_85 0:ea069e8429ef 169 if(loff == 1)hr=31;
rcele_85 0:ea069e8429ef 170 if(hr <= hrmin)hf = 1;
rcele_85 0:ea069e8429ef 171 else if(hr >= hrmax)hf = 2;
rcele_85 0:ea069e8429ef 172 else hf = 0;
rcele_85 0:ea069e8429ef 173 //pc.printf("Heart Rate = %d \r\n",hr);
rcele_85 0:ea069e8429ef 174 }
rcele_85 0:ea069e8429ef 175
rcele_85 0:ea069e8429ef 176 //>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ECG capture Graph and send to ESP8266 <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
rcele_85 0:ea069e8429ef 177 void esp_send_ecg(void)
rcele_85 0:ea069e8429ef 178 {
rcele_85 0:ea069e8429ef 179 uint32_t _cnt = 0;
rcele_85 0:ea069e8429ef 180 beep(4,0.2f,0.5f);
rcele_85 0:ea069e8429ef 181 wait(2.0f);
rcele_85 0:ea069e8429ef 182 beep(1,0.2f,0.1f);
rcele_85 0:ea069e8429ef 183 for(_cnt=0; _cnt<410; _cnt++)
rcele_85 0:ea069e8429ef 184 {
rcele_85 0:ea069e8429ef 185 float raw = ecg.read();
rcele_85 0:ea069e8429ef 186 uint32_t ecg_point = (uint32_t)(((raw*100.0f)-13.15f)*1.66f);
rcele_85 0:ea069e8429ef 187 if(ecg_point > 99)ecg_point=99;
rcele_85 0:ea069e8429ef 188 esp.printf("%d,",ecg_point);
rcele_85 0:ea069e8429ef 189 pc.printf("%d,",ecg_point);
rcele_85 0:ea069e8429ef 190 wait(0.01f);
rcele_85 0:ea069e8429ef 191 }
rcele_85 0:ea069e8429ef 192 esp.printf("10#");
rcele_85 0:ea069e8429ef 193 pc.printf("10#\r\n");
rcele_85 0:ea069e8429ef 194 pc.printf("ecg graph packet sent..\r\n");
rcele_85 0:ea069e8429ef 195 beep(1,0.9f,0.1f);
rcele_85 0:ea069e8429ef 196 }
rcele_85 0:ea069e8429ef 197
rcele_85 0:ea069e8429ef 198 //>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ECG capture Graph and send to ESP8266 <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
rcele_85 0:ea069e8429ef 199 void esp_send_data(void)
rcele_85 0:ea069e8429ef 200 {
rcele_85 0:ea069e8429ef 201 esp.printf("*%d,%d,%d,%d,%d,%d,%d,%d,%d,%d#",hr,hrmax,hrmin,bt,btmax,btmin,hf,bf,ff,sf);
rcele_85 0:ea069e8429ef 202 pc.printf("*%d,%d,%d,%d,%d,%d,%d,%d,%d,%d#\r\rn",hr,hrmax,hrmin,bt,btmax,btmin,hf,bf,ff,sf);
rcele_85 0:ea069e8429ef 203 pc.printf("data packet sent..\r\n");
rcele_85 0:ea069e8429ef 204 }
rcele_85 0:ea069e8429ef 205
rcele_85 0:ea069e8429ef 206 //>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Read ADT7320 Temperature sensor & bf flag <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
rcele_85 0:ea069e8429ef 207 void read_adt_temp(void)
rcele_85 0:ea069e8429ef 208 {
rcele_85 0:ea069e8429ef 209 bt = (uint32_t)(adt.readTemp());
rcele_85 0:ea069e8429ef 210 if(bt <= btmin)bf = 1;
rcele_85 0:ea069e8429ef 211 else if(bf >= btmax)bf = 2;
rcele_85 0:ea069e8429ef 212 else bf = 0;
rcele_85 0:ea069e8429ef 213 }
rcele_85 0:ea069e8429ef 214
rcele_85 0:ea069e8429ef 215 //***************************************** MAIN FUNCTION *******************************************
rcele_85 0:ea069e8429ef 216 int main() {
rcele_85 0:ea069e8429ef 217 uint32_t loop_cnt = 0;
rcele_85 0:ea069e8429ef 218 wait(0.2f);
rcele_85 0:ea069e8429ef 219 pc.baud(9600);
rcele_85 0:ea069e8429ef 220 esp.baud(9600);
rcele_85 0:ea069e8429ef 221 esp.attach(&esp_callback);
rcele_85 0:ea069e8429ef 222 adxl345_init();
rcele_85 0:ea069e8429ef 223 wait(0.01f);
rcele_85 0:ea069e8429ef 224 acctick.attach(&acctick_isr, 0.02);
rcele_85 0:ea069e8429ef 225 timer.start();
rcele_85 0:ea069e8429ef 226 hr_int.rise(&hr_isr);
rcele_85 0:ea069e8429ef 227 buz = 0;
rcele_85 0:ea069e8429ef 228 for (int ap=0; ap<=50; ap++)
rcele_85 0:ea069e8429ef 229 {
rcele_85 0:ea069e8429ef 230 if(sosconf == 0) beep(1,1.0f,0.2f);
rcele_85 0:ea069e8429ef 231 wait(0.1f);
rcele_85 0:ea069e8429ef 232 }
rcele_85 0:ea069e8429ef 233
rcele_85 0:ea069e8429ef 234 // Do forever.
rcele_85 0:ea069e8429ef 235 while(1)
rcele_85 0:ea069e8429ef 236 {
rcele_85 0:ea069e8429ef 237 esp_read_cmd();
rcele_85 0:ea069e8429ef 238 read_adt_temp();
rcele_85 0:ea069e8429ef 239 if(ecgreq == 1)
rcele_85 0:ea069e8429ef 240 {
rcele_85 0:ea069e8429ef 241 esp_send_ecg();
rcele_85 0:ea069e8429ef 242 ecgreq = 0;
rcele_85 0:ea069e8429ef 243 }
rcele_85 0:ea069e8429ef 244
rcele_85 0:ea069e8429ef 245 if(loop_cnt >= 50)
rcele_85 0:ea069e8429ef 246 {
rcele_85 0:ea069e8429ef 247 esp_send_data();
rcele_85 0:ea069e8429ef 248 loop_cnt = 0;
rcele_85 0:ea069e8429ef 249 }
rcele_85 0:ea069e8429ef 250
rcele_85 0:ea069e8429ef 251 if(flagack == 1)
rcele_85 0:ea069e8429ef 252 {
rcele_85 0:ea069e8429ef 253 beep(3,0.4f,0.4f);
rcele_85 0:ea069e8429ef 254 flagack = 0;
rcele_85 0:ea069e8429ef 255 sf = 0;
rcele_85 0:ea069e8429ef 256 ff=0;
rcele_85 0:ea069e8429ef 257 hf=0;
rcele_85 0:ea069e8429ef 258 bf=0;
rcele_85 0:ea069e8429ef 259 }
rcele_85 0:ea069e8429ef 260
rcele_85 0:ea069e8429ef 261 if(sosconf == 0)
rcele_85 0:ea069e8429ef 262 {
rcele_85 0:ea069e8429ef 263 beep(3,0.4f,0.4f);
rcele_85 0:ea069e8429ef 264 sf = 1;
rcele_85 0:ea069e8429ef 265 }
rcele_85 0:ea069e8429ef 266 loop_cnt++;
rcele_85 0:ea069e8429ef 267 wait(0.1f);
rcele_85 0:ea069e8429ef 268 }
rcele_85 0:ea069e8429ef 269
rcele_85 0:ea069e8429ef 270 }