Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: Hexi_KW40Z Hexi_OLED_SSD1351
Fork of Hexi_OLED_Text_Example by
main.cpp
00001 /**************************************************************************** 00002 * Title : iBreathe Breathalyzer 00003 * Filename : breathalyzer 00004 * Author : Dave Clarke 00005 * Origin Date : 27/09/2016 00006 * Notes : Breathalyzer utilizing Hexiware, Alcohol click and Wolksense 00007 *****************************************************************************/ 00008 /**************************CHANGE LIST ************************************** 00009 * 00010 * Date Software Version Initials Description 00011 * 27/09/16 1.0.0 DC Interface Created. 00012 * 00013 *****************************************************************************/ 00014 00015 /** 00016 * @page TEST_CFG Test Configurations 00017 * <h3> Test configuration : </h3> 00018 * @par 00019 * <ul> 00020 * <li><b> MCU </b> : MK64FN1M0XXX12 </li> 00021 * <li><b> Dev. Board </b> : HEXIWEAR </li> 00022 * <li><b> Oscillator </b> : 12 MHz external </li> 00023 * <li><b> Ext. Modules </b> : Alcohol Click on mikroBUS 1 </li> 00024 * <li><b> SW </b> : mBed OS5 </li> 00025 * </ul> 00026 */ 00027 00028 /** 00029 * @mainpage 00030 * <h3> Breathalyser created with HEXIWEAR and mBed OS 5 </h3> 00031 * @par This will show you how much you've drunk and tell you with an Emoticon if 00032 * you're too hammered to even consider driving. Using the Hexiware app the readings 00033 * are transmitted to the cloud via bluetooth. Is it time to give up drinking yet?! 00034 00035 * <h3> Alcohol Features </h3> 00036 * @par Alcohol click, Hexiwear docking station, Hexiware 00037 */ 00038 00039 /****************************************************************************** 00040 * Includes 00041 *******************************************************************************/ 00042 00043 #include "mbed.h" 00044 #include "Hexi_KW40Z.h" 00045 #include "Hexi_OLED_SSD1351.h" 00046 #include "OLED_types.h" 00047 #include "OpenSans_Font.h" 00048 #include "string.h" 00049 #include "iBreatheImages.h" 00050 00051 /****************************************************************************** 00052 * Module Variable Definitions 00053 *******************************************************************************/ 00054 00055 #define LED_ON 0 00056 #define LED_OFF 1 00057 00058 // Pointers to: 00059 const uint8_t *welcome, // Welcome screen image 00060 *blank, // blank image 00061 *blow, // Start Blowing Image 00062 *drink, // You've been drinking image 00063 *drive, // Don't drive image 00064 *hang, // You'll have a hangover image 00065 *ini, // Initialising image 00066 *sober; // Sober as a judge image 00067 00068 const float Vadc_3V3 = 0.00005035; // 16-Bit ADC step 3V3/65535 = 0.05035 mV 00069 00070 float Vrl = 0, // Output voltage 00071 ambientAlc = 0, // Abmient Output voltage from sensor 00072 SensorRes = 0, // SensorRes (Ohm) - Sensor resistance 00073 SensorRes1 = 0, // SensorRes (Ohm) - Sensor resistance 00074 ppm = 0, // ppm 00075 ppm_1 = 0, // Ambient ppm variable 00076 ratio = 0; // SensorRes/LoadRes ratio 00077 00078 unsigned short adc_rd = 0; //Initialise anologue read variable 00079 00080 const uint8_t ppmText[] = "ppm:"; // text for PPM label 00081 00082 char text[20], // Text array variables 00083 text2[20], 00084 text3[20]; 00085 00086 float value[20], // initial sensor set up values 00087 value1[20]; // initial sensor set up values 00088 00089 bool isFirstBoot = true; 00090 00091 00092 /****************************************************************************** 00093 * Function Prototypes 00094 *******************************************************************************/ 00095 00096 void sysinit(void); 00097 void ReadSensor(); 00098 void CalculatePPM(int times, bool amb); 00099 void ambient(int times); 00100 void StartHaptic(void); 00101 void StopHaptic(void const *n); 00102 void ButtonUp(void); 00103 void txTask(void); 00104 00105 /****************************************************************************** 00106 * Instance setups 00107 *******************************************************************************/ 00108 /* Define timer for haptic feedback */ 00109 RtosTimer hapticTimer(StopHaptic, osTimerOnce); 00110 00111 //set up Analog read pin for alcohol sensor 00112 AnalogIn Alcohol(PTB2); 00113 00114 /* Instantiate the SSD1351 OLED Driver */ 00115 SSD1351 oled(PTB22,PTB21,PTC13,PTB20,PTE6, PTD15); /* (MOSI,SCLK,POWER,CS,RST,DC) */ 00116 00117 /* Get OLED Class Default Text Properties */ 00118 oled_text_properties_t textProperties = {0}; 00119 00120 /* Instantiate the Hexi KW40Z Driver (UART TX, UART RX) */ 00121 KW40Z kw40z_device(PTE24, PTE25); 00122 00123 /* LED and Haptic Set ups */ 00124 DigitalOut redLed(LED1); 00125 DigitalOut greenLed(LED2); 00126 DigitalOut blueLed(LED3); 00127 DigitalOut haptic(PTB9); 00128 00129 /****************************************************************************** 00130 * Bluetooth button functions and passkey function 00131 *******************************************************************************/ 00132 00133 void ButtonRight(void) 00134 { 00135 StartHaptic(); 00136 kw40z_device.ToggleAdvertisementMode(); 00137 blueLed = kw40z_device.GetAdvertisementMode(); /*Indicate BLE Advertisment Mode*/ 00138 redLed = !kw40z_device.GetAdvertisementMode(); /*Indicate BLE Advertisment Mode*/ 00139 greenLed = !kw40z_device.GetAdvertisementMode(); /*Indicate BLE Advertisment Mode*/ 00140 } 00141 00142 void ButtonLeft(void) 00143 { 00144 StartHaptic(); 00145 kw40z_device.ToggleAdvertisementMode(); 00146 blueLed = kw40z_device.GetAdvertisementMode(); /*Indicate BLE Advertisment Mode*/ 00147 redLed = !kw40z_device.GetAdvertisementMode(); /*Indicate BLE Advertisment Mode*/ 00148 greenLed = !kw40z_device.GetAdvertisementMode(); /*Indicate BLE Advertisment Mode*/ 00149 } 00150 00151 void PassKey(void) 00152 { 00153 StartHaptic(); 00154 strcpy((char *) text,"PAIR CODE"); 00155 oled.TextBox((uint8_t *)text,0,25,95,18); 00156 00157 /* Display Bond Pass Key in a 95px by 18px textbox at x=0,y=40 */ 00158 sprintf(text3,"%d", kw40z_device.GetPassKey()); 00159 oled.TextBox((uint8_t *)text3,0,40,95,18); 00160 } 00161 00162 /****************************************************************************** 00163 * Main 00164 *******************************************************************************/ 00165 ///////////////////////////////////////////////////////////////////////////////////////////////////////////// 00166 ///////////////////////////////////////////////////////////////////////////////////////////////////////////// 00167 ///////////////////////////////////////////////////////////////////////////////////////////////////////////// 00168 int main() 00169 { 00170 /* Set pointers to the BMPs stored in iBreatheImages.c */ 00171 welcome = iBreatheWS_bmp; // Welcome screen image 00172 blank = iBreatheBlank_bmp; // blank image 00173 blow = iBreatheBlow_bmp; // Start Blowing Image 00174 drink = iBreatheDrink_bmp; // You've been drinking image 00175 drive = iBreatheDrive_bmp; // Don't drive image 00176 hang = iBreatheHang_bmp; // You'll have a hangover image 00177 ini = iBreatheini_bmp; // Initialising image 00178 sober = iBreatheSober_bmp; // Sober as a judge image 00179 00180 /* Set initial Values */ 00181 sysinit(); 00182 } 00183 00184 /****************************************************************************** 00185 * Public Function Definitions 00186 *******************************************************************************/ 00187 ///////////////////////////////////////////////////////////////////////////////////////////////////////////// 00188 ///////////////////////////////////////////////////////////////////////////////////////////////////////////// 00189 ///////////////////////////////////////////////////////////////////////////////////////////////////////////// 00190 /************************************************************************************************** 00191 * Function readSensor(void) 00192 * ------------------------------------------------------------------------------------------------- 00193 * Overview: Read sensor 00194 * Input: None 00195 * Output: None 00196 **************************************************************************************************/ 00197 00198 void ReadSensor() 00199 { 00200 /* Read 16 Bit Analog value */ 00201 adc_rd = Alcohol.read_u16(); 00202 00203 // pause 200ms 00204 Thread::wait(200); 00205 } 00206 00207 ///////////////////////////////////////////////////////////////////////////////////////////////////////////// 00208 ///////////////////////////////////////////////////////////////////////////////////////////////////////////// 00209 ///////////////////////////////////////////////////////////////////////////////////////////////////////////// 00210 /************************************************************************************************** 00211 * Function CalculatePPM(Int times, bool amb) 00212 * ------------------------------------------------------------------------------------------------- 00213 * Overview: Calculation of PPM 00214 * Input: times = Number of samples to take, amb sets either ambient reading or test reading (true for test) 00215 * Output: None 00216 **************************************************************************************************/ 00217 00218 void CalculatePPM(int times, bool amb) 00219 { 00220 float lgPPM; 00221 00222 /* Read values x times */ 00223 for(int x = 0; x < times; x++) 00224 { 00225 ReadSensor(); 00226 value[x] = ((float)adc_rd * Vadc_3V3); 00227 StartHaptic(); 00228 Thread::wait(50); 00229 } 00230 00231 /* Calculate the average value for accuratcy */ 00232 for(int y = 0; y < times; y++) 00233 { 00234 Vrl += value[y]; 00235 } 00236 Vrl = Vrl / times; 00237 00238 /* Set SensorRes reference value */ 00239 SensorRes = (Vrl / 3.3); 00240 00241 /* Set ratio */ 00242 ratio = SensorRes1 / SensorRes; 00243 00244 /* Convert to PPM */ 00245 lgPPM = ( log10( ratio ) * -1.5512 ) + 2.5911; 00246 00247 /* If true create test result, flase creates reference result */ 00248 if (amb == true) 00249 { 00250 ppm = pow( 10, lgPPM ); 00251 } 00252 else 00253 { 00254 ppm_1 = pow( 10, lgPPM ); 00255 } 00256 } 00257 00258 ///////////////////////////////////////////////////////////////////////////////////////////////////////////// 00259 ///////////////////////////////////////////////////////////////////////////////////////////////////////////// 00260 ///////////////////////////////////////////////////////////////////////////////////////////////////////////// 00261 /************************************************************************************************** 00262 * Function void ambient(int times) 00263 * ------------------------------------------------------------------------------------------------- 00264 * Overview: Reading of the Ambient Voltgage of the sensor for reference 00265 * Input: times = Number of samples to take 00266 * Output: None 00267 **************************************************************************************************/ 00268 00269 void ambient(int times) 00270 { 00271 /* Read ambient values x times flashing green led*/ 00272 for(int x = 0; x < times; x++) 00273 { 00274 redLed = LED_OFF; 00275 greenLed = LED_OFF; 00276 blueLed = LED_OFF; 00277 00278 ReadSensor(); 00279 value1[x] = (float)adc_rd * Vadc_3V3; 00280 00281 redLed = LED_OFF; 00282 greenLed = LED_ON; 00283 blueLed = LED_OFF; 00284 Thread::wait(48); 00285 } 00286 00287 /* Calculate the average value for accuratcy */ 00288 for(int y = 0; y < times; y++) 00289 { 00290 ambientAlc+=value1[y]; 00291 } 00292 ambientAlc = ambientAlc / times; 00293 00294 /* Set SensorRes1 reference value */ 00295 SensorRes1 = (ambientAlc / 3.3); 00296 } 00297 00298 ///////////////////////////////////////////////////////////////////////////////////////////////////////////// 00299 ///////////////////////////////////////////////////////////////////////////////////////////////////////////// 00300 ///////////////////////////////////////////////////////////////////////////////////////////////////////////// 00301 /************************************************************************************************** 00302 * Function void StartHaptic(void) 00303 * ------------------------------------------------------------------------------------------------- 00304 * Overview: Start Buzzing haptic motor 00305 * Input: None 00306 * Output: None 00307 **************************************************************************************************/ 00308 00309 void StartHaptic(void) 00310 { 00311 hapticTimer.start(50); 00312 haptic = 1; 00313 } 00314 00315 ///////////////////////////////////////////////////////////////////////////////////////////////////////////// 00316 ///////////////////////////////////////////////////////////////////////////////////////////////////////////// 00317 ///////////////////////////////////////////////////////////////////////////////////////////////////////////// 00318 /************************************************************************************************** 00319 * Function void StopHaptic(void) 00320 * ------------------------------------------------------------------------------------------------- 00321 * Overview: Stop Buzzing haptic motor 00322 * Input: None 00323 * Output: None 00324 **************************************************************************************************/ 00325 00326 void StopHaptic(void const *n) { 00327 haptic = 0; 00328 hapticTimer.stop(); 00329 } 00330 00331 ///////////////////////////////////////////////////////////////////////////////////////////////////////////// 00332 ///////////////////////////////////////////////////////////////////////////////////////////////////////////// 00333 ///////////////////////////////////////////////////////////////////////////////////////////////////////////// 00334 /************************************************************************************************** 00335 * Function void ButtonUp(void) 00336 * ------------------------------------------------------------------------------------------------- 00337 * Overview: Function called whe up button pressed, Begins Breathilyzer testing procedure 00338 * Input: None 00339 * Output: None 00340 **************************************************************************************************/ 00341 00342 void ButtonUp(void) 00343 { 00344 StartHaptic(); 00345 00346 bool Ref = false; 00347 bool Test = true; 00348 00349 /* LED set to green for test beginning*/ 00350 redLed = LED_OFF; 00351 greenLed = LED_ON; 00352 blueLed = LED_OFF; 00353 00354 /* Fill 96px by 96px Screen with 96px by 96px Initialising Image starting at x=0,y=0 */ 00355 oled.DrawImage(ini,0,0); 00356 00357 /* first boot bug work around to stop junk values */ 00358 if (isFirstBoot == true) 00359 { 00360 /*read ambient atmosphere levels with 10 samples and set flag to show it's ambient basline figure*/ 00361 ambient(1); 00362 CalculatePPM(1,Ref); 00363 isFirstBoot = false; 00364 } 00365 00366 /*read ambient atmosphere levels with 10 samples and set flag to show it's ambient basline figure*/ 00367 ambient(10); 00368 CalculatePPM(10,Ref); 00369 00370 00371 /* Fill 96px by 96px Screen with 96px by 96px Blowing Image starting at x=0,y=0 */ 00372 oled.DrawImage(blow,0,0); 00373 00374 /*read breathe alcohol levels with 10 samples and set flag to show it's breathilyzer test figure*/ 00375 CalculatePPM(10,Test); 00376 00377 /*Calculate the difference in Alcohol level based on Ambient and test sample*/ 00378 ppm = ppm - ppm_1; 00379 00380 /*Throw away any values less than 0*/ 00381 if (ppm < 0) 00382 { 00383 ppm = 0; 00384 } 00385 00386 /* Fill 96px by 96px Screen with 96px by 96px Blank Background Image starting at x=0,y=0 */ 00387 oled.DrawImage(blank,0,0); 00388 00389 /* Show Calculated alcohol level in PPM and send data via bluetooth to the cloud */ 00390 oled.SetTextProperties(&textProperties); 00391 oled.Label(ppmText,20,36); 00392 sprintf(text,"%.2f",ppm); 00393 oled.Label((uint8_t *)text,50,36); 00394 Thread::wait(1000); 00395 00396 /* Currently sending to the Pressure variable as a temp place holder */ 00397 kw40z_device.SendPressure(ppm * 10); 00398 00399 /* You've got a Hangover coming!*/ 00400 if ( ppm > 200) 00401 { 00402 redLed = LED_ON; 00403 greenLed = LED_OFF; 00404 blueLed = LED_OFF; 00405 00406 StartHaptic(); 00407 00408 /* Fill 96px by 96px Screen with 96px by 96px Hangover Image starting at x=0,y=0 */ 00409 oled.DrawImage(hang,0,0); 00410 } 00411 00412 /* You Shouldn't drive */ 00413 else if (ppm < 200 && ppm > 150) 00414 { 00415 redLed = LED_ON; 00416 greenLed = LED_OFF; 00417 blueLed = LED_ON; 00418 00419 StartHaptic(); 00420 00421 /* Fill 96px by 96px Screen with 96px by 96px Don't Drive Image starting at x=0,y=0 */ 00422 oled.DrawImage(drive,0,0); 00423 } 00424 00425 /* You've had a drink */ 00426 else if (ppm < 150 && ppm > 50) 00427 { 00428 redLed = LED_OFF; 00429 greenLed = LED_ON; 00430 blueLed = LED_ON; 00431 00432 StartHaptic(); 00433 00434 /* Fill 96px by 96px Screen with 96px by 96px Had a drink Image starting at x=0,y=0 */ 00435 oled.DrawImage(drink,0,0); 00436 } 00437 00438 /* Sober as a judge*/ 00439 else 00440 { 00441 redLed = LED_OFF; 00442 greenLed = LED_ON; 00443 blueLed = LED_OFF; 00444 00445 StartHaptic(); 00446 oled.DrawImage(sober,0,0); 00447 } 00448 Thread::wait(5000); 00449 00450 /* Go back to start screen */ 00451 sysinit(); 00452 } 00453 00454 ///////////////////////////////////////////////////////////////////////////////////////////////////////////// 00455 ///////////////////////////////////////////////////////////////////////////////////////////////////////////// 00456 ///////////////////////////////////////////////////////////////////////////////////////////////////////////// 00457 /************************************************************************************************** 00458 * Function void sysint(void) 00459 * ------------------------------------------------------------------------------------------------- 00460 * Overview: System Initial Values Set up 00461 * Input: None 00462 * Output: None 00463 **************************************************************************************************/ 00464 void sysinit(void) 00465 { 00466 /* Set LED to Blue by default*/ 00467 redLed = LED_OFF; 00468 greenLed = LED_OFF; 00469 blueLed = LED_ON; 00470 00471 /* Turn on the backlight of the OLED Display */ 00472 oled.DimScreenON(); 00473 00474 /* Fill 96px by 96px Screen with 96px by 96px Welcome Image starting at x=0,y=0 */ 00475 oled.DrawImage(welcome,0,0); 00476 00477 /* Register callbacks to application functions */ 00478 kw40z_device.attach_buttonUp(&ButtonUp); 00479 kw40z_device.attach_buttonLeft(&ButtonLeft); 00480 kw40z_device.attach_buttonRight(&ButtonRight); 00481 kw40z_device.attach_passkey(&PassKey); 00482 00483 /* Send sensor data to bluetooth */ 00484 kw40z_device.SendSetApplicationMode(GUI_CURRENT_APP_SENSOR_TAG); 00485 00486 /* Change font color to White */ 00487 oled.GetTextProperties(&textProperties); 00488 textProperties.fontColor = COLOR_WHITE; 00489 oled.SetTextProperties(&textProperties); 00490 }
Generated on Tue Jul 12 2022 19:31:27 by
1.7.2
