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
Diff: main.cpp
- Revision:
- 0:ea069e8429ef
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/main.cpp Fri Jan 13 18:39:18 2017 +0000 @@ -0,0 +1,270 @@ +#include "mbed.h" +#include "ADT7320_SPI.h" +#include "math.h" +#include "ADXL345_I2C.h" + +#define ESP_RXBUF_LEN 20 + + +// GRPEACH SMART HEALTH MONITOR WITH IOT FOR ELDER PEOPLE +// Mbed Code for Renesas GR-PEACH REV-0 +// Released Under Creative Commons Attribution-ShareAlike 3.0 Unported Licence +Serial pc(USBTX, USBRX); // tx, rx for USB Debug on PC +Serial esp(D9, D8); // tx, rx for ESP8266 Interfacing on UART + +ADT7320_SPI adt(D11, D12, D13, D10); // mosi, miso, sclk, cs for ADT7320 Temperature Sensor +Ticker acctick; // ticker for sample of adxl345 at every 10ms regardless what the loop doing + +ADXL345_I2C accelerometer(I2C_SDA,I2C_SCL); // sda and scl for ADXL345 Temperature Sensor +Timer timer; // timer for measure time interval between two heart beat Interrupts + +InterruptIn hr_int(P1_10); +DigitalOut buz(D6); +DigitalIn loff(D7); +DigitalIn sosconf(P1_9); +AnalogIn ecg(P1_8); + +volatile char esp_buf[ESP_RXBUF_LEN]; // Circular Buffer for ESP8266 Serial Receive As MODSERIAL not supported in GRPeach +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 + +volatile float ax,ay,az,a; +volatile float aavg = 50.0f; + +uint32_t pre_millis=0; + +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; + +// >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ESP8266 UART Receive CallBack(ISR) <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< +void esp_callback() { + esp_buf[esp_pos] = esp.getc(); + if(esp_buf[esp_pos]== '#') + { + esp_ok = 1; + } + esp_pos = (esp_pos+1)% ESP_RXBUF_LEN; +} + +//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Beep on buzzer <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< +void beep(unsigned int _beeps, float _on, float _off) +{ + unsigned int _i; + for(_i=0 ; _i<= _beeps; _i++) + { + buz = 1; + wait(_on); + buz = 0; + wait(_off); + + } + +} + +// >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ADXL345 Ticker CallBack(ISR) to detect Impact <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< +void acctick_isr() { + int accraw[3] = {0, 0, 0}; + accelerometer.getOutput(accraw); + ax = (float)((int16_t)accraw[0])/5.2f ; + ay = (float)((int16_t)accraw[1])/5.2f ; + az = (float)((int16_t)accraw[2])/5.2f ; + a = sqrt(pow(ax,2.0f) + pow(ay,2.0f) + pow(az,2.0f)); + aavg = aavg*0.85f + a*0.15f; + if(aavg < 30.0f) + { + beep(2, 0.3f, 0.3f); + ff = 1; + } + //printf("%3.1f%%\t%3.1f%%\r\n",aavg,a); + + //printf("%d\t%d\t%d\r\n",accraw[0],accraw[1],accraw[2]); +} + +// >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ADXL435 Accelerometer Initlization <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< +void adxl345_init(void) +{ + wait(.001); + accelerometer.getDeviceID(); + wait(.001); + // These are here to test whether any of the initialization fails. + accelerometer.setPowerControl(0x00); + //Full resolution, +/-16g, 4mg/LSB. + wait(.001); + accelerometer.setDataFormatControl(0x0B); + wait(.001); + //3.2kHz data rate. + accelerometer.setDataRate(ADXL345_3200HZ); + wait(.001); + //Measurement mode. + accelerometer.setPowerControl(MeasurementMode); +} + +// >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ESP8266 UART returns how many chars available to read <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< +int esp_available(void) +{ + return ((ESP_RXBUF_LEN + esp_pos - esp_por) % ESP_RXBUF_LEN); +} + +// >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ESP8266 UART returns read one char <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< +char esp_read(void) +{ + char c = esp_buf[esp_por]; + esp_por = (esp_por + 1)% ESP_RXBUF_LEN; + return(c); +} + +// >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ESP8266 UART Flush receive Buffer <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< +void esp_flush(void) +{ + esp_pos = 0; + esp_por = 0; +} + +// >>>>>>>>>>>>>>>>>>>>> ESP8266 UART returns comma seperated data points encapsulated between * and # <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< +int esp_read_cmd() +{ + if (esp_ok == 1 ) + { + char tmp[60]; + char* temp; + esp_ok = false; + int _cnt = 0; + while(esp_read() != '*' ); + tmp[_cnt] = esp_read(); + while(tmp[_cnt] != '#') + { + _cnt++; + tmp[_cnt]= esp_read(); + } + tmp[_cnt] = '\0'; + esp.printf("%s\r\n",tmp); + temp = strtok(tmp, ","); + hrmax = atoi(temp); + temp = strtok(NULL, ","); + hrmin = atoi(temp); + temp = strtok(NULL, ","); + btmax = atoi(temp); + temp = strtok(NULL, ","); + btmin = atoi(temp); + temp = strtok(NULL, ","); + ecgreq = atoi(temp); + temp = strtok(NULL, ","); + flagack = atoi(temp); + pc.printf("%d %d %d %d %d %d\r\n",hrmax,hrmin,btmax,btmin,ecgreq,flagack); + return 1; + } + else return 0; +} + +//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ECG/HR ISR <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< +void hr_isr() +{ + uint32_t _hr; + _hr = timer.read_ms() - pre_millis; + pre_millis = timer.read_ms(); + //pc.printf("premillis = %d ",pre_millis); + _hr = 60000/_hr; + if(_hr > 31 && _hr < 200) + { + hr = ((hr*14) + _hr)/15; + } + if(loff == 1)hr=31; + if(hr <= hrmin)hf = 1; + else if(hr >= hrmax)hf = 2; + else hf = 0; + //pc.printf("Heart Rate = %d \r\n",hr); +} + +//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ECG capture Graph and send to ESP8266 <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< +void esp_send_ecg(void) +{ + uint32_t _cnt = 0; + beep(4,0.2f,0.5f); + wait(2.0f); + beep(1,0.2f,0.1f); + for(_cnt=0; _cnt<410; _cnt++) + { + float raw = ecg.read(); + uint32_t ecg_point = (uint32_t)(((raw*100.0f)-13.15f)*1.66f); + if(ecg_point > 99)ecg_point=99; + esp.printf("%d,",ecg_point); + pc.printf("%d,",ecg_point); + wait(0.01f); + } + esp.printf("10#"); + pc.printf("10#\r\n"); + pc.printf("ecg graph packet sent..\r\n"); + beep(1,0.9f,0.1f); +} + +//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ECG capture Graph and send to ESP8266 <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< +void esp_send_data(void) +{ + esp.printf("*%d,%d,%d,%d,%d,%d,%d,%d,%d,%d#",hr,hrmax,hrmin,bt,btmax,btmin,hf,bf,ff,sf); + pc.printf("*%d,%d,%d,%d,%d,%d,%d,%d,%d,%d#\r\rn",hr,hrmax,hrmin,bt,btmax,btmin,hf,bf,ff,sf); + pc.printf("data packet sent..\r\n"); +} + +//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Read ADT7320 Temperature sensor & bf flag <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< +void read_adt_temp(void) +{ + bt = (uint32_t)(adt.readTemp()); + if(bt <= btmin)bf = 1; + else if(bf >= btmax)bf = 2; + else bf = 0; +} + +//***************************************** MAIN FUNCTION ******************************************* +int main() { + uint32_t loop_cnt = 0; + wait(0.2f); + pc.baud(9600); + esp.baud(9600); + esp.attach(&esp_callback); + adxl345_init(); + wait(0.01f); + acctick.attach(&acctick_isr, 0.02); + timer.start(); + hr_int.rise(&hr_isr); + buz = 0; + for (int ap=0; ap<=50; ap++) + { + if(sosconf == 0) beep(1,1.0f,0.2f); + wait(0.1f); + } + + // Do forever. + while(1) + { + esp_read_cmd(); + read_adt_temp(); + if(ecgreq == 1) + { + esp_send_ecg(); + ecgreq = 0; + } + + if(loop_cnt >= 50) + { + esp_send_data(); + loop_cnt = 0; + } + + if(flagack == 1) + { + beep(3,0.4f,0.4f); + flagack = 0; + sf = 0; + ff=0; + hf=0; + bf=0; + } + + if(sosconf == 0) + { + beep(3,0.4f,0.4f); + sf = 1; + } + loop_cnt++; + wait(0.1f); + } + + } \ No newline at end of file