Code for the Hexiwear sensor system. Requires an Air Quality Click, Carbon Monoxide Click, and Buzzer Click for full functionality. Currently only reads values and displays to the OLED while testing and alerting the user of present threats. Future goals are to incorporate button presses with separate screens to display the data as well as using the KW40 drivers to transmit the data. Still in early stages of development, many unnecessary files will be removed and cleaned up once final product is completed within the next month. Driver.cpp is the main driver for the program and was written for purposes of this project. All other headers and functions were found on mbed.org from other developers repositories or provided by NXP Semiconductors for purposes of this project.

Dependencies:   Hexi_KW40Z images

Committer:
Gfolker
Date:
Mon Mar 27 17:36:47 2017 +0000
Revision:
1:8ab4a1e27785
Parent:
0:f70b1d60f794
Child:
2:aa8c291b3f9a
This revision includes the changes to the user interface including the button presses and transition screens

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Gfolker 0:f70b1d60f794 1 #include "mbed.h"
Gfolker 0:f70b1d60f794 2 #include "pwm_tone.h" /* Tone library for Buzzer Click */
Gfolker 0:f70b1d60f794 3 #include "Hexi_OLED_SSD1351.h" /* Header file for OLED Display */
Gfolker 0:f70b1d60f794 4 #include "string.h"
Gfolker 0:f70b1d60f794 5 #include "Hexi_KW40Z.h" /* Driver for button presses and BLE */
Gfolker 0:f70b1d60f794 6 #include <math.h> /* Used for ADC conversion algorithm */
Gfolker 1:8ab4a1e27785 7 #include "images.h" /* BMPs of the images drawn to the OLED */
Gfolker 0:f70b1d60f794 8
Gfolker 0:f70b1d60f794 9 /*****Function Prototypes*****/
Gfolker 0:f70b1d60f794 10 void readSensors();
Gfolker 0:f70b1d60f794 11 void ledColor();
Gfolker 0:f70b1d60f794 12 void led_out();
Gfolker 0:f70b1d60f794 13 void buzzer();
Gfolker 0:f70b1d60f794 14 void CalculatePPM();
Gfolker 1:8ab4a1e27785 15 void dataQueue();
Gfolker 1:8ab4a1e27785 16 void initModules();
Gfolker 1:8ab4a1e27785 17 void StartHaptic(void);
Gfolker 1:8ab4a1e27785 18 void StopHaptic(void const *n);
Gfolker 0:f70b1d60f794 19
Gfolker 0:f70b1d60f794 20 PwmOut Buzzer(PTA10); /* Buzzer is attached to docking station port 1 */
Gfolker 0:f70b1d60f794 21 AnalogIn AQSensor(PTB3); /* Air Quality sensor is attached to docking station port 2 */
Gfolker 0:f70b1d60f794 22 AnalogIn COSensor(PTB6); /* Carbon Monoxide sensor is attached to docking station port 3 */
Gfolker 0:f70b1d60f794 23
Gfolker 1:8ab4a1e27785 24 /* Instantiate the SSD1351 OLED Driver */
Gfolker 1:8ab4a1e27785 25 SSD1351 oled(PTB22,PTB21,PTC13,PTB20,PTE6, PTD15);
Gfolker 1:8ab4a1e27785 26
Gfolker 0:f70b1d60f794 27 BusOut led(PTC8, PTD0, PTC9); /* RGB Port Configurations */
Gfolker 1:8ab4a1e27785 28 DigitalOut haptic(PTB9); /* Port Configuration for vibrations */
Gfolker 1:8ab4a1e27785 29 /* Define timer for haptic feedback */
Gfolker 1:8ab4a1e27785 30 RtosTimer hapticTimer(StopHaptic, osTimerOnce);
Gfolker 1:8ab4a1e27785 31
Gfolker 1:8ab4a1e27785 32 int screen = 1; //detects which screen the user is currently on
Gfolker 1:8ab4a1e27785 33 bool is_drawn1 = 0; //detects if the screen is already drawn to the screen
Gfolker 1:8ab4a1e27785 34 bool is_drawn2 = 0;
Gfolker 1:8ab4a1e27785 35 bool is_drawn3 = 0;
Gfolker 1:8ab4a1e27785 36
Gfolker 1:8ab4a1e27785 37 /* Screens */
Gfolker 1:8ab4a1e27785 38 const uint8_t *image1;
Gfolker 1:8ab4a1e27785 39 //image1 = homescreen_bmp;
Gfolker 1:8ab4a1e27785 40
Gfolker 1:8ab4a1e27785 41 const uint8_t *image2;
Gfolker 1:8ab4a1e27785 42 //image2 = airquality_bmp;
Gfolker 1:8ab4a1e27785 43
Gfolker 1:8ab4a1e27785 44 const uint8_t *image3;
Gfolker 1:8ab4a1e27785 45 //image3 = co_bmp;
Gfolker 0:f70b1d60f794 46
Gfolker 0:f70b1d60f794 47 const int green = 5,
Gfolker 0:f70b1d60f794 48 red = 6, /* LED Colors */
Gfolker 0:f70b1d60f794 49 black = 7,
Gfolker 0:f70b1d60f794 50 yellow = 4;
Gfolker 0:f70b1d60f794 51
Gfolker 0:f70b1d60f794 52 bool is_sounding = false; /* Set to high if the buzzer is going off */
Gfolker 0:f70b1d60f794 53
Gfolker 0:f70b1d60f794 54 int led_color; /* Variable to hold the current LED color */
Gfolker 0:f70b1d60f794 55
Gfolker 0:f70b1d60f794 56 Ticker sensor_read, /* Used for the read sensor subroutine call */
Gfolker 0:f70b1d60f794 57 buzzer_sound, /* Used for the sound buzzer subroutine call */
Gfolker 0:f70b1d60f794 58 led_flash, /* Used to determine the flash rate */
Gfolker 0:f70b1d60f794 59 ledcolor, /* Used to determine the LED color */
Gfolker 1:8ab4a1e27785 60 A2D_Convert, /* Used to convert the analog signal to digital */
Gfolker 1:8ab4a1e27785 61 push; /* Used to push values into the data array */
Gfolker 0:f70b1d60f794 62
Gfolker 0:f70b1d60f794 63 float B_4 = 1000000/Ti4, /* Tones that will play on the buzzer click */
Gfolker 0:f70b1d60f794 64 B_5 = 1000000/Ti5;
Gfolker 0:f70b1d60f794 65
Gfolker 0:f70b1d60f794 66 char text[20]; /* Static Text Buffer for OLED Display */
Gfolker 0:f70b1d60f794 67 char AQ_level[20]; /* Dynamic Text Buffer for AQ total */
Gfolker 0:f70b1d60f794 68 char CO_level[20]; /* Dynamic Text Buffer for CO total */
Gfolker 0:f70b1d60f794 69 char average[20]; /* Dynamic Text Buffer for the Average total */
Gfolker 0:f70b1d60f794 70 char total_total[20]; /* Dynamic Text Buffer for the Total total */
Gfolker 0:f70b1d60f794 71
Gfolker 1:8ab4a1e27785 72 /* Either unit16_t or double */
Gfolker 1:8ab4a1e27785 73 double total, /* Variable to store the total total */
Gfolker 1:8ab4a1e27785 74 aq_ppm, /* Variable used to store the AQ PPM */
Gfolker 1:8ab4a1e27785 75 co_ppm; /* Variable used to store the CO PPM */
Gfolker 0:f70b1d60f794 76
Gfolker 0:f70b1d60f794 77 uint16_t aq_total, /* Variable to store the AQ total */
Gfolker 1:8ab4a1e27785 78 co_total; /* Variable to store the CO total */
Gfolker 1:8ab4a1e27785 79
Gfolker 1:8ab4a1e27785 80 /* Variables to handle the data queue algorithm */
Gfolker 1:8ab4a1e27785 81 const int SIZE = 500;
Gfolker 1:8ab4a1e27785 82 double dataSet [SIZE];
Gfolker 1:8ab4a1e27785 83 int pushIndex = 0;
Gfolker 1:8ab4a1e27785 84 bool calc = false;
Gfolker 1:8ab4a1e27785 85 double avg = 0, sum = 0;
Gfolker 1:8ab4a1e27785 86
Gfolker 1:8ab4a1e27785 87 /* Instantiate the Hexi KW40Z Driver (UART TX, UART RX) */
Gfolker 1:8ab4a1e27785 88 KW40Z kw40z_device(PTE24, PTE25);
Gfolker 1:8ab4a1e27785 89
Gfolker 1:8ab4a1e27785 90 /* Instantiate the SSD1351 OLED Driver */
Gfolker 1:8ab4a1e27785 91 //SSD1351 oled(PTB22,PTB21,PTC13,PTB20,PTE6, PTD15);
Gfolker 1:8ab4a1e27785 92 /* Get OLED Class Default Text Properties */
Gfolker 1:8ab4a1e27785 93 //oled_text_properties_t textProperties = {0};
Gfolker 1:8ab4a1e27785 94 //oled.GetTextProperties(&textProperties);
Gfolker 1:8ab4a1e27785 95
Gfolker 1:8ab4a1e27785 96 /* Below are the functions to handle button presses and screens */
Gfolker 1:8ab4a1e27785 97
Gfolker 1:8ab4a1e27785 98 void ButtonRight(void)//CO screen button
Gfolker 1:8ab4a1e27785 99 {
Gfolker 1:8ab4a1e27785 100 screen = 3;
Gfolker 1:8ab4a1e27785 101 //StartHaptic();
Gfolker 1:8ab4a1e27785 102
Gfolker 1:8ab4a1e27785 103 //oled.DrawImage(image3,0,0);
Gfolker 1:8ab4a1e27785 104
Gfolker 1:8ab4a1e27785 105 /* Get OLED Class Default Text Properties */
Gfolker 1:8ab4a1e27785 106 //oled_text_properties_t textProperties = {0};
Gfolker 1:8ab4a1e27785 107 //oled.GetTextProperties(&textProperties);
Gfolker 1:8ab4a1e27785 108
Gfolker 1:8ab4a1e27785 109 //textProperties.fontColor = COLOR_WHITE;
Gfolker 1:8ab4a1e27785 110 //textProperties.alignParam = OLED_TEXT_ALIGN_RIGHT;
Gfolker 1:8ab4a1e27785 111 //oled.SetTextProperties(&textProperties);
Gfolker 1:8ab4a1e27785 112 }
Gfolker 1:8ab4a1e27785 113
Gfolker 1:8ab4a1e27785 114 void ButtonLeft(void)//AQ screen button
Gfolker 1:8ab4a1e27785 115 {
Gfolker 1:8ab4a1e27785 116 screen = 2;
Gfolker 1:8ab4a1e27785 117 //StartHaptic();
Gfolker 1:8ab4a1e27785 118
Gfolker 1:8ab4a1e27785 119 //oled.DrawImage(image2,0,0);
Gfolker 1:8ab4a1e27785 120
Gfolker 1:8ab4a1e27785 121 /* Get OLED Class Default Text Properties */
Gfolker 1:8ab4a1e27785 122 //oled_text_properties_t textProperties = {0};
Gfolker 1:8ab4a1e27785 123 //oled.GetTextProperties(&textProperties);
Gfolker 1:8ab4a1e27785 124
Gfolker 1:8ab4a1e27785 125 //textProperties.fontColor = COLOR_WHITE;
Gfolker 1:8ab4a1e27785 126 //textProperties.alignParam = OLED_TEXT_ALIGN_RIGHT;
Gfolker 1:8ab4a1e27785 127 //oled.SetTextProperties(&textProperties);
Gfolker 1:8ab4a1e27785 128 }
Gfolker 1:8ab4a1e27785 129
Gfolker 1:8ab4a1e27785 130 void ButtonDown(void)//home screen button
Gfolker 1:8ab4a1e27785 131 {
Gfolker 1:8ab4a1e27785 132 screen = 1;
Gfolker 1:8ab4a1e27785 133 //StartHaptic();
Gfolker 1:8ab4a1e27785 134 //const uint8_t *image1;
Gfolker 1:8ab4a1e27785 135 //image1 = homescreen_bmp;
Gfolker 1:8ab4a1e27785 136
Gfolker 1:8ab4a1e27785 137 //oled.DrawImage(image1,0,0);
Gfolker 1:8ab4a1e27785 138
Gfolker 1:8ab4a1e27785 139 /* Get OLED Class Default Text Properties */
Gfolker 1:8ab4a1e27785 140 //oled_text_properties_t textProperties = {0};
Gfolker 1:8ab4a1e27785 141 //oled.GetTextProperties(&textProperties);
Gfolker 1:8ab4a1e27785 142
Gfolker 1:8ab4a1e27785 143 //textProperties.fontColor = COLOR_WHITE;
Gfolker 1:8ab4a1e27785 144 //textProperties.alignParam = OLED_TEXT_ALIGN_RIGHT;
Gfolker 1:8ab4a1e27785 145 //oled.SetTextProperties(&textProperties);
Gfolker 1:8ab4a1e27785 146 }
Gfolker 0:f70b1d60f794 147
Gfolker 0:f70b1d60f794 148 int main(){
Gfolker 0:f70b1d60f794 149
Gfolker 0:f70b1d60f794 150 /* Get OLED Class Default Text Properties */
Gfolker 1:8ab4a1e27785 151 //oled_text_properties_t textProperties = {0};
Gfolker 1:8ab4a1e27785 152 //oled.GetTextProperties(&textProperties);
Gfolker 0:f70b1d60f794 153
Gfolker 0:f70b1d60f794 154 /* Turns on the OLED Display*/
Gfolker 1:8ab4a1e27785 155 //oled.PowerON();
Gfolker 1:8ab4a1e27785 156
Gfolker 1:8ab4a1e27785 157 // const uint8_t *image1;
Gfolker 1:8ab4a1e27785 158 //image1 = homescreen_bmp;
Gfolker 1:8ab4a1e27785 159
Gfolker 1:8ab4a1e27785 160 // oled.DrawImage(image1,0,0);
Gfolker 0:f70b1d60f794 161
Gfolker 0:f70b1d60f794 162 /* Fills the screen with solid black */
Gfolker 1:8ab4a1e27785 163 //oled.FillScreen(COLOR_BLACK);
Gfolker 0:f70b1d60f794 164
Gfolker 0:f70b1d60f794 165 /* Display 'GAS LEVELS' at (x = 13,y = 0) */
Gfolker 1:8ab4a1e27785 166 //strcpy((char *) text,"GAS LEVELS");
Gfolker 1:8ab4a1e27785 167 //oled.Label((uint8_t *)text,13,0);
Gfolker 0:f70b1d60f794 168
Gfolker 0:f70b1d60f794 169 /* Change font color to green for Air Quality */
Gfolker 1:8ab4a1e27785 170 //textProperties.fontColor = COLOR_GREEN;
Gfolker 1:8ab4a1e27785 171 //oled.SetTextProperties(&textProperties);
Gfolker 0:f70b1d60f794 172
Gfolker 0:f70b1d60f794 173 /* Display 'Air Quality: ' at (x = 0, y = 20) */
Gfolker 1:8ab4a1e27785 174 //strcpy(text,"AQ: ");
Gfolker 1:8ab4a1e27785 175 //oled.Label((uint8_t *)text,0,20);
Gfolker 0:f70b1d60f794 176
Gfolker 0:f70b1d60f794 177 /* Change font color to red for Carbon Monoxide */
Gfolker 1:8ab4a1e27785 178 //textProperties.fontColor = COLOR_RED;
Gfolker 1:8ab4a1e27785 179 //oled.SetTextProperties(&textProperties);
Gfolker 0:f70b1d60f794 180
Gfolker 0:f70b1d60f794 181 /* Display 'CO: ' at (x = 0, y = 40) */
Gfolker 1:8ab4a1e27785 182 //strcpy(text, "CO: ");
Gfolker 1:8ab4a1e27785 183 //oled.Label((uint8_t *)text,0,40);
Gfolker 0:f70b1d60f794 184
Gfolker 0:f70b1d60f794 185 /* Change font color to blue for Average and Total total */
Gfolker 1:8ab4a1e27785 186 //textProperties.fontColor = COLOR_BLUE;
Gfolker 1:8ab4a1e27785 187 //oled.SetTextProperties(&textProperties);
Gfolker 0:f70b1d60f794 188
Gfolker 0:f70b1d60f794 189 /* Display 'Average: ' at (x = 0, y = 60) */
Gfolker 1:8ab4a1e27785 190 //strcpy(text, "Average: ");
Gfolker 1:8ab4a1e27785 191 //oled.Label((uint8_t *)text, 0, 60);
Gfolker 0:f70b1d60f794 192
Gfolker 0:f70b1d60f794 193 /* Display 'Total: ' at (x = 0, y = 80) */
Gfolker 1:8ab4a1e27785 194 //strcpy(text, "Total: ");
Gfolker 1:8ab4a1e27785 195 //oled.Label((uint8_t *)text,0,80);
Gfolker 0:f70b1d60f794 196
Gfolker 0:f70b1d60f794 197 /* Set text properties to white and right aligned for the dynamic text */
Gfolker 1:8ab4a1e27785 198 //textProperties.fontColor = COLOR_WHITE;
Gfolker 1:8ab4a1e27785 199 //textProperties.alignParam = OLED_TEXT_ALIGN_RIGHT;
Gfolker 1:8ab4a1e27785 200 //oled.SetTextProperties(&textProperties);
Gfolker 1:8ab4a1e27785 201
Gfolker 1:8ab4a1e27785 202 initModules();
Gfolker 0:f70b1d60f794 203
Gfolker 0:f70b1d60f794 204 /* Subroutine Calls */
Gfolker 1:8ab4a1e27785 205 //sensor_read.attach(&readSensors, 1); /* Read the sensor on a time interval */
Gfolker 1:8ab4a1e27785 206 //A2D_Convert.attach(&CalculatePPM, 1); /* Convert the values read from the sensors to floating point ppm values */
Gfolker 1:8ab4a1e27785 207 //push.attach(&dataQueue, 1); /* Push the value into the set and compute the average */
Gfolker 0:f70b1d60f794 208 ledcolor.attach(&ledColor, 0.5); /* Determine the LED color */
Gfolker 0:f70b1d60f794 209 led_flash.attach(&led_out, 0.25); /* Flash LED based on sensor data */
Gfolker 0:f70b1d60f794 210 buzzer_sound.attach(&buzzer, 0.25); /* Sensor values are sent to buzzer function */
Gfolker 0:f70b1d60f794 211
Gfolker 1:8ab4a1e27785 212 /* Register callbacks to button presses */
Gfolker 1:8ab4a1e27785 213 kw40z_device.attach_buttonDown(&ButtonDown);
Gfolker 1:8ab4a1e27785 214 kw40z_device.attach_buttonLeft(&ButtonLeft);
Gfolker 1:8ab4a1e27785 215 kw40z_device.attach_buttonRight(&ButtonRight);
Gfolker 1:8ab4a1e27785 216
Gfolker 1:8ab4a1e27785 217 while (1) { /* Loop to display data to the OLED */
Gfolker 1:8ab4a1e27785 218
Gfolker 1:8ab4a1e27785 219 /* Get OLED Class Default Text Properties */
Gfolker 1:8ab4a1e27785 220 oled_text_properties_t textProperties = {0};
Gfolker 1:8ab4a1e27785 221 oled.GetTextProperties(&textProperties);
Gfolker 0:f70b1d60f794 222
Gfolker 1:8ab4a1e27785 223 /* Set text properties to white and right aligned for the dynamic text */
Gfolker 1:8ab4a1e27785 224 textProperties.fontColor = COLOR_WHITE;
Gfolker 1:8ab4a1e27785 225 textProperties.alignParam = OLED_TEXT_ALIGN_RIGHT;
Gfolker 1:8ab4a1e27785 226 oled.SetTextProperties(&textProperties);
Gfolker 1:8ab4a1e27785 227
Gfolker 1:8ab4a1e27785 228 readSensors();
Gfolker 1:8ab4a1e27785 229 CalculatePPM();
Gfolker 1:8ab4a1e27785 230 dataQueue();
Gfolker 1:8ab4a1e27785 231 //ledColor();
Gfolker 1:8ab4a1e27785 232 //led_out();
Gfolker 1:8ab4a1e27785 233 //buzzer();
Gfolker 1:8ab4a1e27785 234 if (screen == 2){ //Air Quality Screen
Gfolker 1:8ab4a1e27785 235 is_drawn1 = 0;
Gfolker 1:8ab4a1e27785 236 is_drawn3 = 0;
Gfolker 1:8ab4a1e27785 237 if(!is_drawn2){
Gfolker 1:8ab4a1e27785 238 oled.DrawImage(image2,0,0);
Gfolker 1:8ab4a1e27785 239 is_drawn2 = 1;
Gfolker 1:8ab4a1e27785 240 }
Gfolker 1:8ab4a1e27785 241 sprintf(AQ_level,"%.2f",aq_ppm); /* Print the AQ PPM to the screen */
Gfolker 1:8ab4a1e27785 242 oled.TextBox((uint8_t *)AQ_level,35,76,35,15);
Gfolker 1:8ab4a1e27785 243 }
Gfolker 1:8ab4a1e27785 244 else if (screen == 3){ //Carbon Monoxide Screen
Gfolker 1:8ab4a1e27785 245 is_drawn2 = 0;
Gfolker 1:8ab4a1e27785 246 is_drawn1 = 0;
Gfolker 1:8ab4a1e27785 247 if (!is_drawn3){
Gfolker 1:8ab4a1e27785 248 oled.DrawImage(image3,0,0);
Gfolker 1:8ab4a1e27785 249 is_drawn3 = 1;
Gfolker 1:8ab4a1e27785 250 }
Gfolker 1:8ab4a1e27785 251 sprintf(CO_level,"%.2f",co_ppm); /* Print the CO PPM to the screen */
Gfolker 1:8ab4a1e27785 252 oled.TextBox((uint8_t *)CO_level,35,76,35,15);
Gfolker 1:8ab4a1e27785 253 }
Gfolker 1:8ab4a1e27785 254 else if (screen == 1) { //Home Screen
Gfolker 1:8ab4a1e27785 255 is_drawn3 = 0;
Gfolker 1:8ab4a1e27785 256 is_drawn2 = 0;
Gfolker 1:8ab4a1e27785 257 if (!is_drawn1){
Gfolker 1:8ab4a1e27785 258 oled.DrawImage(image1,0,0);
Gfolker 1:8ab4a1e27785 259 is_drawn1 = 1;
Gfolker 1:8ab4a1e27785 260 }
Gfolker 1:8ab4a1e27785 261 sprintf(average, "%.2f", avg); /* Print the average to the screen */
Gfolker 1:8ab4a1e27785 262 oled.TextBox((uint8_t *)average,55,20,35,15);
Gfolker 1:8ab4a1e27785 263 sprintf(total_total, "%.2f", total); /* Print the total to the screen */
Gfolker 1:8ab4a1e27785 264 oled.TextBox((uint8_t *)total_total,55,40,35,15);
Gfolker 1:8ab4a1e27785 265 }
Gfolker 1:8ab4a1e27785 266 Thread::wait(100);
Gfolker 1:8ab4a1e27785 267 }
Gfolker 1:8ab4a1e27785 268
Gfolker 1:8ab4a1e27785 269 return 0;
Gfolker 1:8ab4a1e27785 270 }
Gfolker 1:8ab4a1e27785 271
Gfolker 1:8ab4a1e27785 272 void initModules() { /* Function to initialize the system */
Gfolker 1:8ab4a1e27785 273
Gfolker 1:8ab4a1e27785 274 /* Turns on the OLED Display*/
Gfolker 1:8ab4a1e27785 275 oled.PowerON();
Gfolker 1:8ab4a1e27785 276
Gfolker 1:8ab4a1e27785 277 image1 = homescreen_bmp;
Gfolker 1:8ab4a1e27785 278 image2 = airquality_bmp;
Gfolker 1:8ab4a1e27785 279 image3 = co_bmp;
Gfolker 1:8ab4a1e27785 280
Gfolker 1:8ab4a1e27785 281 //oled.DrawImage(image1,0,0);
Gfolker 1:8ab4a1e27785 282 //screen = 1;
Gfolker 1:8ab4a1e27785 283
Gfolker 1:8ab4a1e27785 284 /* Register callbacks to button presses */
Gfolker 1:8ab4a1e27785 285 //kw40z_device.attach_buttonDown(&ButtonDown);
Gfolker 1:8ab4a1e27785 286 //kw40z_device.attach_buttonLeft(&ButtonLeft);
Gfolker 1:8ab4a1e27785 287 //kw40z_device.attach_buttonRight(&ButtonRight);
Gfolker 1:8ab4a1e27785 288
Gfolker 1:8ab4a1e27785 289 /* Set text properties to white and right aligned for the dynamic text */
Gfolker 1:8ab4a1e27785 290 //textProperties.fontColor = COLOR_WHITE;
Gfolker 1:8ab4a1e27785 291 //textProperties.alignParam = OLED_TEXT_ALIGN_RIGHT;
Gfolker 1:8ab4a1e27785 292 //oled.SetTextProperties(&textProperties);
Gfolker 1:8ab4a1e27785 293
Gfolker 1:8ab4a1e27785 294 /* while (1) {
Gfolker 1:8ab4a1e27785 295 readSensors();
Gfolker 1:8ab4a1e27785 296 CalculatePPM();
Gfolker 1:8ab4a1e27785 297 dataQueue();
Gfolker 1:8ab4a1e27785 298 ledColor();
Gfolker 1:8ab4a1e27785 299 led_out();
Gfolker 1:8ab4a1e27785 300 buzzer();
Gfolker 0:f70b1d60f794 301
Gfolker 0:f70b1d60f794 302 sprintf(average, "%.2f", avg); /* Print the average to the screen */
Gfolker 1:8ab4a1e27785 303
Gfolker 1:8ab4a1e27785 304 /* oled.TextBox((uint8_t *)average,55,20,35,15);
Gfolker 0:f70b1d60f794 305
Gfolker 0:f70b1d60f794 306 sprintf(total_total, "%.2f", total); /* Print the total to the screen */
Gfolker 0:f70b1d60f794 307
Gfolker 1:8ab4a1e27785 308 /* oled.TextBox((uint8_t *)total_total,55,40,35,15);
Gfolker 1:8ab4a1e27785 309 Thread::wait(50); */
Gfolker 1:8ab4a1e27785 310 //}
Gfolker 0:f70b1d60f794 311 }
Gfolker 0:f70b1d60f794 312
Gfolker 0:f70b1d60f794 313 void readSensors(){ /* Function to read sensors */
Gfolker 0:f70b1d60f794 314
Gfolker 0:f70b1d60f794 315 /* Grab the analog signal from the sensors as 16 bit unsigned integers */
Gfolker 0:f70b1d60f794 316 aq_total = AQSensor.read_u16();
Gfolker 0:f70b1d60f794 317 co_total = COSensor.read_u16();
Gfolker 0:f70b1d60f794 318 /* Grab the analog signal from the sensors as floats */
Gfolker 0:f70b1d60f794 319 //aq_total = AQSensor.read();
Gfolker 0:f70b1d60f794 320 //co_total = AQSensor.read();
Gfolker 0:f70b1d60f794 321
Gfolker 0:f70b1d60f794 322 }
Gfolker 0:f70b1d60f794 323
Gfolker 0:f70b1d60f794 324 void ledColor(){ /* Function to determine the LED color */
Gfolker 0:f70b1d60f794 325
Gfolker 1:8ab4a1e27785 326 if ((total - avg) <= 10) {
Gfolker 0:f70b1d60f794 327 led = green;
Gfolker 0:f70b1d60f794 328 led_color = led; /* Store the LED color for the flash function */
Gfolker 0:f70b1d60f794 329 }
Gfolker 1:8ab4a1e27785 330 else if ((total - avg) > 10 && (total - avg) < 50) {
Gfolker 0:f70b1d60f794 331 led = yellow;
Gfolker 0:f70b1d60f794 332 led_color = led; /* Store the LED color for the flash function */
Gfolker 0:f70b1d60f794 333 }
Gfolker 1:8ab4a1e27785 334 else if ((total - avg >= 50) or total >= 100) {
Gfolker 0:f70b1d60f794 335 led = red;
Gfolker 0:f70b1d60f794 336 led_color = led; /* Store the LED color for the flash function */
Gfolker 0:f70b1d60f794 337 }
Gfolker 0:f70b1d60f794 338 }
Gfolker 0:f70b1d60f794 339
Gfolker 0:f70b1d60f794 340 void led_out() { /* Function to flash LEDs */
Gfolker 0:f70b1d60f794 341
Gfolker 0:f70b1d60f794 342 if (led == green) {return;} /* If green, don't blink */
Gfolker 0:f70b1d60f794 343 else if (led == black) {led = led_color;}
Gfolker 0:f70b1d60f794 344 else {led = black;}
Gfolker 0:f70b1d60f794 345
Gfolker 0:f70b1d60f794 346 }
Gfolker 0:f70b1d60f794 347
Gfolker 0:f70b1d60f794 348 void buzzer() { /* Function to handle the buzzer sound */
Gfolker 0:f70b1d60f794 349
Gfolker 1:8ab4a1e27785 350 if ((total - avg) <=25){ /* No buzzer sound if PPM is under 10 */
Gfolker 0:f70b1d60f794 351 Buzzer.period_us(0);
Gfolker 0:f70b1d60f794 352 is_sounding = false;
Gfolker 0:f70b1d60f794 353 }
Gfolker 0:f70b1d60f794 354
Gfolker 1:8ab4a1e27785 355 else if ((total - avg) > 25 and (total - avg) < 50) {
Gfolker 0:f70b1d60f794 356 if (is_sounding == false){ /* If the buzzer is not triggered, trigger */
Gfolker 0:f70b1d60f794 357 Buzzer.period_us(B_4); /* Period of B4 */
Gfolker 0:f70b1d60f794 358 Buzzer.write(0.50f); /* 50% Duty Cycle on the Tone */
Gfolker 0:f70b1d60f794 359 is_sounding = true; /* Signal that the buzzer is currently triggering */
Gfolker 0:f70b1d60f794 360 }
Gfolker 0:f70b1d60f794 361 else {
Gfolker 0:f70b1d60f794 362 Buzzer.period_us(0); /* Turn off the buzzer (Period = 0us)*/
Gfolker 0:f70b1d60f794 363 is_sounding = false; /* Signal that the buzzer is no longer triggering */
Gfolker 0:f70b1d60f794 364 }
Gfolker 0:f70b1d60f794 365 }
Gfolker 0:f70b1d60f794 366
Gfolker 1:8ab4a1e27785 367 else if ((total - avg) >= 50 or total >= 100){
Gfolker 0:f70b1d60f794 368 if (is_sounding == false){
Gfolker 0:f70b1d60f794 369 Buzzer.period_us(B_5); /* Period of B5 */
Gfolker 0:f70b1d60f794 370 Buzzer.write(0.50f); /* 50% Duty Cycle on the Tone */
Gfolker 0:f70b1d60f794 371 is_sounding = true;
Gfolker 0:f70b1d60f794 372 }
Gfolker 0:f70b1d60f794 373 else {
Gfolker 0:f70b1d60f794 374 Buzzer.period_us(0); /* Turn off the buzzer */
Gfolker 0:f70b1d60f794 375 is_sounding = false;
Gfolker 0:f70b1d60f794 376 }
Gfolker 0:f70b1d60f794 377 }
Gfolker 0:f70b1d60f794 378 }
Gfolker 0:f70b1d60f794 379
Gfolker 0:f70b1d60f794 380 void CalculatePPM(){ /* Function to convert the analog signals to digital based on 16 bit adc steps */
Gfolker 0:f70b1d60f794 381
Gfolker 0:f70b1d60f794 382 const double AQ_Rl = 20000.0; // AQ_Rl (20kOhm) - Load resistance for AQ sensor
Gfolker 0:f70b1d60f794 383 const double CO_Rl = 18500.0; // CO_Rl (18.5kOhm) - Load resistance for CO sensor
Gfolker 0:f70b1d60f794 384 const double Vadc_33 = 0.0000503548; // ADC step 3,3V/65535 0.00503mV (16bit ADC)
Gfolker 0:f70b1d60f794 385 //const double Vadc_5 = 5.0/65535; // ADC step 5.0V/2^16 (65535, 16bit ADC)
Gfolker 0:f70b1d60f794 386 double Vrl; // Output voltage
Gfolker 0:f70b1d60f794 387 double Rs; // Rs (Ohm) - Sensor resistance
Gfolker 0:f70b1d60f794 388 double ratio; // Rs/Rl ratio
Gfolker 0:f70b1d60f794 389 double lgPPM;
Gfolker 0:f70b1d60f794 390
Gfolker 0:f70b1d60f794 391 Vrl = (double)aq_total * Vadc_33; // For 3.3V Vcc use Vadc_33
Gfolker 0:f70b1d60f794 392 Rs = AQ_Rl * (3.3 - Vrl)/Vrl; // Calculate sensor resistance
Gfolker 0:f70b1d60f794 393 ratio = Rs/AQ_Rl; // Calculate ratio
Gfolker 1:8ab4a1e27785 394 lgPPM = (log10(ratio) * -0.8) + 0.9;
Gfolker 1:8ab4a1e27785 395 aq_ppm = 6* pow(10,lgPPM) - 12; // Calculate air quality ppm
Gfolker 0:f70b1d60f794 396
Gfolker 0:f70b1d60f794 397 Vrl = (double)co_total * Vadc_33; // For 3.3V Vcc use Vadc_33
Gfolker 0:f70b1d60f794 398 Rs = CO_Rl * (3.3 - Vrl)/Vrl; // Calculate sensor resistance
Gfolker 0:f70b1d60f794 399 ratio = Rs/CO_Rl; // Calculate ratio
Gfolker 1:8ab4a1e27785 400 lgPPM = (log10(ratio) * -0.8) + 0.9;
Gfolker 1:8ab4a1e27785 401 co_ppm = 6* pow(10,lgPPM) - 12; // Calculate carbon monoxide ppm
Gfolker 1:8ab4a1e27785 402
Gfolker 1:8ab4a1e27785 403 if (aq_ppm < 0)
Gfolker 1:8ab4a1e27785 404 aq_ppm = 0; //prevents underflow
Gfolker 1:8ab4a1e27785 405 else if (aq_ppm >= 1000)
Gfolker 1:8ab4a1e27785 406 aq_ppm = 999.99; //prevents overflow
Gfolker 1:8ab4a1e27785 407
Gfolker 1:8ab4a1e27785 408 if (co_ppm <0)
Gfolker 1:8ab4a1e27785 409 co_ppm = 0;
Gfolker 1:8ab4a1e27785 410 else if (co_ppm >= 1000)
Gfolker 1:8ab4a1e27785 411 co_ppm = 999.99;
Gfolker 1:8ab4a1e27785 412
Gfolker 1:8ab4a1e27785 413 /* Calculate the total */
Gfolker 1:8ab4a1e27785 414 total = co_ppm + aq_ppm;
Gfolker 1:8ab4a1e27785 415 if (total < 0)
Gfolker 1:8ab4a1e27785 416 total = 0;
Gfolker 1:8ab4a1e27785 417 else if (total >= 1000)
Gfolker 1:8ab4a1e27785 418 total = 999.99;
Gfolker 1:8ab4a1e27785 419 }
Gfolker 1:8ab4a1e27785 420
Gfolker 1:8ab4a1e27785 421 void dataQueue()
Gfolker 1:8ab4a1e27785 422 { /* Beginning of function */
Gfolker 0:f70b1d60f794 423
Gfolker 1:8ab4a1e27785 424 if (pushIndex != SIZE and !calc){ /* Initially pushing values into the set */
Gfolker 1:8ab4a1e27785 425 dataSet[pushIndex] = total; //push value into the queue
Gfolker 1:8ab4a1e27785 426 sum += dataSet[pushIndex]; //add the value to the sum
Gfolker 1:8ab4a1e27785 427 pushIndex++; //increment the push index
Gfolker 1:8ab4a1e27785 428
Gfolker 1:8ab4a1e27785 429 if (pushIndex == SIZE){
Gfolker 1:8ab4a1e27785 430 avg = sum / SIZE; //compute the average once the queue is full
Gfolker 1:8ab4a1e27785 431 calc = true; //flag calc
Gfolker 1:8ab4a1e27785 432 pushIndex = 0; //reset the push index back to 0
Gfolker 1:8ab4a1e27785 433 }
Gfolker 1:8ab4a1e27785 434 }
Gfolker 1:8ab4a1e27785 435
Gfolker 1:8ab4a1e27785 436 else if (pushIndex != SIZE and calc){ /* Pushing values into the set once the set is full */
Gfolker 1:8ab4a1e27785 437 sum -= dataSet[pushIndex]; //subtract the value to be overriden from the sum
Gfolker 1:8ab4a1e27785 438 dataSet[pushIndex] = total; //push the value into the set
Gfolker 1:8ab4a1e27785 439 sum += dataSet[pushIndex]; //add the value to the sum
Gfolker 1:8ab4a1e27785 440 avg = sum / SIZE;
Gfolker 1:8ab4a1e27785 441 pushIndex++; //increment the push index
Gfolker 1:8ab4a1e27785 442
Gfolker 1:8ab4a1e27785 443 if (pushIndex == SIZE)
Gfolker 1:8ab4a1e27785 444 pushIndex = 0; //reset the push index back to 0
Gfolker 1:8ab4a1e27785 445 }
Gfolker 1:8ab4a1e27785 446
Gfolker 1:8ab4a1e27785 447 } /* End of function */
Gfolker 1:8ab4a1e27785 448
Gfolker 1:8ab4a1e27785 449 void StartHaptic(void)
Gfolker 1:8ab4a1e27785 450 {
Gfolker 1:8ab4a1e27785 451 hapticTimer.start(100);
Gfolker 1:8ab4a1e27785 452 haptic = 1;
Gfolker 1:8ab4a1e27785 453 }
Gfolker 1:8ab4a1e27785 454
Gfolker 1:8ab4a1e27785 455 void StopHaptic(void const *n) {
Gfolker 1:8ab4a1e27785 456 haptic = 0;
Gfolker 1:8ab4a1e27785 457 hapticTimer.stop();
Gfolker 0:f70b1d60f794 458 }