Wenfei Lu / Mbed OS final_project_ee119

Dependencies:   FXOS8700 Hexi_KW40Z Hexi_OLED_SSD1351 MAX30101

Fork of FINAL_FINAL_FINAL by Trevor Hackett

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers main.cpp Source File

main.cpp

00001 #include "mbed.h"
00002 #include "mbed_events.h"
00003 #include "Hexi_KW40Z.h"
00004 #include "Hexi_OLED_SSD1351.h"
00005 #include "OLED_types.h"
00006 #include "OpenSans_Font.h"
00007 #include "string.h"
00008 #include "FXOS8700.h"
00009 
00010 void StartHaptic(void);
00011 void StopHaptic(void const *n);
00012 float Filter(int s);
00013 void AlertReceived(uint8_t *data, uint8_t length);
00014 void clearScreen();
00015 
00016 void displayString();
00017 void UpdateSensorData(void);
00018 void BTTask(void);
00019 void dataTask(void);
00020 
00021 void ButtonLeft();
00022 void ButtonRight();
00023 void ButtonDown();
00024 void ButtonUp();
00025 void ButtonLeft(void);
00026 
00027 FXOS8700 accel(PTC11, PTC10);
00028 
00029 /* Instantiate the Hexi KW40Z Driver (UART TX, UART RX) */ 
00030 KW40Z kw40z_device(PTE24, PTE25);
00031 
00032 /* Instantiate the SSD1351 OLED Driver */ 
00033 SSD1351 oled(PTB22,PTB21,PTC13,PTB20,PTE6, PTD15);
00034 
00035 RtosTimer hapticTimer(StopHaptic, osTimerOnce);
00036 DigitalOut haptic(PTB9);
00037 
00038 /* Create a Thread to handle sending BLE Sensor Data */ 
00039 Thread bluetoothThread;
00040 Thread dataThread;
00041 
00042 Thread displayThread;
00043 EventQueue displayEventQueue;
00044 
00045 char text[20]; 
00046 
00047 // Variables
00048 float accel_data[3]; // Storage for the data from the sensor
00049 float accel_rms=0.0; // RMS value from the sensor
00050 float ax, ay, az; // Integer value from the sensor to be displayed
00051 const uint8_t *image1; // Pointer for the image1 to be displayed
00052 char text1[20]; // Text Buffer for dynamic value displayed
00053 char text2[20]; // Text Buffer for dynamic value displayed
00054 char text3[20]; // Text Buffer for dynamic value displayed
00055 float dot;
00056 float old_acc=0;
00057 float new_acc=0;
00058 float old_accx, old_accy, old_accz, old_dot=0.0;
00059 uint8_t StepNum = 0, StepNumber = 0;
00060 
00061 float filter_buf[75];
00062 
00063 uint8_t result[1]={0};
00064 
00065 
00066 // variable to assist with viewing the other users' data
00067 char user[2];
00068 char mean[4];
00069 char max[4];
00070 char min[4];
00071 char steps[6];
00072 // boolean flag that says whether or not we've processed new data from pi
00073 // default to true because not data from pi until we ask for it
00074 bool processedReceivedData = true;
00075 
00076 int flag = 0;
00077 int userChosen = flag;
00078 
00079 // main() runs in its own thread in the OS
00080 int main() {
00081     kw40z_device.attach_buttonLeft(&ButtonLeft);
00082     kw40z_device.attach_buttonRight(&ButtonRight);
00083     kw40z_device.attach_buttonDown(&ButtonDown);
00084     kw40z_device.attach_buttonUp(&ButtonUp);
00085     kw40z_device.attach_alert(&AlertReceived);
00086     
00087     accel.accel_config();
00088     
00089     // open up the display queue so that at any point in the program,
00090     // we can put things inside of it and they'll be executed eventually
00091     displayThread.start(callback(&displayEventQueue, &EventQueue::dispatch_forever));
00092     displayEventQueue.call(&clearScreen);
00093     
00094     dataThread.start(BTTask);
00095     bluetoothThread.start(dataTask);
00096     
00097     wait(osWaitForever); 
00098 }
00099 
00100 void BTTask(void){
00101    
00102    while (true) 
00103    {
00104         if (kw40z_device.GetLinkState() == 0) {
00105             kw40z_device.ToggleAdvertisementMode();
00106          }
00107         
00108         /*Notify Hexiwear App that it is running Sensor Tag mode*/
00109         kw40z_device.SendSetApplicationMode(GUI_CURRENT_APP_SENSOR_TAG);
00110         
00111         kw40z_device.SendAlert(result, 2);
00112         kw40z_device.SendBatteryLevel(StepNumber);
00113 
00114         Thread::wait(1000);                 
00115     }
00116 }
00117 
00118 void dataTask(void) {    
00119     while (true) {
00120         if(flag == 1) {
00121             result[1] = 1;
00122             flag = 0;
00123             userChosen = 1;
00124         }
00125         
00126         if(flag == 2) { 
00127             result[1] = 2;
00128             flag = 0;
00129             userChosen = 2;
00130         }
00131         
00132         if(flag == 3){ 
00133             result[1] = 3;
00134             flag = 0;
00135             userChosen = 3;
00136         }
00137         
00138         accel.acquire_accel_data_g(accel_data);
00139         ax = Filter(0);
00140         ay = Filter(1);
00141         az = Filter(2);  
00142         wait(0.02);           
00143         accel_rms = sqrt((ax*ax)+(ay*ay)+(az*az)/3);
00144         dot = (old_accx * ax)+(old_accy * ay)+(old_accz * az);
00145         old_acc = abs(sqrt(old_accx*old_accx+old_accy*old_accy+old_accz*old_accz));
00146         new_acc = abs(sqrt(ax*ax+ay*ay+az*az));
00147         dot /= (old_acc * new_acc);
00148         
00149         /* Display Legends */ 
00150         StepNum = StepNumber;
00151         if(abs(dot - old_dot) >= 0.05 && abs(dot - old_dot) <= 0.10) {
00152             StepNumber += 1;
00153         }
00154         
00155         old_accx = ax;
00156         old_accy = ay;
00157         old_accz = az;
00158         old_dot = dot;
00159         
00160         Thread::wait(250);
00161     }
00162 }
00163 
00164 void StartHaptic(void)  {
00165     hapticTimer.start(50);
00166     haptic = 1;
00167 }
00168 
00169 void StopHaptic(void const *n) {
00170     haptic = 0;
00171     hapticTimer.stop();
00172 }
00173 
00174 float Filter(int s) {
00175     accel.acquire_accel_data_g(accel_data);
00176     float filter_sum = 0.0;
00177     //printf("%d\n\r",s);
00178     for(int i = 0; i < 75; i++) 
00179     {
00180     filter_buf[i] = accel_data[s];
00181     //printf("%4.2f\n\r",filter_buf[i]);
00182     filter_sum += filter_buf[i];
00183     }
00184     return (float)(filter_sum / 75);
00185 }
00186 
00187 // Key modification: use the alert functionality enabled by the host-ble interface
00188 // to define our own command.
00189 void AlertReceived(uint8_t *data, uint8_t length) {
00190     processedReceivedData = false;
00191     
00192     StartHaptic();
00193     data[19] = 0;
00194     
00195     user[0] = '0' + userChosen;
00196     
00197     mean[0] = data[0];
00198     mean[1] = data[1];
00199     mean[2] = data[2];
00200     
00201     max[0] = data[5];
00202     max[1] = data[6];
00203     max[2] = data[7];
00204     
00205     min[0] = data[10];
00206     min[1] = data[11];
00207     min[2] = data[12];
00208     
00209     steps[0] = data[15];
00210     steps[1] = data[16];
00211     steps[2] = data[17];
00212     steps[3] = data[18];
00213     steps[4] = data[19];
00214     
00215     user[1] = 0;
00216     mean[3] = 0;
00217     max[3] = 0;
00218     min[3] = 0;
00219     steps[5] = 0;
00220     
00221     // if you haven't yet processed the data that pi sent
00222     // you in the past, then don't do anything.
00223     
00224     // 2: queue up the displaying of that string
00225     displayEventQueue.call(&displayString);
00226 }
00227 
00228 
00229 /****************************Call Back Functions*******************************/
00230 
00231 // just write the received data to the screen
00232 void displayString() {
00233     if (!processedReceivedData) {
00234         clearScreen();
00235         
00236         processedReceivedData = true;
00237         oled_text_properties_t textProperties = {0};
00238         oled.GetTextProperties(&textProperties);
00239         
00240         textProperties.fontColor   = COLOR_BLUE;
00241         oled.SetTextProperties(&textProperties);
00242         
00243         sprintf(text, "USER: %s\0",user);
00244         oled.Label((uint8_t*)text,0,0);
00245         
00246         sprintf(text, "MEAN HR: %s\0",mean);
00247         oled.Label((uint8_t*)text,0,15);
00248         
00249         sprintf(text, "MAX HR: %s\0",max);
00250         oled.Label((uint8_t*)text,0,30);
00251         
00252         sprintf(text, "MIN HR: %s\0",min);
00253         oled.Label((uint8_t*)text,0,45);
00254         
00255         sprintf(text, "STEPS: %s\0",steps);
00256         oled.Label((uint8_t*)text,0,60);
00257     }
00258 }
00259 
00260 void ButtonUp(void) {
00261     StartHaptic();
00262     flag = 1;
00263 //    processedReceivedData = false;
00264 }
00265 
00266 void ButtonDown(void) {
00267     StartHaptic();
00268     flag = 2;
00269 //    processedReceivedData = false;
00270 }
00271 
00272 void ButtonRight(void) {
00273     StartHaptic();
00274     flag = 3;
00275 //    processedReceivedData = false;
00276 }
00277 
00278 void ButtonLeft(void) {
00279     StartHaptic();
00280     kw40z_device.ToggleAdvertisementMode();
00281 }
00282 
00283 
00284 
00285 // initialize the screen to black
00286 void clearScreen() {    
00287     oled.FillScreen(COLOR_BLACK);
00288 }