debug_wip
Dependencies: BLE_API mbed nRF51822 X_NUCLEO_IDB0XA1
Fork of Biometricos_0 by
Diff: main.cpp
- 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(); + } +}