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

main.cpp

Committer:
rcele_85
Date:
2017-01-13
Revision:
0:ea069e8429ef

File content as of revision 0:ea069e8429ef:

#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);
    }
   
 }