Code to be run for the project Group Fitness

Dependencies:   FXOS8700 Hexi_KW40Z Hexi_OLED_SSD1351 MAX30101

Fork of final_project_ee119 by Wenfei Lu

Committer:
aadithyavenkat
Date:
Sun Jun 17 22:01:52 2018 +0000
Revision:
9:c3f399b835ce
Parent:
8:f5a21cfd3833
Added Comments;

Who changed what in which revision?

UserRevisionLine numberNew contents of line
aadithyavenkat 9:c3f399b835ce 1 // Importing the necessary header files for mbed OS, KW40z, OLED screen and
aadithyavenkat 9:c3f399b835ce 2 // FXOS 8700
xihan94 0:33686dd26bf9 3 #include "mbed.h"
xihan94 0:33686dd26bf9 4 #include "mbed_events.h"
catchvibes95 4:eb89733b8642 5 #include "Hexi_KW40Z.h"
catchvibes95 4:eb89733b8642 6 #include "Hexi_OLED_SSD1351.h"
catchvibes95 4:eb89733b8642 7 #include "OLED_types.h"
catchvibes95 4:eb89733b8642 8 #include "OpenSans_Font.h"
catchvibes95 4:eb89733b8642 9 #include "string.h"
catchvibes95 4:eb89733b8642 10 #include "FXOS8700.h"
catchvibes95 4:eb89733b8642 11
aadithyavenkat 9:c3f399b835ce 12
aadithyavenkat 9:c3f399b835ce 13 // Utility functions defined below
angelasnail 6:328ef7a29083 14 void StartHaptic(void);
angelasnail 6:328ef7a29083 15 void StopHaptic(void const *n);
angelasnail 6:328ef7a29083 16 float Filter(int s);
angelasnail 6:328ef7a29083 17 void AlertReceived(uint8_t *data, uint8_t length);
trhackett 7:e5fcb30509ea 18 void clearScreen();
angelasnail 6:328ef7a29083 19
trhackett 7:e5fcb30509ea 20 void displayString();
catchvibes95 4:eb89733b8642 21 void UpdateSensorData(void);
trhackett 7:e5fcb30509ea 22 void BTTask(void);
trhackett 7:e5fcb30509ea 23 void dataTask(void);
trhackett 7:e5fcb30509ea 24
trhackett 7:e5fcb30509ea 25 void ButtonLeft();
trhackett 7:e5fcb30509ea 26 void ButtonRight();
trhackett 7:e5fcb30509ea 27 void ButtonDown();
trhackett 7:e5fcb30509ea 28 void ButtonUp();
trhackett 7:e5fcb30509ea 29 void ButtonLeft(void);
catchvibes95 4:eb89733b8642 30
aadithyavenkat 9:c3f399b835ce 31 /* Instantiate the accelerometer */
aadithyavenkat 9:c3f399b835ce 32
catchvibes95 4:eb89733b8642 33 FXOS8700 accel(PTC11, PTC10);
catchvibes95 4:eb89733b8642 34
catchvibes95 4:eb89733b8642 35 /* Instantiate the Hexi KW40Z Driver (UART TX, UART RX) */
catchvibes95 4:eb89733b8642 36 KW40Z kw40z_device(PTE24, PTE25);
catchvibes95 4:eb89733b8642 37
catchvibes95 4:eb89733b8642 38 /* Instantiate the SSD1351 OLED Driver */
trhackett 7:e5fcb30509ea 39 SSD1351 oled(PTB22,PTB21,PTC13,PTB20,PTE6, PTD15);
trhackett 7:e5fcb30509ea 40
trhackett 7:e5fcb30509ea 41 RtosTimer hapticTimer(StopHaptic, osTimerOnce);
trhackett 7:e5fcb30509ea 42 DigitalOut haptic(PTB9);
catchvibes95 4:eb89733b8642 43
trhackett 7:e5fcb30509ea 44 /* Create a Thread to handle sending BLE Sensor Data */
trhackett 7:e5fcb30509ea 45 Thread bluetoothThread;
trhackett 7:e5fcb30509ea 46 Thread dataThread;
catchvibes95 4:eb89733b8642 47
aadithyavenkat 9:c3f399b835ce 48 /* Create a Thread to handle displaying */
trhackett 7:e5fcb30509ea 49 Thread displayThread;
trhackett 7:e5fcb30509ea 50 EventQueue displayEventQueue;
xihan94 0:33686dd26bf9 51
catchvibes95 4:eb89733b8642 52 char text[20];
catchvibes95 4:eb89733b8642 53
catchvibes95 4:eb89733b8642 54 // Variables
catchvibes95 4:eb89733b8642 55 float accel_data[3]; // Storage for the data from the sensor
catchvibes95 4:eb89733b8642 56 float accel_rms=0.0; // RMS value from the sensor
catchvibes95 4:eb89733b8642 57 float ax, ay, az; // Integer value from the sensor to be displayed
catchvibes95 4:eb89733b8642 58 const uint8_t *image1; // Pointer for the image1 to be displayed
catchvibes95 4:eb89733b8642 59 char text1[20]; // Text Buffer for dynamic value displayed
catchvibes95 4:eb89733b8642 60 char text2[20]; // Text Buffer for dynamic value displayed
catchvibes95 4:eb89733b8642 61 char text3[20]; // Text Buffer for dynamic value displayed
catchvibes95 4:eb89733b8642 62 float dot;
catchvibes95 4:eb89733b8642 63 float old_acc=0;
catchvibes95 4:eb89733b8642 64 float new_acc=0;
catchvibes95 4:eb89733b8642 65 float old_accx, old_accy, old_accz, old_dot=0.0;
catchvibes95 4:eb89733b8642 66 uint8_t StepNum = 0, StepNumber = 0;
catchvibes95 4:eb89733b8642 67
aadithyavenkat 9:c3f399b835ce 68 // Buffer for averaging out the Pedometer data
catchvibes95 4:eb89733b8642 69 float filter_buf[75];
catchvibes95 4:eb89733b8642 70
trhackett 7:e5fcb30509ea 71 uint8_t result[1]={0};
angelasnail 6:328ef7a29083 72
catchvibes95 4:eb89733b8642 73
trhackett 7:e5fcb30509ea 74 // variable to assist with viewing the other users' data
aadithyavenkat 9:c3f399b835ce 75 char user[2];
trhackett 7:e5fcb30509ea 76 char mean[4];
trhackett 7:e5fcb30509ea 77 char max[4];
trhackett 7:e5fcb30509ea 78 char min[4];
trhackett 7:e5fcb30509ea 79 char steps[6];
trhackett 7:e5fcb30509ea 80 // boolean flag that says whether or not we've processed new data from pi
trhackett 7:e5fcb30509ea 81 // default to true because not data from pi until we ask for it
trhackett 7:e5fcb30509ea 82 bool processedReceivedData = true;
catchvibes95 4:eb89733b8642 83
trhackett 7:e5fcb30509ea 84 int flag = 0;
trhackett 7:e5fcb30509ea 85 int userChosen = flag;
catchvibes95 4:eb89733b8642 86
trhackett 5:a2f68bbb5400 87 // main() runs in its own thread in the OS
trhackett 5:a2f68bbb5400 88 int main() {
aadithyavenkat 9:c3f399b835ce 89
aadithyavenkat 9:c3f399b835ce 90 /* Attaching the different functions to the Haptic Buttons*/
trhackett 7:e5fcb30509ea 91 kw40z_device.attach_buttonLeft(&ButtonLeft);
trhackett 7:e5fcb30509ea 92 kw40z_device.attach_buttonRight(&ButtonRight);
trhackett 7:e5fcb30509ea 93 kw40z_device.attach_buttonDown(&ButtonDown);
trhackett 7:e5fcb30509ea 94 kw40z_device.attach_buttonUp(&ButtonUp);
trhackett 7:e5fcb30509ea 95 kw40z_device.attach_alert(&AlertReceived);
trhackett 7:e5fcb30509ea 96
aadithyavenkat 9:c3f399b835ce 97 /* Starting the accelerometer values*/
trhackett 5:a2f68bbb5400 98 accel.accel_config();
catchvibes95 4:eb89733b8642 99
trhackett 7:e5fcb30509ea 100 // open up the display queue so that at any point in the program,
trhackett 7:e5fcb30509ea 101 // we can put things inside of it and they'll be executed eventually
trhackett 7:e5fcb30509ea 102 displayThread.start(callback(&displayEventQueue, &EventQueue::dispatch_forever));
trhackett 7:e5fcb30509ea 103 displayEventQueue.call(&clearScreen);
catchvibes95 4:eb89733b8642 104
aadithyavenkat 9:c3f399b835ce 105 /*Thread start the thread for Handling Bluetooth Events*/
trhackett 7:e5fcb30509ea 106 dataThread.start(BTTask);
trhackett 7:e5fcb30509ea 107 bluetoothThread.start(dataTask);
trhackett 7:e5fcb30509ea 108
trhackett 7:e5fcb30509ea 109 wait(osWaitForever);
catchvibes95 4:eb89733b8642 110 }
xihan94 0:33686dd26bf9 111
aadithyavenkat 9:c3f399b835ce 112 // Function for handling Bluetooth toggling advertisement, send Alert flag and
aadithyavenkat 9:c3f399b835ce 113 // Step numbers
trhackett 7:e5fcb30509ea 114 void BTTask(void){
catchvibes95 4:eb89733b8642 115
catchvibes95 4:eb89733b8642 116 while (true)
catchvibes95 4:eb89733b8642 117 {
angelasnail 6:328ef7a29083 118 if (kw40z_device.GetLinkState() == 0) {
angelasnail 6:328ef7a29083 119 kw40z_device.ToggleAdvertisementMode();
angelasnail 6:328ef7a29083 120 }
angelasnail 6:328ef7a29083 121
catchvibes95 4:eb89733b8642 122 /*Notify Hexiwear App that it is running Sensor Tag mode*/
catchvibes95 4:eb89733b8642 123 kw40z_device.SendSetApplicationMode(GUI_CURRENT_APP_SENSOR_TAG);
angelasnail 6:328ef7a29083 124
angelasnail 6:328ef7a29083 125 kw40z_device.SendAlert(result, 2);
catchvibes95 4:eb89733b8642 126 kw40z_device.SendBatteryLevel(StepNumber);
catchvibes95 4:eb89733b8642 127
trhackett 7:e5fcb30509ea 128 Thread::wait(1000);
catchvibes95 4:eb89733b8642 129 }
catchvibes95 4:eb89733b8642 130 }
catchvibes95 4:eb89733b8642 131
aadithyavenkat 9:c3f399b835ce 132 // Function for setting up the flag to configure different users to different
aadithyavenkat 9:c3f399b835ce 133 // buttons on the Hexiwear and also to compute Pedometer algorithm based on
aadithyavenkat 9:c3f399b835ce 134 // Hexiwear data
trhackett 7:e5fcb30509ea 135 void dataTask(void) {
trhackett 7:e5fcb30509ea 136 while (true) {
trhackett 7:e5fcb30509ea 137 if(flag == 1) {
trhackett 7:e5fcb30509ea 138 result[1] = 1;
trhackett 7:e5fcb30509ea 139 flag = 0;
trhackett 7:e5fcb30509ea 140 userChosen = 1;
trhackett 7:e5fcb30509ea 141 }
trhackett 7:e5fcb30509ea 142
trhackett 7:e5fcb30509ea 143 if(flag == 2) {
trhackett 7:e5fcb30509ea 144 result[1] = 2;
trhackett 7:e5fcb30509ea 145 flag = 0;
trhackett 7:e5fcb30509ea 146 userChosen = 2;
trhackett 7:e5fcb30509ea 147 }
trhackett 7:e5fcb30509ea 148
trhackett 7:e5fcb30509ea 149 if(flag == 3){
trhackett 7:e5fcb30509ea 150 result[1] = 3;
trhackett 7:e5fcb30509ea 151 flag = 0;
trhackett 7:e5fcb30509ea 152 userChosen = 3;
trhackett 7:e5fcb30509ea 153 }
trhackett 7:e5fcb30509ea 154
trhackett 7:e5fcb30509ea 155 accel.acquire_accel_data_g(accel_data);
trhackett 7:e5fcb30509ea 156 ax = Filter(0);
trhackett 7:e5fcb30509ea 157 ay = Filter(1);
trhackett 7:e5fcb30509ea 158 az = Filter(2);
trhackett 7:e5fcb30509ea 159 wait(0.02);
trhackett 7:e5fcb30509ea 160 accel_rms = sqrt((ax*ax)+(ay*ay)+(az*az)/3);
trhackett 7:e5fcb30509ea 161 dot = (old_accx * ax)+(old_accy * ay)+(old_accz * az);
trhackett 7:e5fcb30509ea 162 old_acc = abs(sqrt(old_accx*old_accx+old_accy*old_accy+old_accz*old_accz));
trhackett 7:e5fcb30509ea 163 new_acc = abs(sqrt(ax*ax+ay*ay+az*az));
trhackett 7:e5fcb30509ea 164 dot /= (old_acc * new_acc);
trhackett 7:e5fcb30509ea 165
trhackett 7:e5fcb30509ea 166 /* Display Legends */
trhackett 7:e5fcb30509ea 167 StepNum = StepNumber;
trhackett 7:e5fcb30509ea 168 if(abs(dot - old_dot) >= 0.05 && abs(dot - old_dot) <= 0.10) {
trhackett 7:e5fcb30509ea 169 StepNumber += 1;
trhackett 7:e5fcb30509ea 170 }
trhackett 7:e5fcb30509ea 171
trhackett 7:e5fcb30509ea 172 old_accx = ax;
trhackett 7:e5fcb30509ea 173 old_accy = ay;
trhackett 7:e5fcb30509ea 174 old_accz = az;
trhackett 7:e5fcb30509ea 175 old_dot = dot;
trhackett 7:e5fcb30509ea 176
trhackett 7:e5fcb30509ea 177 Thread::wait(250);
angelasnail 6:328ef7a29083 178 }
angelasnail 6:328ef7a29083 179 }
angelasnail 6:328ef7a29083 180
angelasnail 6:328ef7a29083 181 void StartHaptic(void) {
angelasnail 6:328ef7a29083 182 hapticTimer.start(50);
angelasnail 6:328ef7a29083 183 haptic = 1;
angelasnail 6:328ef7a29083 184 }
angelasnail 6:328ef7a29083 185
angelasnail 6:328ef7a29083 186 void StopHaptic(void const *n) {
angelasnail 6:328ef7a29083 187 haptic = 0;
angelasnail 6:328ef7a29083 188 hapticTimer.stop();
angelasnail 6:328ef7a29083 189 }
angelasnail 6:328ef7a29083 190
angelasnail 6:328ef7a29083 191 float Filter(int s) {
angelasnail 6:328ef7a29083 192 accel.acquire_accel_data_g(accel_data);
angelasnail 6:328ef7a29083 193 float filter_sum = 0.0;
angelasnail 6:328ef7a29083 194 //printf("%d\n\r",s);
angelasnail 6:328ef7a29083 195 for(int i = 0; i < 75; i++)
angelasnail 6:328ef7a29083 196 {
angelasnail 6:328ef7a29083 197 filter_buf[i] = accel_data[s];
angelasnail 6:328ef7a29083 198 //printf("%4.2f\n\r",filter_buf[i]);
angelasnail 6:328ef7a29083 199 filter_sum += filter_buf[i];
angelasnail 6:328ef7a29083 200 }
angelasnail 6:328ef7a29083 201 return (float)(filter_sum / 75);
angelasnail 6:328ef7a29083 202 }
angelasnail 6:328ef7a29083 203
angelasnail 6:328ef7a29083 204 // Key modification: use the alert functionality enabled by the host-ble interface
aadithyavenkat 9:c3f399b835ce 205 // to define our own command to display different user's data
angelasnail 6:328ef7a29083 206 void AlertReceived(uint8_t *data, uint8_t length) {
angelasnail 8:f5a21cfd3833 207 processedReceivedData = false;
angelasnail 6:328ef7a29083 208
angelasnail 6:328ef7a29083 209 StartHaptic();
angelasnail 6:328ef7a29083 210 data[19] = 0;
angelasnail 6:328ef7a29083 211
angelasnail 6:328ef7a29083 212 user[0] = '0' + userChosen;
angelasnail 6:328ef7a29083 213
angelasnail 6:328ef7a29083 214 mean[0] = data[0];
angelasnail 6:328ef7a29083 215 mean[1] = data[1];
angelasnail 6:328ef7a29083 216 mean[2] = data[2];
angelasnail 6:328ef7a29083 217
angelasnail 6:328ef7a29083 218 max[0] = data[5];
angelasnail 6:328ef7a29083 219 max[1] = data[6];
angelasnail 6:328ef7a29083 220 max[2] = data[7];
angelasnail 6:328ef7a29083 221
angelasnail 6:328ef7a29083 222 min[0] = data[10];
angelasnail 6:328ef7a29083 223 min[1] = data[11];
angelasnail 6:328ef7a29083 224 min[2] = data[12];
angelasnail 6:328ef7a29083 225
angelasnail 6:328ef7a29083 226 steps[0] = data[15];
angelasnail 6:328ef7a29083 227 steps[1] = data[16];
angelasnail 6:328ef7a29083 228 steps[2] = data[17];
angelasnail 6:328ef7a29083 229 steps[3] = data[18];
angelasnail 6:328ef7a29083 230 steps[4] = data[19];
angelasnail 6:328ef7a29083 231
angelasnail 6:328ef7a29083 232 user[1] = 0;
angelasnail 6:328ef7a29083 233 mean[3] = 0;
angelasnail 6:328ef7a29083 234 max[3] = 0;
angelasnail 6:328ef7a29083 235 min[3] = 0;
angelasnail 6:328ef7a29083 236 steps[5] = 0;
angelasnail 6:328ef7a29083 237
angelasnail 6:328ef7a29083 238 // if you haven't yet processed the data that pi sent
angelasnail 6:328ef7a29083 239 // you in the past, then don't do anything.
angelasnail 6:328ef7a29083 240
angelasnail 6:328ef7a29083 241 // 2: queue up the displaying of that string
angelasnail 6:328ef7a29083 242 displayEventQueue.call(&displayString);
trhackett 7:e5fcb30509ea 243 }
trhackett 7:e5fcb30509ea 244
trhackett 7:e5fcb30509ea 245
trhackett 7:e5fcb30509ea 246 /****************************Call Back Functions*******************************/
trhackett 7:e5fcb30509ea 247
trhackett 7:e5fcb30509ea 248 // just write the received data to the screen
trhackett 7:e5fcb30509ea 249 void displayString() {
trhackett 7:e5fcb30509ea 250 if (!processedReceivedData) {
trhackett 7:e5fcb30509ea 251 clearScreen();
trhackett 7:e5fcb30509ea 252
trhackett 7:e5fcb30509ea 253 processedReceivedData = true;
trhackett 7:e5fcb30509ea 254 oled_text_properties_t textProperties = {0};
trhackett 7:e5fcb30509ea 255 oled.GetTextProperties(&textProperties);
trhackett 7:e5fcb30509ea 256
trhackett 7:e5fcb30509ea 257 textProperties.fontColor = COLOR_BLUE;
trhackett 7:e5fcb30509ea 258 oled.SetTextProperties(&textProperties);
trhackett 7:e5fcb30509ea 259
trhackett 7:e5fcb30509ea 260 sprintf(text, "USER: %s\0",user);
trhackett 7:e5fcb30509ea 261 oled.Label((uint8_t*)text,0,0);
trhackett 7:e5fcb30509ea 262
trhackett 7:e5fcb30509ea 263 sprintf(text, "MEAN HR: %s\0",mean);
trhackett 7:e5fcb30509ea 264 oled.Label((uint8_t*)text,0,15);
trhackett 7:e5fcb30509ea 265
trhackett 7:e5fcb30509ea 266 sprintf(text, "MAX HR: %s\0",max);
trhackett 7:e5fcb30509ea 267 oled.Label((uint8_t*)text,0,30);
trhackett 7:e5fcb30509ea 268
trhackett 7:e5fcb30509ea 269 sprintf(text, "MIN HR: %s\0",min);
trhackett 7:e5fcb30509ea 270 oled.Label((uint8_t*)text,0,45);
trhackett 7:e5fcb30509ea 271
trhackett 7:e5fcb30509ea 272 sprintf(text, "STEPS: %s\0",steps);
trhackett 7:e5fcb30509ea 273 oled.Label((uint8_t*)text,0,60);
trhackett 7:e5fcb30509ea 274 }
trhackett 7:e5fcb30509ea 275 }
trhackett 7:e5fcb30509ea 276
trhackett 7:e5fcb30509ea 277 void ButtonUp(void) {
trhackett 7:e5fcb30509ea 278 StartHaptic();
trhackett 7:e5fcb30509ea 279 flag = 1;
angelasnail 8:f5a21cfd3833 280 // processedReceivedData = false;
trhackett 7:e5fcb30509ea 281 }
trhackett 7:e5fcb30509ea 282
trhackett 7:e5fcb30509ea 283 void ButtonDown(void) {
trhackett 7:e5fcb30509ea 284 StartHaptic();
trhackett 7:e5fcb30509ea 285 flag = 2;
angelasnail 8:f5a21cfd3833 286 // processedReceivedData = false;
trhackett 7:e5fcb30509ea 287 }
trhackett 7:e5fcb30509ea 288
trhackett 7:e5fcb30509ea 289 void ButtonRight(void) {
trhackett 7:e5fcb30509ea 290 StartHaptic();
trhackett 7:e5fcb30509ea 291 flag = 3;
angelasnail 8:f5a21cfd3833 292 // processedReceivedData = false;
trhackett 7:e5fcb30509ea 293 }
trhackett 7:e5fcb30509ea 294
trhackett 7:e5fcb30509ea 295 void ButtonLeft(void) {
trhackett 7:e5fcb30509ea 296 StartHaptic();
trhackett 7:e5fcb30509ea 297 kw40z_device.ToggleAdvertisementMode();
trhackett 7:e5fcb30509ea 298 }
trhackett 7:e5fcb30509ea 299
trhackett 7:e5fcb30509ea 300
trhackett 7:e5fcb30509ea 301
trhackett 7:e5fcb30509ea 302 // initialize the screen to black
trhackett 7:e5fcb30509ea 303 void clearScreen() {
trhackett 7:e5fcb30509ea 304 oled.FillScreen(COLOR_BLACK);
trhackett 5:a2f68bbb5400 305 }