HAND
Dependencies: mbed BMI160 MLX90614 max32630fthr Adafruit_FeatherOLED MAX30100
functions.cpp
- Committer:
- condato_mbed
- Date:
- 2021-11-03
- Revision:
- 1:774d50d6f9d6
- Parent:
- 0:d36fd4cabb70
File content as of revision 1:774d50d6f9d6:
#include "functions.h" #include "ble_functions.h" #include "RawSerial.h" #include <InterruptIn.h> #include <InterruptManager.h> #include "bmi160.h" #include "max32630fthr.h" #include "max3263x.h" #include "MAX14690.h" #include "MAX30100_PulseOximeter.h" #include "mlx90614.h" #include "Adafruit_SSD1306.h" #include <BLE.h> #include "ble/BLE.h" #include "ble/Gap.h" #include "SDBlockDevice.h" #include "FATFileSystem.h" #include <errno.h> #include <stdio.h> #include <time.h> #include <stdint.h> extern char device_id[]; extern unsigned short int measure_id; extern unsigned short int log_id; extern Serial pan1326b; extern DigitalOut bt_rst; extern volatile int conn_state; extern bool in_BT; extern AnalogIn battery; extern DigitalOut r; extern DigitalOut g; extern DigitalOut b; extern DigitalOut RGBs[]; extern MAX32630FTHR pegasus; extern I2C i2cm2; extern MAX14690 max14690; extern InterruptIn button; extern FATFileSystem fileSystem; extern SDBlockDevice blockDevice; extern I2C i2c; extern int sensor_temp; extern Adafruit_SSD1306_I2c featherOLED; extern Timer t; extern PulseOximeter pox; extern uint32_t tsLastReport; extern DigitalIn ain; extern double anSignal; extern int bpm; extern int signal; extern int ibi; extern MLX90614 IR_thermometer; extern float ir_temp; extern volatile int quit; extern volatile int ble_return; extern volatile int conn_state; extern int counter_ble; extern bool error_status; extern bool BT_error; extern bool shipping; extern bool pause; extern bool init_status; extern bool after_BT; extern Timeout after_BLE; extern Timeout turnoff; extern Timeout flipper; // extern Timeout advertise_cancel; // Zum abbrechen von BT bei keinem Verbindungsaufbau extern Timeout connected_cancel; // Zum abbrechen von BT bei kein Befehlempfang extern Ticker mess_timer; // ticker eventuell nur bis 30 Minuten geeignet extern Ticker ticker; extern time_t now; extern time_t raw; extern float buffer_temp; extern struct tm current; extern struct tm actual; extern struct user_config_struct user_config_para; extern struct tm user_config_time; extern Timeout done_rcv; extern int next_state; extern int unsigned long t_diff; extern int unsigned long unix_time; extern int default_advertise_time; extern int default_connected_time; extern int alert_count; extern Timer t; extern PulseOximeter pox; extern uint32_t tsLastReport; bool newValueMAX30100 = 0; extern float heartRate; float finalHeartRate; extern uint8_t sp02; uint16_t finalSp02; uint32_t REPORTING_PERIOD_MS = 1000; std::vector<float> valuesHeartRate; std::vector<uint8_t> valuesSp02; uint8_t samplesMAX30100 = 10; uint8_t counterMAX30100 = 0; void turnON(){ max14690.writeReg(MAX14690::REG_PWR_CFG, 0x1D); char string[] = "H.A.N.D. turned on"; write_to_sd_log_single(string); } void reboot(){ char string[] = "Rebooting H.A.N.D. ..."; write_to_sd_log_single(string); printf("\n__________________________\n\nRebooting H.A.N.D.\n__________________________\n\n"); log_id -= 2; BT_false(); wait(0.2); NVIC_SystemReset(); } void set_time(){ unix_time = 946684800; //946684800: 2000-01-01 00:00:00 now = time(0); time(&now); set_time(unix_time); } int set_app_time(unsigned long device_time){ printf("\nDevice time: %ld\n", device_time); if(device_time >= 946684800){ unix_time = device_time; now = time(0); time(&now); set_time(unix_time); tm *current; time(&now); current = localtime (&now); char string[] = "Device time updated"; write_to_sd_log_single(string); printf ("\nDate: 20%02d-%02d-%02d %02d:%02d:%02d\r\n", current->tm_year - 100, current->tm_mon + 1, current->tm_mday, current->tm_hour, current->tm_min, current->tm_sec); printf("\n__________________________\n\nNew device time applied\n__________________________\n\n"); return 1; }else{ printf("\n__________________________\n\nCan not applie new device time\n__________________________\n\n"); return -1; } } void write_to_sd_log_single(char log_string[]) { fileSystem.unmount(); fflush(stdout); fileSystem.mount(&blockDevice); char file_name[14] = "/fs/log"; char file_type[10] = ".csv"; char buff_file[25]; sprintf(buff_file, "%s%s", file_name, file_type); FILE * f = fopen(buff_file, "a"); log_id++; tm *current; time(&now); current = localtime (&now); fprintf(f, "%d;20%02d-%02d-%02d;%02d:%02d:%02d;%s;\r\n", log_id, current->tm_year - 100, current->tm_mon + 1, current->tm_mday, current->tm_hour, current->tm_min, current->tm_sec, log_string); fclose(f); fileSystem.unmount(); } void write_to_sd_messdaten_single(float buffer_temp) { fileSystem.unmount(); fflush(stdout); fileSystem.mount(&blockDevice); char file_name[14] = "/fs/messdaten"; char file_type[10] = ".csv"; char buff_file[25]; sprintf(buff_file, "%s%s", file_name, file_type); FILE * f = fopen(buff_file, "a"); int buffer_conv = (int)(100*buffer_temp); measure_id++; tm *current; time(&now); current = localtime (&now); fprintf(f, "%d;20%02d-%02d-%02d;%02d:%02d:%02d;%d;%4d;\r\n", measure_id, current->tm_year - 100, current->tm_mon + 1, current->tm_mday, current->tm_hour, current->tm_min, current->tm_sec, sensor_temp, buffer_conv); fclose(f); fileSystem.unmount(); } void get_save_Messpunkt(float temperatur) { buffer_temp = temperatur; tm *current; time(&now); current = localtime (&now); write_to_sd_messdaten_single(buffer_temp); sensor_temp = 2; write_to_sd_messdaten_single(finalHeartRate); write_to_sd_messdaten_single((float)finalSp02); sensor_temp = 1; printf ("Measurement %d saved 20%02d-%02d-%02d %02d:%02d:%02d\r\n", measure_id, current->tm_year - 100, current->tm_mon + 1, current->tm_mday, current->tm_hour, current->tm_min, current->tm_sec); } float get_Messwert() { float temperatur = 0; IR_thermometer.getTemp(&temperatur); wait(0.3); if(user_config_para.alert == 1){ if(user_config_para.minimum > temperatur){ char string[] = "ALERT: lower threshold limit below"; write_to_sd_log_single(string); printf("ALERT: lower threshold limit below (lower limit: %d C)\n", user_config_para.minimum); alert_count++; }else if(user_config_para.maximum < temperatur){ char string[] = "ALERT: upper threshold exceeded"; write_to_sd_log_single(string); printf("ALERT: upper threshold exceeded (upper limit: %d C)\n", user_config_para.maximum); alert_count++; } } get_save_Messpunkt(temperatur); return temperatur; } int create_file_messdaten(){ fileSystem.unmount(); fflush(stdout); int file_err = fileSystem.mount(&blockDevice); if(file_err){ fileSystem.unmount(); char string[] = "SD mount error"; write_to_sd_log_single(string); printf("\n__________________________\n\n! No SD-card detected !\n__________________________\n\n"); return -1; }else{ char file_name[14] = "/fs/messdaten"; char file_type[10] = ".csv"; char buff_file[25]; sprintf(buff_file, "%s%s", file_name, file_type); FILE * f = fopen(buff_file, "a"); fclose(f); fileSystem.unmount(); return 1; } } int create_file_log() { fileSystem.unmount(); fflush(stdout); int file_err = fileSystem.mount(&blockDevice); if(file_err){ fileSystem.unmount(); char string[] = "SD mount error"; write_to_sd_log_single(string); printf("\n__________________________\n\n! No SD-card detected !\n__________________________\n\n"); return -1; }else{ char file_name[14] = "/fs/log"; char file_type[10] = ".csv"; char buff_file[25]; sprintf(buff_file, "%s%s", file_name, file_type); FILE * f = fopen(buff_file, "a"); fclose(f); fileSystem.unmount(); return 1; } } int delete_file_messdaten(){ fileSystem.unmount(); fflush(stdout); int file_err = fileSystem.mount(&blockDevice); if(file_err) { char string[] = "SD mount error"; write_to_sd_log_single(string); printf("\n__________________________\n\n! No SD-card detected !\n__________________________\n\n"); fileSystem.unmount(); return -1; }else{ remove("/fs/messdaten.csv"); wait(0.2); fileSystem.unmount(); fflush(stdout); char string_1[] = "Measuring data file deleted"; write_to_sd_log_single(string_1); if(create_file_messdaten() == 1){ char string[] = "New measuring data file created"; write_to_sd_log_single(string); fileSystem.unmount(); measure_id = 0; printf("\n__________________________\n\nMeasuring data deleted\n__________________________\n\n"); return 1; }else{ fileSystem.unmount(); printf("\nError while creating new file\n"); return -1; } } } int delete_file_log(){ fileSystem.unmount(); fflush(stdout); int file_err = fileSystem.mount(&blockDevice); if(file_err) { char string[] = "SD mount error"; write_to_sd_log_single(string); printf("\n__________________________\n\n! No SD-card detected !\n__________________________\n\n"); fileSystem.unmount(); return -1; }else{ remove("/fs/log.csv"); wait(0.2); /* char string_1[] = "Log file deleted"; write_to_sd_log_single(string_1); */ if(create_file_log() == 1){ log_id = 0; char string[] = "New log data file created"; write_to_sd_log_single(string); fileSystem.unmount(); printf("\n__________________________\n\nLog deleted\n__________________________\n\n"); return 1; }else{ fileSystem.unmount(); printf("\nError while creating new file\n"); return -1; } } } int file_copy(const char *src, const char *dst) { fileSystem.unmount(); fflush(stdout); int retval = 0; int ch; int file_err = fileSystem.mount(&blockDevice); if(file_err) { printf("\n__________________________\n\n! No SD-card detected !\n__________________________\n\n"); fileSystem.unmount(); return -1; }else{ FILE *fpsrc = fopen(src, "r"); // src file FILE *fpdst = fopen(dst, "w"); // dest file while (1) { // Copy src to dest ch = fgetc(fpsrc); // until src EOF read. if (ch == EOF) break; fputc(ch, fpdst); } fclose(fpsrc); fclose(fpdst); fpdst = fopen(dst, "r"); // Reopen dest to insure if (fpdst == NULL) { // that it was created. retval = -1; // Return error. } else { fclose(fpdst); retval = 0; // Return success. } return retval; } } int load_user_config() { printf("\n__________________________\n\nReading the config\n__________________________\n\n"); fileSystem.unmount(); fflush(stdout); int file_err = fileSystem.mount(&blockDevice); if(file_err) { printf("\n__________________________\n\n! No SD-card detected !\n__________________________\n\n"); fileSystem.unmount(); return -1; }else{ FILE * conf = fopen ("/fs/user_config.csv", "rb"); char buffer[700]; int length; if (conf) { fseek (conf, 0, SEEK_END); length = ftell (conf); fseek (conf, 0, SEEK_SET); if (buffer) { fread (buffer, 1, length, conf); } fclose(conf); fileSystem.unmount(); if (buffer) { char* single_word[100]; int word_count = 0; char delim[] = ";\r\n"; char *ptr = strtok(buffer, delim); for(int j = 0; j < 100; j++) { single_word[j] = new char[15]; } while (ptr != NULL) { strcpy(single_word[word_count], ptr); ptr = strtok(NULL, delim); word_count++; } const char *params[] = {"interval", "alert", "minimum", "maximum", "advertise", "connected"}; for(int k = 0; k < 100; k++) { for(int l = 0; l < 5; l++) { if(strcmp(single_word[k], params[0]) == 0){ user_config_para.interval = atoi(single_word[k+1]); } else if(strcmp(single_word[k], params[1]) == 0){ user_config_para.alert = atoi(single_word[k+1]); } else if(strcmp(single_word[k], params[2]) == 0){ user_config_para.minimum = atoi(single_word[k+1]); } else if(strcmp(single_word[k], params[3]) == 0){ user_config_para.maximum = atoi(single_word[k+1]); } else if(strcmp(single_word[k], params[4]) == 0){ user_config_para.advertise = atoi(single_word[k+1]); } else if(strcmp(single_word[k], params[5]) == 0){ user_config_para.connected = atoi(single_word[k+1]); } } } //printf("\nID: #%s\n", user_config_para.id); //char idnummer[10]; //sscanf(idnummer, "%d", &user_config_para.id); printf("\nH.A.N.D. ID #%s\n", device_id); if(user_config_para.interval == 1){ printf("Mesureual interval: %d second\n", user_config_para.interval); }else{ printf("Mesureual interval: %d seconds\n", user_config_para.interval); } if(user_config_para.alert == 1){ printf("Alert-function - ON\n"); printf("Minimum temperature: %d C | Maximum temperature: %d C\n", user_config_para.minimum, user_config_para.maximum); }else{ printf("Alert-function - OFF\n"); } printf("BLE advertise timer: %d seconds\n", user_config_para.advertise); printf("BLE when connected timer: %d seconds\n", user_config_para.connected); } else{ printf("Buffer empty: %s", buffer); } return 1; } else{ printf("!!! Config file not found, error: %s (%d)\n", strerror(errno), -errno); fileSystem.unmount(); user_config_para.advertise = default_advertise_time; user_config_para.connected = default_connected_time; return -1; } } } int load_standard_config(){ fileSystem.unmount(); fflush(stdout); printf("\n__________________________\n\nReseting config settings \nto default\n__________________________\n\n"); int file_err = fileSystem.mount(&blockDevice); if(file_err){ printf("\n__________________________\n\n! No SD-card detected !\n__________________________\n\n"); fileSystem.unmount(); return -1; }else{ remove("/fs/user_config.csv"); wait(0.2); if(file_copy("/fs/standard_config.csv", "/fs/user_config.csv") == 0){ load_user_config(); printf("\n__________________________\n\nConfig settings reseted\n__________________________\n\n"); char string[] = "Standard user config file created"; write_to_sd_log_single(string); fileSystem.unmount(); return 1; }else{ printf("\n__________________________\n\nFailed to reset config file\n__________________________\n\n"); char string[] = "Failed to copy standard config file"; write_to_sd_log_single(string); fileSystem.unmount(); return -1; } } } int read_id() { fileSystem.unmount(); fflush(stdout); int file_err = fileSystem.mount(&blockDevice); if(file_err) { printf("\n__________________________\n\n! No SD-card detected !\n__________________________\n\n"); fileSystem.unmount(); return -1; }else{ FILE * id = fopen ("/fs/id.csv", "rb"); char buffer[14]; int length; if (id) { fseek (id, 0, SEEK_END); length = ftell (id); fseek (id, 0, SEEK_SET); if (buffer) { fread (buffer, 1, length, id); } fclose(id); fileSystem.unmount(); if (buffer) { char* single_word[10]; int word_count = 0; char delim[] = ";\r\n"; char *ptr = strtok(buffer, delim); for(int j = 0; j < 10; j++) { single_word[j] = new char[10]; } while (ptr != NULL) { strcpy(single_word[word_count], ptr); ptr = strtok(NULL, delim); word_count++; } strcpy(device_id, single_word[1]); return 1; } else{ printf("Buffer empty: %s", buffer); return -1; } } else{ printf("!!! Config file not found, error: %s (%d)\n", strerror(errno), -errno); fileSystem.unmount(); return -1; } } } int create_user_config(char params[]){ fileSystem.unmount(); fflush(stdout); int file_err = fileSystem.mount(&blockDevice); if(file_err){ printf("\n__________________________\n\n! No SD-card detected !\n__________________________\n\n"); fileSystem.unmount(); return -1; }else{ remove("/fs/user_config.csv"); wait(0.2); char string[] = "User config file deleted"; write_to_sd_log_single(string); fileSystem.unmount(); fileSystem.mount(&blockDevice); char file_name[16] = "/fs/user_config"; char file_type[10] = ".csv"; char buff_file[27]; sprintf(buff_file, "%s%s", file_name, file_type); FILE * f = fopen(buff_file, "a"); fclose(f); char string_1[] = "User config file created"; write_to_sd_log_single(string_1); fileSystem.unmount(); char *single_word[15]; int word_count = 0; char delim[] = ";\r\n"; char *ptr = strtok(params, delim); for(int j = 0; j < 9; j++) { single_word[j] = new char[6]; } while (ptr != NULL) { strcpy(single_word[word_count], ptr); ptr = strtok(NULL, delim); word_count++; } printf("interval;%s;\r\nalert;%s;\r\nminimum;%s;\r\nmaximum;%s;\r\nadvertise;%s;\r\nconnected;%s;", single_word[0], single_word[1], single_word[2], single_word[3], single_word[4]); fileSystem.mount(&blockDevice); FILE * fp = fopen("/fs/user_config.csv", "w"); fprintf(fp, "interval;%s;\r\n", single_word[0]); fprintf(fp, "alert;%s;\r\n", single_word[1]); fprintf(fp, "minimum;%s;\r\n", single_word[2]); fprintf(fp, "maximum;%s;\r\n", single_word[3]); fprintf(fp, "advertise;%s;\r\n", single_word[4]); fprintf(fp, "connected;%s;\r\n", single_word[5]); fclose(fp); fileSystem.unmount(); if(load_user_config() == 1){ return 1; }else{ printf("\nFaild to read the config!\n"); return -1; } } } void led_blink(int led, int anzahl, int lang, int pause){ for(int i = 0; anzahl > i; i++){ RGBs[led] = 0; if(lang == 1){ wait(1.5); }else{ wait(0.5); } RGBs[led] = 1; wait(0.5); } if(pause == 1){ wait(1); } } void error_handler(int error) { g = 1; wait(1); int file_err = fileSystem.mount(&blockDevice); if(file_err){ switch (error) { case 10:{ led_blink(0, 2, 1, 1); } break; case 11:{ BT_error = true; led_blink(0, 1, 1, 1); led_blink(0, 2, 1, 1); } break; case 110:{ led_blink(0, 2, 1, 1); led_blink(0, 3, 1, 1); } break; case 111:{ BT_error = true; led_blink(0, 1, 1, 1); led_blink(0, 2, 1, 1); led_blink(0, 3, 1, 1); } break; } fileSystem.unmount(); }else{ tm *current; time(&now); current = localtime (&now); switch (error) { case 0:{ char string[] = "Initializing succesfull"; write_to_sd_log_single(string); led_blink(1, 1, 0, 0); } break; case 1:{ char string[] = "Initializing failed: Bluetooth not detected"; write_to_sd_log_single(string); BT_error = true; led_blink(0, 1, 1, 1); } break; case 100:{ char string[] = "Initializing failed: Temperature sensor not detected"; write_to_sd_log_single(string); led_blink(0, 3, 1, 1); } break; case 101:{ char string[] = "Initializing failed: Temperature sensor and bluetooth not detected"; write_to_sd_log_single(string); BT_error = true; led_blink(0, 1, 1, 1); led_blink(0, 3, 1, 1); } break; } fileSystem.unmount(); } r = 1; g = 1; b = 1; wait(0.5); } /* void sendDataToProcessing(char symbol, int data) { if(symbol == 'S'){ signal = data; } else if(symbol == 'B'){ bpm = data; } else if(symbol == 'Q'){ ibi = data; } } */ void onBeatDetected() { //printf("Beat!\r\n"); } bool setup() { // Initialize the PulseOximeter instance and register a beat-detected callback if(!pox.begin()) return false; pox.setOnBeatDetectedCallback(onBeatDetected); return true; } void updateMAX30100 (){ // Make sure to call update as fast as possible pox.update(); if (t.read_ms() > REPORTING_PERIOD_MS) { heartRate = pox.getHeartRate(); sp02 = pox.getSpO2(); if(heartRate != 0 && sp02 != 0) { valuesHeartRate.push_back(heartRate); valuesSp02.push_back(sp02); counterMAX30100 ++; next_state = 1; }else{ next_state = 0; } if(samplesMAX30100 == counterMAX30100) { finalHeartRate = 0; finalSp02 = 0; for(int i=0; i<samplesMAX30100; i++){ finalHeartRate += valuesHeartRate[i]; finalSp02 += valuesSp02[i]; } finalHeartRate /= samplesMAX30100; finalSp02 /= samplesMAX30100; counterMAX30100 = 0; valuesHeartRate.clear(); valuesSp02.clear(); newValueMAX30100 = true; } t.reset(); } } void loop() { updateMAX30100(); if(newValueMAX30100){ printf("--->New Value\r\n"); printf("Heart rate: %f",finalHeartRate); printf(" bpm / SpO2: %d%\r\n",finalSp02); printf("*************************\r\n"); newValueMAX30100 = false; } } int check_devices() { printf("\nDevices check...\n\n"); int bl = 1; int sd = 10; int tempsen = 100; int pulsoxi = 1000; //BLE check bt_rst = 1; bt_rst = 0; wait(0.5); BLE& ble = BLE::Instance(BLE::DEFAULT_INSTANCE); ble.init(bleInitComplete); if(ble.hasInitialized() == true){ bl = 0; BT_error = false; printf("\nBLE detected\n"); printMacAddress(); }else{ BT_error = true; printf("\nBLE not detected!\n"); } //SD check int file_err = fileSystem.mount(&blockDevice); if(file_err) { printf("\nSD-card not detected\n"); BT_error = true; } else { sd = 0; create_file_log(); create_file_messdaten(); printf("\nSD-card detected\n"); fileSystem.unmount(); messdaten_count(); printf("Measuremnts count: %d\n", measure_id); log_count(); printf("Logs count: %d\n", log_id); } fileSystem.unmount(); //IR Thermometer check if(IR_thermometer.getTemp(&ir_temp)){ printf("\nIR Thermometer detected\n"); tempsen = 0; }else{ printf("\nIR Thermometer not detected\n"); } //Pulsoximeter check if(setup()){ printf("\nPulsoximeter detected!\r\n"); t.start(); pulsoxi = 0; }else{ printf("\nPulsoximeter not detected!\r\n"); } //Check output int devices = pulsoxi + tempsen + sd + bl; if(devices != 0000){ printf("\nError in check_devices(): %04d\n", devices); error_handler(devices); return 0; }else{ printf("\n__________________________\n\nAll devices connected\n__________________________\n\n"); return 1; } } int RTC_check(){ tm *current; time(&now); if ( (current = localtime (&now) ) == NULL) { printf ("\n\n__________________________\n\n! RTC initialize failed !\n__________________________\n"); return -1; }else{ set_time(); printf ("\n\n__________________________\n\nRTC initialized\n__________________________\n"); return 1; } } void max14690_init(){ max14690.resetToDefaults(); max14690.ldo2Millivolts = 3300; max14690.ldo3Millivolts = 3300; max14690.ldo2Mode = MAX14690::LDO_ENABLED; max14690.ldo3Mode = MAX14690::LDO_ENABLED; max14690.intEnChgStatus = 1; max14690.monCfg = MAX14690::MON_SYS; //Monitoring - Multiplexer auf Battery eingestellt, um Akku-wert auszulesen max14690.monRatio = MAX14690::MON_DIV4; max14690.intEnChgStatus = 0; max14690.ldo3Mode = MAX14690::SW_EN_MPC1_DSC; if (max14690.init() == MAX14690_ERROR) { printf("Error initializing MAX14690"); } } void init(){ r = 1; g = 1; b = 1; printf("\n\n__________________________\n\nStarting H.A.N.D.\n__________________________\n\n"); g = 0; printf("Initializing MAX32630FTHR\n\n"); pegasus.init(MAX32630FTHR::VIO_3V3); printf("Initializing MAX14690N\n"); max14690_init(); if(RTC_check() == 1){ if(check_devices() == 1 & read_id() == 1 & load_user_config() == 1){ printf("\n__________________________\n\nInitializing succesfull\n__________________________\n\n"); BLE& ble = BLE::Instance(BLE::DEFAULT_INSTANCE); g = 1; init_status = true; error_status = false; error_handler(000); }else{ printf("\n__________________________\n\nInitializing failed\n__________________________\n\n"); BLE& ble = BLE::Instance(BLE::DEFAULT_INSTANCE); next_state = 0; init_status = false; error_status = true; g = 1; } }else{ printf("\n__________________________\n\nRTC failure\n__________________________\n\n"); error_status = true; init_status = false; next_state = 0; g = 1; } }