debug_wip

Dependencies:   BLE_API mbed nRF51822 X_NUCLEO_IDB0XA1

Fork of Biometricos_0 by Tuna Shields

main.cpp

Committer:
Jacacent
Date:
2018-04-10
Revision:
1:49659ca954b3
Parent:
0:fb0d095dc5dd

File content as of revision 1:49659ca954b3:

#include "mbed.h"
#include "biometricos.h"
#include "Hotboards_rtcc.h"
#include "MMA8451Q.h"
#include "MAX30100_PulseOximeter.h"
#include "ble/BLE.h"
#include "ble/services/UARTService.h"

#define NEED_CONSOLE_OUTPUT 1
#define MMA8451_I2C_ADDRESS (0x1d<<1)
#define REPORTING_PERIOD_MS 1000

#if NEED_CONSOLE_OUTPUT
  
  Serial pc(LED_RED,LED_ORANGE);
  #define DEBUG(...) { pc.printf(__VA_ARGS__); }
#else
  #define DEBUG(...)
#endif

/* general ------------------------------------------------------------------ */

I2C i2c(I2C_SDA, I2C_SCL);
Ticker counter_tick;

bool      timestmap = 0;
float     tick_time;
uint8_t   data[13];
uint32_t  general_counter;

void increment_counter() {
    general_counter++;
}

uint16_t get_cicles(float seconds) {
    return seconds * (1/tick_time);
}

void general_init() {
    tick_time = 0.01;
    i2c.frequency(100000);
    counter_tick.attach(&increment_counter, tick_time);
}
/* -------------------------------------------------------------------------- */

/* led_red ------------------------------------------------------------------ */
/*DigitalOut led_red(LED_RED);
Ticker led_red_ticker;

void periodicCallback(void) {
    led_red = !led_red;
}

void led_red_init() {
    led_red_ticker.attach(periodicCallback, 3);
}*/
/* -------------------------------------------------------------------------- */


/* real time clock ---------------------------------------------------------- */
Hotboards_rtcc rtcc(i2c);

void rtcc_init(){
    if(rtcc.begin()) {
        DEBUG("rtcc initialized!\r\n");
        timestmap = 1;
    } else {
        DEBUG("rtcc not initialized!\r\n");
        timestmap = 0;
    }
}

bool rtcc_now(DateTime &t) {
    if(rtcc.getStatus()) {
        if(!rtcc.now(t)) {
            DEBUG("Error rtcc.now(t)\r\n");
            return 0;
          }
    } else {
        DEBUG("Error rtcc.getStatus()\r\n");
        return 0;
    }

    return true;
}

uint8_t rtcc_verify(const uint8_t *d) {
    DateTime t;
    if(rtcc_now(t)) {
        DEBUG("Time- %d:%d:%d  Date-  %d/ %d/ %d\r\n",t.hour(),t.minute(),t.second(),t.day(),t.month()+1,t.year());
        if((d[2] == t.minute()) && (d[3] == t.hour()) && (d[4] == t.day()) && (d[5] == t.month()) && (d[6] == (t.year() - 2000))) {
            DEBUG("MCP79410 good\r\n");
            return 1;
        } else {
            rtcc.setVBAT(1);
            if(rtcc.adjust(DateTime(d[6] + 2000, d[5], d[4], d[3], d[2], d[1]))) {
              DEBUG("MCP79410 adjusted\r\n");
                return 2;
            } else {
                DEBUG("MCP79410 not adjusted\r\n");
                return 0;
            }
        }
    } else {
        DEBUG("Error rtcc_now in rtcc_verify\r\n");
        return 0;
    }
}
/* -------------------------------------------------------------------------- */


/* bluetooth ---------------------------------------------------------------- */
uint8_t device_name[] = "HNCR-06";
BLEDevice  ble;
UARTService *uartServicePtr;

void disconnectionCallback(const Gap::DisconnectionCallbackParams_t *params) {
    DEBUG("ble disconnected!\r\n");
    DEBUG("ble restarting the advertising process\r\n");
    ble.startAdvertising();
}

void connectionCallback(const Gap::ConnectionCallbackParams_t *params) {
    DEBUG("ble connected!\r\n");
}

void onDataWritten(const GattWriteCallbackParams *params) {
    if ((uartServicePtr != NULL) && (params->handle == uartServicePtr->getTXCharacteristicHandle())) {
        DEBUG("received %u bytes\r\n", params->len);
        uint8_t data_send[2];
        uint8_t bytes_send;

        switch (params->data[0]) {
          case 0x00:
            data_send[0] = 0x00;
            data_send[1] = rtcc_verify(params->data);
            bytes_send = 2;
            break;
        }
        ble.updateCharacteristicValue(uartServicePtr->getRXCharacteristicHandle(), data_send, bytes_send);
    }
}

void ble_init() {
    DEBUG("ble initialized!\r\n");
    ble.init();
    ble.onConnection(connectionCallback);
    ble.onDisconnection(disconnectionCallback);
    ble.onDataWritten(onDataWritten);

    ble.accumulateAdvertisingPayload(GapAdvertisingData::BREDR_NOT_SUPPORTED);
    ble.setAdvertisingType(GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED);
    ble.accumulateAdvertisingPayload(GapAdvertisingData::SHORTENED_LOCAL_NAME,
                                     (const uint8_t *)device_name, sizeof(device_name) - 1);
    ble.accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LIST_128BIT_SERVICE_IDS,
                                     (const uint8_t *)UARTServiceUUID_reversed, sizeof(UARTServiceUUID_reversed));

    ble.setAdvertisingInterval(1000);
    ble.startAdvertising();
}

void send_ble(uint8_t *data, uint8_t size) {
    if (uartServicePtr != NULL && ble.getGapState().connected) {
        ble.updateCharacteristicValue(uartServicePtr->getRXCharacteristicHandle(), data, size);
    } else {
         // DEBUG("Error send_ble\r\n");
    }
}

void send_behavior(uint8_t i) {
    uint8_t bytes_send;
    if(!timestmap) {
        data[1] = 0x00;
        bytes_send = i;
    } else {
        DateTime t;
        if(rtcc_now(t)) {
            data[1] = 0x01;
            data[i] = t.second();
            data[i+1] = t.minute();
            data[i+2] = t.hour();
            data[i+3] = t.day();
            data[i+4] = t.month();
            data[i+5] = (t.year() - 2000);
            bytes_send = i+6;
        } else {
            DEBUG("Error rtcc_now in lm35_sens\r\n");
            bytes_send = 0;
        }
    }
    if(bytes_send)
      send_ble(data, bytes_send);
}
/* -------------------------------------------------------------------------- */


/* button ------------------------------------------------------------------- */
DigitalIn button(USER_BUTTON, PullUp);
bool      button_state, button_last_state;
uint16_t  button_debounce_delay;
uint32_t  button_last_debounce_time;

void button_init() {
    button_debounce_delay = get_cicles(0.5);
    button_last_state = 0;
}

void button_sens() {
    int reading = button;

    if(reading != button_last_state) {
        button_last_debounce_time = general_counter;
    }

    if(general_counter >= (button_last_debounce_time + button_debounce_delay)) {
        if(reading != button_state) {
            button_state = reading;

            if(button_state) {
                DEBUG("button_state == 1\r\n");
            } else {
                DEBUG("button_state == 0\r\n");
            }

            data[0] = 0x02;
            data[2] = button_state;

            send_behavior(3);
        }
    }

    button_last_state = reading;
}
/* -------------------------------------------------------------------------- */


/* lm35 temperature sensor -------------------------------------------------- */
AnalogIn  lm35(TEMP);

bool      lm35_state;
float     lm35_temperature_celsius, factor_temperature;
uint8_t   lm35_num_samples;
uint16_t  lm35_polling_time_main, lm35_min, lm35_max;
uint16_t  lm35_samples_counter, lm35_polling_time_samples, lm35_samples[5];
uint32_t  lm35_last_counter_value, lm35_last_samples_counter_value;

uint16_t lm35_get_adc_value(float degrees_celsius) {
    return degrees_celsius / factor_temperature;
}

void lm35_init() {
    lm35_last_counter_value = 0;
    lm35_samples_counter = 0;
    lm35_last_samples_counter_value = 0;
    lm35_num_samples = 5;
    lm35_polling_time_samples = get_cicles(0.5);
    lm35_polling_time_main = get_cicles(3);
    factor_temperature = 0.3200391; // ((3.274 * 100) / 1023)
    lm35_min = lm35_get_adc_value(20);//62.4923
    lm35_max = lm35_get_adc_value(50);//156.2309

    uint16_t val = lm35.read_u16();

    if(val >= lm35_min && val <= lm35_max) {
        DEBUG("lm35 initialized!\r\n");
        lm35_state = 1;
    } else {
        DEBUG("lm35 not initialized!\r\n");
        lm35_state = 0;
    }
}

void lm35_sens() {
    if(lm35_state)
        if(general_counter >= (lm35_last_counter_value + lm35_polling_time_main))
            if(general_counter >= (lm35_last_samples_counter_value + lm35_polling_time_samples)) {
                uint16_t val = lm35.read_u16();

                if(val >= lm35_min && val <= lm35_max) {
                    uint16_t temperature_sample = val;
                    data[0] = 0x01;
                    data[2] = temperature_sample & 0xff;
                    data[3] = temperature_sample >> 8;

                    send_behavior(4);
                    lm35_last_counter_value = general_counter;
                  }



                lm35_last_samples_counter_value = general_counter;
            }
}
/* -------------------------------------------------------------------------- */


/* termistor breathing sensor  ---------------------------------------------- */
AnalogIn breath(BREATHING);

bool init_exhalation, breathing_status;
uint8_t val, min_val_allowed, max_val_allowed;
uint8_t base, base_umbral, umbral, dif, max_val_readed;
uint16_t breathing_pollingTime;
uint32_t breathing_last_counter_value;

uint16_t breath_get_temp() {
    return breath.read_u16() - 768;
}

void breathing_init() {
    init_exhalation = 0;
    max_val_readed = 0;
    breathing_status = 0;
    breathing_last_counter_value = 0;
    min_val_allowed = 80;
    max_val_allowed = 150;
    base_umbral = 4;
    dif = 2;
    breathing_pollingTime = get_cicles(5);
    base = breath_get_temp();

    if(base > min_val_allowed && base < max_val_allowed) {
        DEBUG("breathing initialized!\r\n");
        umbral = base - base_umbral;
        breathing_status = 1;
    } else {
        DEBUG("breathing not initialized!\r\n");
        breathing_status = 0;
    }
}

void breath_sens() {
    if(breathing_status) {
        val = breath_get_temp();
        //DEBUG("%d\r\n", val);

        if(val > min_val_allowed && val < max_val_allowed) {

            if(val > max_val_readed)
                max_val_readed = val;

            if((general_counter >= (breathing_last_counter_value + breathing_pollingTime))) {
                base = max_val_readed;
                umbral = base - base_umbral;
                max_val_readed = 0;
                //DEBUG("Updated %d %d %d\r\n",val, base ,umbral);
                breathing_last_counter_value = general_counter;
            }

            if(val < umbral && !init_exhalation) {
                init_exhalation = true;
                //DEBUG("init_exhalation\r\n");
            }

            //DEBUG("%d %d\r\n",val, umbral);
            if(val > (umbral + dif) && init_exhalation) {
                DEBUG("Inhalation\r\n");

                data[0] = 0x05;
                data[2] = 0x01;

                send_behavior(3);

                init_exhalation = false;
            }
        }
    }
}
/* -------------------------------------------------------------------------- */


/* max30100 herat rate and oximetry sensor ---------------------------------- */
MAX30100      max30100(i2c);
PulseOximeter pox(max30100);

bool    max30100_status;
float   max_heart_rate, min_heart_rate;
uint8_t min_sp02, max_sp02;
uint8_t samples_max30100, heart_rate_min_dif, sp02_min_dif, counter_max30100;

float  samples_heart_rate[5];
uint8_t samples_sp02[5];

Timer t;

void pox_init() {
    max30100_status = 0;
    samples_max30100 = 5;
    heart_rate_min_dif = 6;
    sp02_min_dif = 2;
    counter_max30100 = 0;

    if(pox.begin()) {
        DEBUG("max30100 initialized!\r\n");
        max30100_status = 1;
        t.start();
    } else {
        DEBUG("max30100 not initialized!\r\n");
        max30100_status = 0;
    }
}

void pox_sens() {
    if(max30100_status) {
        // Make sure to call update as fast as possible
        if(!pox.update()) {
            DEBUG("Error: if(!pox.update())\r\n");
            pox_init();
        }

        // Asynchronously dump heart rate and oxidation levels to the serial
        // For both, a value of 0 means "invalid"
        if (t.read_ms() > REPORTING_PERIOD_MS) {
            float new_heart_rate = pox.getHeartRate();
            uint8_t new_sp02 = pox.getSpO2();

            if(new_heart_rate != 0 && new_sp02 != 0) {
                DEBUG("Heart rate: %f bmp\r\n", new_heart_rate);
                DEBUG("SpO2: %d%\r\n\n", new_sp02);



                    uint32_t int_heart_rate;
                    memcpy(&int_heart_rate,&new_heart_rate,4);

                    data[0] = 0x03;
                    data[2] = new_sp02;
                    data[3] = (int_heart_rate & 0xFF);
                    data[4] = ((int_heart_rate >> 8) & 0xFF);
                    data[5] = ((int_heart_rate >> 16) & 0xFF);
                    data[6] = ((int_heart_rate >> 24) & 0xFF);

                    send_behavior(7);
            //DEBUG("No finger\r\n");
            }

            t.reset();
        }
    }
}
/* -------------------------------------------------------------------------- */


/* mma8451q accelerometer --------------------------------------------------- */
MMA8451Q mma(i2c, MMA8451_I2C_ADDRESS);

bool mma_status, mma_new_value = false;
float mma_y;
uint8_t sample_counter = 0;
uint8_t num_samples = 3;
uint8_t mma_samples[3];

void mma_init() {
    if(mma.begin()) {
        mma_status = 1;
        DEBUG("MMA8451 initialized\r\n");
    } else {
        mma_status = 0;
        DEBUG("MMA8451 not initialized\r\n");
    }
}

bool mma_get_acc_y(float &y) {
    if(mma.getAccY(y))
        y = abs(y);
    else
        return 0;

    return 1;
}

void mma_sens() {
    if(mma_status)
      if(mma.getStatus()) {
          float y;
          if(mma_get_acc_y(y)) {
              if(y > 1.2) {
                  mma_new_value = true;
                  if(mma_y < y)
                      mma_y = y;

              } else if(mma_new_value) {
                  mma_samples[sample_counter++] = mma_y;
                  if(sample_counter == num_samples) {
                      for (uint8_t i = 0; i < num_samples; i++) {
                          if(mma_y < mma_samples[i])
                              mma_y = mma_samples[i];
                      }

                      uint8_t val =  (mma_y - 1) * 255;

                      DEBUG("%d\r\n", val);
                      sample_counter = 0;

                      data[0] = 0x04;
                      data[2] = val;

                      send_behavior(3);
                  }

                  mma_new_value = false;
                  mma_y = 0;
              }
          } else{
              DEBUG("MMA8451 Error getAccAxis()\r\n");
              mma.setStatus(false);
          }
      } else
          mma_init();
}
/* -------------------------------------------------------------------------- */


/* ecg ---------------------------------------------------------------------- */
AnalogIn ecg(ECG_OUT);
DigitalIn ecg_lo_p(ECG_LO_PLUS);
DigitalIn ecg_lo_m(ECG_LO_MIN);

bool ecg_status;
uint8_t ecg_samples[20], ecg_samples_counter;
uint16_t ecg_polling_time_main;
uint32_t ecg_last_counter_value;

void ecg_init() {
    ecg_samples_counter = 1;
    ecg_last_counter_value = 0;
    ecg_polling_time_main = get_cicles(0.02);
    ecg_samples[0] = 0x06;

    if(!ecg_lo_p && !ecg_lo_m){
        ecg_status = 1;
        DEBUG("ecg initialized\r\n");
    } else {
        ecg_status = 0;
        DEBUG("ecg not initialized\r\n");
    }
}

uint8_t get_ecg_value() {
    uint16_t val = ecg.read_u16();
    if(val > 232 && val < 743) {
        return (val - 232)/2;
    } else {
        return 0;
    }
}

void ecg_sens() {
    if(ecg_status)
        if(general_counter >= (ecg_last_counter_value + ecg_polling_time_main)) {
            if(!ecg_lo_p && !ecg_lo_m){
                uint8_t val = get_ecg_value();
                ecg_samples[ecg_samples_counter++] = val;

                if(ecg_samples_counter == 20) {
                    send_ble(ecg_samples, 20);
                    ecg_samples_counter = 1;
                }

                ecg_last_counter_value = general_counter;
            }
        }
}
/* -------------------------------------------------------------------------- */

int main(void)
{
    pc.printf("\r\nMensaje de prueba DEBUG");
    DEBUG("\r\nInitialising program\r\n");

    ble_init();
    UARTService uartService(ble);
    uartServicePtr = &uartService;

//    rtcc_init();
    general_init();

    //led_red_init();
    button_init();
    lm35_init();
    mma_init();
    breathing_init();
    pox_init();
    ecg_init();

    while (true) {

        button_sens();
        lm35_sens();
        mma_sens();
        breath_sens();
        pox_sens();
        ecg_sens();

        ble.waitForEvent();
    }
}