debug_wip

Dependencies:   BLE_API mbed nRF51822 X_NUCLEO_IDB0XA1

Fork of Biometricos_0 by Tuna Shields

Revision:
0:fb0d095dc5dd
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp	Tue Apr 10 15:47:07 2018 +0000
@@ -0,0 +1,597 @@
+#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();
+    }
+}