dsdaf
Dependencies: FXOS8700 Hexi_KW40Z Hexi_OLED_SSD1351 MAX30101
Fork of HeartRate by
main.cpp
00001 #include "mbed.h" 00002 #include "mbed_events.h" 00003 #include "MAX30101.h" 00004 #include "Hexi_KW40Z.h" 00005 #include "Hexi_OLED_SSD1351.h" 00006 #include "OLED_types.h" 00007 #include "OpenSans_Font.h" 00008 #include "string.h" 00009 #include "FXOS8700.h" 00010 00011 00012 #define FIFO_DATA_MAX 288 00013 00014 00015 00016 #define LED_ON 0 00017 #define LED_OFF 1 00018 00019 void UpdateSensorData(void); 00020 void StartHaptic(void); 00021 void StopHaptic(void const *n); 00022 void txTask(void); 00023 00024 DigitalOut led1(LED_GREEN); // RGB LED 00025 FXOS8700 accel(PTC11, PTC10); 00026 00027 DigitalOut pwr1v8(PTA29); 00028 DigitalOut pwr3v3b(PTC13); 00029 DigitalOut pwr15v(PTB12); 00030 I2C i2c0(PTB1, PTB0); 00031 InterruptIn maximInterrupt(PTB18); 00032 Serial pc(USBTX, USBRX); 00033 00034 DigitalOut redLed(LED1,1); 00035 DigitalOut greenLed(LED2,1); 00036 DigitalOut blueLed(LED3,1); 00037 DigitalOut haptic(PTB9); 00038 00039 00040 RtosTimer hapticTimer(StopHaptic, osTimerOnce); 00041 00042 /* Instantiate the Hexi KW40Z Driver (UART TX, UART RX) */ 00043 KW40Z kw40z_device(PTE24, PTE25); 00044 00045 /* Instantiate the SSD1351 OLED Driver */ 00046 SSD1351 oled(PTB22,PTB21,PTC13,PTB20,PTE6, PTD15); /* (MOSI,SCLK,POWER,CS,RST,DC) */ 00047 00048 /*Create a Thread to handle sending BLE Sensor Data */ 00049 Thread txThread; 00050 00051 EventQueue evqueue(32 * EVENTS_EVENT_SIZE); 00052 Thread t; 00053 00054 MAX30101 hr(i2c0); 00055 00056 int mask_ppg = 0; 00057 uint32_t count = 0; 00058 00059 00060 00061 char text[20]; 00062 00063 uint8_t battery = 100; 00064 uint8_t light = 0; 00065 uint16_t humidity = 4500; 00066 uint16_t temperature = 2000; 00067 uint16_t pressure = 9000; 00068 uint16_t x = 0; 00069 uint16_t y = 5000; 00070 uint16_t z = 10000; 00071 00072 // Variables 00073 float accel_data[3]; // Storage for the data from the sensor 00074 float accel_rms=0.0; // RMS value from the sensor 00075 float ax, ay, az; // Integer value from the sensor to be displayed 00076 const uint8_t *image1; // Pointer for the image1 to be displayed 00077 char text1[20]; // Text Buffer for dynamic value displayed 00078 char text2[20]; // Text Buffer for dynamic value displayed 00079 char text3[20]; // Text Buffer for dynamic value displayed 00080 float dot; 00081 float old_acc=0; 00082 float new_acc=0; 00083 float old_accx, old_accy, old_accz, old_dot=0.0; 00084 uint8_t StepNum = 0, StepNumber = 0; 00085 00086 float filter_buf[75]; 00087 00088 /****************************Call Back Functions*******************************/ 00089 00090 float Filter(int s) 00091 { 00092 accel.acquire_accel_data_g(accel_data); 00093 float filter_sum = 0.0; 00094 //printf("%d\n\r",s); 00095 for(int i = 0; i < 75; i++) 00096 { 00097 filter_buf[i] = accel_data[s]; 00098 //printf("%4.2f\n\r",filter_buf[i]); 00099 filter_sum += filter_buf[i]; 00100 } 00101 return (float)(filter_sum / 75); 00102 } 00103 00104 00105 void ButtonRight(void) 00106 { 00107 StartHaptic(); 00108 kw40z_device.ToggleAdvertisementMode(); 00109 } 00110 00111 void ButtonLeft(void) 00112 { 00113 StartHaptic(); 00114 kw40z_device.ToggleAdvertisementMode(); 00115 } 00116 00117 void ButtonUp(void) 00118 { 00119 StartHaptic(); 00120 oled.FillScreen(COLOR_BLACK); 00121 00122 /* Get OLED Class Default Text Properties */ 00123 oled_text_properties_t textProperties = {0}; 00124 oled.GetTextProperties(&textProperties); 00125 00126 /* Change font color to Blue */ 00127 textProperties.fontColor = COLOR_BLUE; 00128 oled.SetTextProperties(&textProperties); 00129 strcpy((char *) text1,"Steps: "); 00130 oled.Label((uint8_t *)text1,3,45); 00131 sprintf(text1,"%d",StepNumber); 00132 /* Display time reading in 35px by 15px textbox at(x=55, y=40) */ 00133 oled.TextBox((uint8_t *)text1,70,45,20,15); //Increase textbox for more digits 00134 00135 00136 } 00137 void ButtonDown(void) 00138 { 00139 oled.FillScreen(COLOR_BLACK); 00140 00141 /* Get OLED Class Default Text Properties */ 00142 oled_text_properties_t textProperties = {0}; 00143 oled.GetTextProperties(&textProperties); 00144 00145 /* Change font color to Blue */ 00146 textProperties.fontColor = COLOR_BLUE; 00147 oled.SetTextProperties(&textProperties); 00148 00149 /* Display Bluetooth Label at x=17,y=65 */ 00150 strcpy((char *) text,"BLUETOOTH"); 00151 oled.Label((uint8_t *)text,17,65); 00152 00153 /* Change font color to white */ 00154 textProperties.fontColor = COLOR_WHITE; 00155 textProperties.alignParam = OLED_TEXT_ALIGN_CENTER; 00156 oled.SetTextProperties(&textProperties); 00157 00158 /* Display Label at x=22,y=80 */ 00159 strcpy((char *) text,"Tap Below"); 00160 oled.Label((uint8_t *)text,22,80); 00161 00162 00163 } 00164 void PassKey(void) 00165 { 00166 StartHaptic(); 00167 strcpy((char *) text,"PAIR CODE"); 00168 oled.TextBox((uint8_t *)text,0,25,95,18); 00169 00170 /* Display Bond Pass Key in a 95px by 18px textbox at x=0,y=40 */ 00171 sprintf(text,"%d", kw40z_device.GetPassKey()); 00172 oled.TextBox((uint8_t *)text,0,40,95,18); 00173 } 00174 00175 // Key modification: use the alert functionality enabled by the host-ble interface 00176 // to define our own command. 00177 void AlertReceived(uint8_t *data, uint8_t length) 00178 { 00179 StartHaptic(); 00180 data[19] = 0; 00181 pc.printf("%s\n\r", data); 00182 00183 // data (our command) must 20 bytes long. 00184 // CMD for turning on: 'ledonledonledonledon' 00185 if (data[4] == 'n') { 00186 greenLed = LED_ON; 00187 redLed = LED_ON; 00188 blueLed = LED_ON; 00189 pc.printf("on\n\r", data); 00190 00191 // CMD for turning off: 'ledoffledoffledoffled' 00192 } else if (data[4] == 'f') { 00193 greenLed = LED_OFF; 00194 redLed = LED_OFF; 00195 blueLed = LED_OFF; 00196 pc.printf("off\n\r", data); 00197 } 00198 } 00199 void interruptHandlerQueued() { 00200 00201 MAX30101::InterruptBitField_u interruptStatus; 00202 hr.getInterruptStatus(interruptStatus); 00203 // printf("Interrupt Status: 0x%02x\r\n", interruptStatus.all); 00204 00205 if (interruptStatus.bits.pwr_rdy == 0x1) { 00206 // printf("Powered on\r\n"); 00207 00208 // Soft reset 00209 MAX30101::ModeConfiguration_u modeConf; 00210 modeConf.all = 0; 00211 modeConf.bits.reset = 1; 00212 hr.setModeConfiguration(modeConf); 00213 wait(0.01); 00214 00215 // Configure FIFO 00216 MAX30101::FIFO_Configuration_u fifoConf; 00217 hr.getFIFOConfiguration(fifoConf); 00218 // pc.printf("FIFO Configuration: 0x%02x\r\n", fifoConf.all); 00219 00220 // Set LED power 00221 hr.setLEDPulseAmplitude(MAX30101::LED1_PA, 0x0C); 00222 hr.setLEDPulseAmplitude(MAX30101::ProxModeLED_PA, 0x19); 00223 // pc.printf("LED set\r\n"); 00224 00225 MAX30101::SpO2Configuration_u spo2Conf; 00226 hr.getSpO2Configuration(spo2Conf); 00227 spo2Conf.bits.led_pw = MAX30101::PW_1; 00228 spo2Conf.bits.spo2_sr = MAX30101::SR_100_Hz; 00229 hr.setSpO2Configuration(spo2Conf); 00230 hr.getSpO2Configuration(spo2Conf); 00231 // pc.printf("SpO2 Configuration: 0x%02x\r\n", spo2Conf.all); 00232 00233 // Proximity settings 00234 hr.setProxIntThreshold(0x14); 00235 00236 // Enable HR mode 00237 modeConf.all = 0; 00238 modeConf.bits.mode = MAX30101::HeartRateMode; 00239 hr.setModeConfiguration(modeConf); 00240 // printf("Mode set\r\n"); 00241 } 00242 00243 if (interruptStatus.bits.prox_int == 0x1) { 00244 // printf("Proximity Triggered, entered HR Mode."); 00245 } 00246 00247 if (interruptStatus.bits.ppg_rdy == 0x1) { 00248 // printf("PPG Ready.\r\n"); 00249 mask_ppg = 1; 00250 } 00251 00252 if (interruptStatus.bits.a_full == 0x1) { 00253 // printf("FIFO Almost Full.\r\n"); 00254 uint8_t data[FIFO_DATA_MAX]; 00255 uint16_t readBytes = 0; 00256 hr.readFIFO(MAX30101::OneLedChannel, data, readBytes); 00257 00258 for (uint16_t i = 0; i < readBytes; i += 3) { 00259 uint8_t sample[4] = {0}; 00260 sample[0] = data[i + 2]; 00261 sample[1] = data[i + 1]; 00262 sample[2] = data[i]; 00263 00264 printf("%u\r\n", *(uint32_t *) sample); 00265 } 00266 } 00267 00268 interruptStatus.all = 0xFF; 00269 if (mask_ppg == 1) { 00270 interruptStatus.bits.ppg_rdy = 0; 00271 } 00272 hr.enableInterrupts(interruptStatus); 00273 } 00274 00275 void interruptHandler() { 00276 evqueue.call(interruptHandlerQueued); 00277 } 00278 00279 // main() runs in its own thread in the OS 00280 int main() { 00281 // printf("Hello world.\r\n"); 00282 00283 t.start(callback(&evqueue, &EventQueue::dispatch_forever)); 00284 accel.accel_config(); 00285 /* Register callbacks to application functions */ 00286 kw40z_device.attach_buttonLeft(&ButtonLeft); 00287 kw40z_device.attach_buttonRight(&ButtonRight); 00288 kw40z_device.attach_buttonDown(&ButtonDown); 00289 kw40z_device.attach_buttonUp(&ButtonUp); 00290 kw40z_device.attach_passkey(&PassKey); 00291 kw40z_device.attach_alert(&AlertReceived); 00292 00293 pc.printf("hello\n\r"); 00294 00295 /* Turn on the backlight of the OLED Display */ 00296 oled.DimScreenON(); 00297 00298 /* Fills the screen with solid black */ 00299 00300 00301 uint8_t prevLinkState = 0; 00302 uint8_t currLinkState = 0; 00303 00304 00305 pwr1v8 = 1; 00306 pwr3v3b = 1; 00307 pwr15v = 0; 00308 00309 maximInterrupt.fall(interruptHandler); 00310 maximInterrupt.enable_irq(); 00311 00312 MAX30101::InterruptBitField_u interruptStatus; 00313 interruptStatus.all = 0xFF; 00314 hr.enableInterrupts(interruptStatus); 00315 00316 00317 txThread.start(txTask); /*Start transmitting Sensor Tag Data */ 00318 00319 while (true) 00320 { 00321 // blueLed = !kw40z_device.GetAdvertisementMode(); /*Indicate BLE Advertisment Mode*/ 00322 Thread::wait(50); 00323 } 00324 00325 return 0; 00326 } 00327 void txTask(void){ 00328 00329 while (true) 00330 { 00331 UpdateSensorData(); 00332 00333 /*Notify Hexiwear App that it is running Sensor Tag mode*/ 00334 kw40z_device.SendSetApplicationMode(GUI_CURRENT_APP_SENSOR_TAG); 00335 00336 /*The following is sending dummy data over BLE. Replace with real data*/ 00337 00338 /*Send Battery Level for 20% */ 00339 kw40z_device.SendBatteryLevel(StepNumber); 00340 00341 /*Send Ambient Light Level at 50% */ 00342 //kw40z_device.SendAmbientLight(light); 00343 00344 /*Send Humidity at 90% */ 00345 //kw40z_device.SendHumidity(humidity); 00346 00347 /*Send Temperature at 25 degrees Celsius */ 00348 //kw40z_device.SendTemperature(temperature); 00349 00350 /*Send Pressure at 100kPA */ 00351 //kw40z_device.SendPressure(pressure); 00352 00353 /*Send Mag,Accel,Gyro Data. */ 00354 // kw40z_device.SendGyro(x,y,z); 00355 // kw40z_device.SendAccel(z,x,y); 00356 // kw40z_device.SendMag(y,z,x); 00357 00358 Thread::wait(10); 00359 } 00360 } 00361 00362 void UpdateSensorData(void) 00363 { 00364 accel.acquire_accel_data_g(accel_data); 00365 //printf("Accelerometer \tX-Axis %4.2f \tY-Axis %4.2f \tZ-Axis %4.2f \tRMS %4.2f\n\r",accel_data[0],accel_data[1],accel_data[2],accel_rms); 00366 ax = Filter(0); 00367 ay = Filter(1); 00368 az = Filter(2); 00369 wait(0.02); 00370 accel_rms = sqrt((ax*ax)+(ay*ay)+(az*az)/3); 00371 //printf("Accelerometer \tX-Axis %4.2f \tY-Axis %4.2f \tZ-Axis %4.2f \tRMS %4.2f\n\r",ax,ay,az,accel_rms); 00372 dot = (old_accx * ax)+(old_accy * ay)+(old_accz * az); 00373 old_acc = abs(sqrt(old_accx*old_accx+old_accy*old_accy+old_accz*old_accz)); 00374 new_acc = abs(sqrt(ax*ax+ay*ay+az*az)); 00375 //printf("\nOld Acceleration: %4.2f\n\r",old_acc); 00376 //printf("New Acceleration: %4.2f\n\r",new_acc); 00377 dot /= (old_acc * new_acc); 00378 //printf("\nDot: %4.2f\n\r",dot); 00379 //printf("Old Dot: %4.2f\n\r",old_dot); 00380 00381 oled_text_properties_t textProperties = {0}; 00382 oled.GetTextProperties(&textProperties); 00383 00384 /* Set text properties to white and right aligned for the dynamic text */ 00385 textProperties.fontColor = COLOR_BLUE; 00386 textProperties.alignParam = OLED_TEXT_ALIGN_LEFT; 00387 oled.SetTextProperties(&textProperties); 00388 00389 /* Display Legends */ 00390 //strcpy((char *) text1,"Steps: "); 00391 //oled.Label((uint8_t *)text1,3,45); 00392 StepNum = StepNumber; 00393 if(abs(dot - old_dot) >= 0.05 && abs(dot - old_dot) <= 0.10) 00394 { 00395 StepNumber += 1; 00396 00397 } 00398 //printf("%4.2f\n\r",dot); 00399 old_accx = ax; 00400 old_accy = ay; 00401 old_accz = az; 00402 old_dot = dot; 00403 00404 Thread::wait(250); 00405 } 00406 00407 00408 void StartHaptic(void) { 00409 hapticTimer.start(50); 00410 haptic = 1; 00411 } 00412 00413 void StopHaptic(void const *n) { 00414 haptic = 0; 00415 hapticTimer.stop(); 00416 } 00417
Generated on Sat Jul 16 2022 21:31:31 by 1.7.2