Advanced iBreath Analyzer featuring Hexiwear with Alcohol Click module

Dependencies:   Hexi_KW40Z Hexi_OLED_SSD1351

This Application example of iBreath Analyzer featuring Hexiwear with Alcohol Click module has been developed by Dave Clarke.

Detailed instructions for setting up Hexiwear and run the Application are available on hackster.io HERE

Dave published a new version of his iBreath Analyzer, which is now capable to talk thanks to the addition of the Click Text to Speech module

Import programTalking_breathalyzer

iBreathe Breathalyzer can now talk thanks to the Text to Speech Click Board

Committer:
GregC
Date:
Tue Oct 18 21:52:42 2016 +0000
Revision:
0:d10482dd53e5
Advanced iBreath Analyzer featuring Hexiwear with Alcohol Click module

Who changed what in which revision?

UserRevisionLine numberNew contents of line
GregC 0:d10482dd53e5 1 /****************************************************************************
GregC 0:d10482dd53e5 2 * Title : iBreathe Breathalyzer
GregC 0:d10482dd53e5 3 * Filename : breathalyzer
GregC 0:d10482dd53e5 4 * Author : Dave Clarke
GregC 0:d10482dd53e5 5 * Origin Date : 27/09/2016
GregC 0:d10482dd53e5 6 * Notes : Breathalyzer utilizing Hexiware, Alcohol click and Wolksense
GregC 0:d10482dd53e5 7 *****************************************************************************/
GregC 0:d10482dd53e5 8 /**************************CHANGE LIST **************************************
GregC 0:d10482dd53e5 9 *
GregC 0:d10482dd53e5 10 * Date Software Version Initials Description
GregC 0:d10482dd53e5 11 * 27/09/16 1.0.0 DC Interface Created.
GregC 0:d10482dd53e5 12 *
GregC 0:d10482dd53e5 13 *****************************************************************************/
GregC 0:d10482dd53e5 14
GregC 0:d10482dd53e5 15 /**
GregC 0:d10482dd53e5 16 * @page TEST_CFG Test Configurations
GregC 0:d10482dd53e5 17 * <h3> Test configuration : </h3>
GregC 0:d10482dd53e5 18 * @par
GregC 0:d10482dd53e5 19 * <ul>
GregC 0:d10482dd53e5 20 * <li><b> MCU </b> : MK64FN1M0XXX12 </li>
GregC 0:d10482dd53e5 21 * <li><b> Dev. Board </b> : HEXIWEAR </li>
GregC 0:d10482dd53e5 22 * <li><b> Oscillator </b> : 12 MHz external </li>
GregC 0:d10482dd53e5 23 * <li><b> Ext. Modules </b> : Alcohol Click on mikroBUS 1 </li>
GregC 0:d10482dd53e5 24 * <li><b> SW </b> : mBed OS5 </li>
GregC 0:d10482dd53e5 25 * </ul>
GregC 0:d10482dd53e5 26 */
GregC 0:d10482dd53e5 27
GregC 0:d10482dd53e5 28 /**
GregC 0:d10482dd53e5 29 * @mainpage
GregC 0:d10482dd53e5 30 * <h3> Breathalyser created with HEXIWEAR and mBed OS 5 </h3>
GregC 0:d10482dd53e5 31 * @par This will show you how much you've drunk and tell you with an Emoticon if
GregC 0:d10482dd53e5 32 * you're too hammered to even consider driving. Using the Hexiware app the readings
GregC 0:d10482dd53e5 33 * are transmitted to the cloud via bluetooth. Is it time to give up drinking yet?!
GregC 0:d10482dd53e5 34
GregC 0:d10482dd53e5 35 * <h3> Alcohol Features </h3>
GregC 0:d10482dd53e5 36 * @par Alcohol click, Hexiwear docking station, Hexiware
GregC 0:d10482dd53e5 37 */
GregC 0:d10482dd53e5 38
GregC 0:d10482dd53e5 39 /******************************************************************************
GregC 0:d10482dd53e5 40 * Includes
GregC 0:d10482dd53e5 41 *******************************************************************************/
GregC 0:d10482dd53e5 42
GregC 0:d10482dd53e5 43 #include "mbed.h"
GregC 0:d10482dd53e5 44 #include "Hexi_KW40Z.h"
GregC 0:d10482dd53e5 45 #include "Hexi_OLED_SSD1351.h"
GregC 0:d10482dd53e5 46 #include "OLED_types.h"
GregC 0:d10482dd53e5 47 #include "OpenSans_Font.h"
GregC 0:d10482dd53e5 48 #include "string.h"
GregC 0:d10482dd53e5 49 #include "iBreatheImages.h"
GregC 0:d10482dd53e5 50
GregC 0:d10482dd53e5 51 /******************************************************************************
GregC 0:d10482dd53e5 52 * Module Variable Definitions
GregC 0:d10482dd53e5 53 *******************************************************************************/
GregC 0:d10482dd53e5 54
GregC 0:d10482dd53e5 55 #define LED_ON 0
GregC 0:d10482dd53e5 56 #define LED_OFF 1
GregC 0:d10482dd53e5 57
GregC 0:d10482dd53e5 58 // Pointers to:
GregC 0:d10482dd53e5 59 const uint8_t *welcome, // Welcome screen image
GregC 0:d10482dd53e5 60 *blank, // blank image
GregC 0:d10482dd53e5 61 *blow, // Start Blowing Image
GregC 0:d10482dd53e5 62 *drink, // You've been drinking image
GregC 0:d10482dd53e5 63 *drive, // Don't drive image
GregC 0:d10482dd53e5 64 *hang, // You'll have a hangover image
GregC 0:d10482dd53e5 65 *ini, // Initialising image
GregC 0:d10482dd53e5 66 *sober; // Sober as a judge image
GregC 0:d10482dd53e5 67
GregC 0:d10482dd53e5 68 const float Vadc_3V3 = 0.00005035; // 16-Bit ADC step 3V3/65535 = 0.05035 mV
GregC 0:d10482dd53e5 69
GregC 0:d10482dd53e5 70 float Vrl = 0, // Output voltage
GregC 0:d10482dd53e5 71 ambientAlc = 0, // Abmient Output voltage from sensor
GregC 0:d10482dd53e5 72 SensorRes = 0, // SensorRes (Ohm) - Sensor resistance
GregC 0:d10482dd53e5 73 SensorRes1 = 0, // SensorRes (Ohm) - Sensor resistance
GregC 0:d10482dd53e5 74 ppm = 0, // ppm
GregC 0:d10482dd53e5 75 ppm_1 = 0, // Ambient ppm variable
GregC 0:d10482dd53e5 76 ratio = 0; // SensorRes/LoadRes ratio
GregC 0:d10482dd53e5 77
GregC 0:d10482dd53e5 78 unsigned short adc_rd = 0; //Initialise anologue read variable
GregC 0:d10482dd53e5 79
GregC 0:d10482dd53e5 80 const uint8_t ppmText[] = "ppm:"; // text for PPM label
GregC 0:d10482dd53e5 81
GregC 0:d10482dd53e5 82 char text[20], // Text array variables
GregC 0:d10482dd53e5 83 text2[20],
GregC 0:d10482dd53e5 84 text3[20];
GregC 0:d10482dd53e5 85
GregC 0:d10482dd53e5 86 float value[20], // initial sensor set up values
GregC 0:d10482dd53e5 87 value1[20]; // initial sensor set up values
GregC 0:d10482dd53e5 88
GregC 0:d10482dd53e5 89 bool isFirstBoot = true;
GregC 0:d10482dd53e5 90
GregC 0:d10482dd53e5 91
GregC 0:d10482dd53e5 92 /******************************************************************************
GregC 0:d10482dd53e5 93 * Function Prototypes
GregC 0:d10482dd53e5 94 *******************************************************************************/
GregC 0:d10482dd53e5 95
GregC 0:d10482dd53e5 96 void sysinit(void);
GregC 0:d10482dd53e5 97 void ReadSensor();
GregC 0:d10482dd53e5 98 void CalculatePPM(int times, bool amb);
GregC 0:d10482dd53e5 99 void ambient(int times);
GregC 0:d10482dd53e5 100 void StartHaptic(void);
GregC 0:d10482dd53e5 101 void StopHaptic(void const *n);
GregC 0:d10482dd53e5 102 void ButtonUp(void);
GregC 0:d10482dd53e5 103 void txTask(void);
GregC 0:d10482dd53e5 104
GregC 0:d10482dd53e5 105 /******************************************************************************
GregC 0:d10482dd53e5 106 * Instance setups
GregC 0:d10482dd53e5 107 *******************************************************************************/
GregC 0:d10482dd53e5 108 /* Define timer for haptic feedback */
GregC 0:d10482dd53e5 109 RtosTimer hapticTimer(StopHaptic, osTimerOnce);
GregC 0:d10482dd53e5 110
GregC 0:d10482dd53e5 111 //set up Analog read pin for alcohol sensor
GregC 0:d10482dd53e5 112 AnalogIn Alcohol(PTB2);
GregC 0:d10482dd53e5 113
GregC 0:d10482dd53e5 114 /* Instantiate the SSD1351 OLED Driver */
GregC 0:d10482dd53e5 115 SSD1351 oled(PTB22,PTB21,PTC13,PTB20,PTE6, PTD15); /* (MOSI,SCLK,POWER,CS,RST,DC) */
GregC 0:d10482dd53e5 116
GregC 0:d10482dd53e5 117 /* Get OLED Class Default Text Properties */
GregC 0:d10482dd53e5 118 oled_text_properties_t textProperties = {0};
GregC 0:d10482dd53e5 119
GregC 0:d10482dd53e5 120 /* Instantiate the Hexi KW40Z Driver (UART TX, UART RX) */
GregC 0:d10482dd53e5 121 KW40Z kw40z_device(PTE24, PTE25);
GregC 0:d10482dd53e5 122
GregC 0:d10482dd53e5 123 /* LED and Haptic Set ups */
GregC 0:d10482dd53e5 124 DigitalOut redLed(LED1);
GregC 0:d10482dd53e5 125 DigitalOut greenLed(LED2);
GregC 0:d10482dd53e5 126 DigitalOut blueLed(LED3);
GregC 0:d10482dd53e5 127 DigitalOut haptic(PTB9);
GregC 0:d10482dd53e5 128
GregC 0:d10482dd53e5 129 /******************************************************************************
GregC 0:d10482dd53e5 130 * Bluetooth button functions and passkey function
GregC 0:d10482dd53e5 131 *******************************************************************************/
GregC 0:d10482dd53e5 132
GregC 0:d10482dd53e5 133 void ButtonRight(void)
GregC 0:d10482dd53e5 134 {
GregC 0:d10482dd53e5 135 StartHaptic();
GregC 0:d10482dd53e5 136 kw40z_device.ToggleAdvertisementMode();
GregC 0:d10482dd53e5 137 blueLed = kw40z_device.GetAdvertisementMode(); /*Indicate BLE Advertisment Mode*/
GregC 0:d10482dd53e5 138 redLed = !kw40z_device.GetAdvertisementMode(); /*Indicate BLE Advertisment Mode*/
GregC 0:d10482dd53e5 139 greenLed = !kw40z_device.GetAdvertisementMode(); /*Indicate BLE Advertisment Mode*/
GregC 0:d10482dd53e5 140 }
GregC 0:d10482dd53e5 141
GregC 0:d10482dd53e5 142 void ButtonLeft(void)
GregC 0:d10482dd53e5 143 {
GregC 0:d10482dd53e5 144 StartHaptic();
GregC 0:d10482dd53e5 145 kw40z_device.ToggleAdvertisementMode();
GregC 0:d10482dd53e5 146 blueLed = kw40z_device.GetAdvertisementMode(); /*Indicate BLE Advertisment Mode*/
GregC 0:d10482dd53e5 147 redLed = !kw40z_device.GetAdvertisementMode(); /*Indicate BLE Advertisment Mode*/
GregC 0:d10482dd53e5 148 greenLed = !kw40z_device.GetAdvertisementMode(); /*Indicate BLE Advertisment Mode*/
GregC 0:d10482dd53e5 149 }
GregC 0:d10482dd53e5 150
GregC 0:d10482dd53e5 151 void PassKey(void)
GregC 0:d10482dd53e5 152 {
GregC 0:d10482dd53e5 153 StartHaptic();
GregC 0:d10482dd53e5 154 strcpy((char *) text,"PAIR CODE");
GregC 0:d10482dd53e5 155 oled.TextBox((uint8_t *)text,0,25,95,18);
GregC 0:d10482dd53e5 156
GregC 0:d10482dd53e5 157 /* Display Bond Pass Key in a 95px by 18px textbox at x=0,y=40 */
GregC 0:d10482dd53e5 158 sprintf(text3,"%d", kw40z_device.GetPassKey());
GregC 0:d10482dd53e5 159 oled.TextBox((uint8_t *)text3,0,40,95,18);
GregC 0:d10482dd53e5 160 }
GregC 0:d10482dd53e5 161
GregC 0:d10482dd53e5 162 /******************************************************************************
GregC 0:d10482dd53e5 163 * Main
GregC 0:d10482dd53e5 164 *******************************************************************************/
GregC 0:d10482dd53e5 165 /////////////////////////////////////////////////////////////////////////////////////////////////////////////
GregC 0:d10482dd53e5 166 /////////////////////////////////////////////////////////////////////////////////////////////////////////////
GregC 0:d10482dd53e5 167 /////////////////////////////////////////////////////////////////////////////////////////////////////////////
GregC 0:d10482dd53e5 168 int main()
GregC 0:d10482dd53e5 169 {
GregC 0:d10482dd53e5 170 /* Set pointers to the BMPs stored in iBreatheImages.c */
GregC 0:d10482dd53e5 171 welcome = iBreatheWS_bmp; // Welcome screen image
GregC 0:d10482dd53e5 172 blank = iBreatheBlank_bmp; // blank image
GregC 0:d10482dd53e5 173 blow = iBreatheBlow_bmp; // Start Blowing Image
GregC 0:d10482dd53e5 174 drink = iBreatheDrink_bmp; // You've been drinking image
GregC 0:d10482dd53e5 175 drive = iBreatheDrive_bmp; // Don't drive image
GregC 0:d10482dd53e5 176 hang = iBreatheHang_bmp; // You'll have a hangover image
GregC 0:d10482dd53e5 177 ini = iBreatheini_bmp; // Initialising image
GregC 0:d10482dd53e5 178 sober = iBreatheSober_bmp; // Sober as a judge image
GregC 0:d10482dd53e5 179
GregC 0:d10482dd53e5 180 /* Set initial Values */
GregC 0:d10482dd53e5 181 sysinit();
GregC 0:d10482dd53e5 182 }
GregC 0:d10482dd53e5 183
GregC 0:d10482dd53e5 184 /******************************************************************************
GregC 0:d10482dd53e5 185 * Public Function Definitions
GregC 0:d10482dd53e5 186 *******************************************************************************/
GregC 0:d10482dd53e5 187 /////////////////////////////////////////////////////////////////////////////////////////////////////////////
GregC 0:d10482dd53e5 188 /////////////////////////////////////////////////////////////////////////////////////////////////////////////
GregC 0:d10482dd53e5 189 /////////////////////////////////////////////////////////////////////////////////////////////////////////////
GregC 0:d10482dd53e5 190 /**************************************************************************************************
GregC 0:d10482dd53e5 191 * Function readSensor(void)
GregC 0:d10482dd53e5 192 * -------------------------------------------------------------------------------------------------
GregC 0:d10482dd53e5 193 * Overview: Read sensor
GregC 0:d10482dd53e5 194 * Input: None
GregC 0:d10482dd53e5 195 * Output: None
GregC 0:d10482dd53e5 196 **************************************************************************************************/
GregC 0:d10482dd53e5 197
GregC 0:d10482dd53e5 198 void ReadSensor()
GregC 0:d10482dd53e5 199 {
GregC 0:d10482dd53e5 200 /* Read 16 Bit Analog value */
GregC 0:d10482dd53e5 201 adc_rd = Alcohol.read_u16();
GregC 0:d10482dd53e5 202
GregC 0:d10482dd53e5 203 // pause 200ms
GregC 0:d10482dd53e5 204 Thread::wait(200);
GregC 0:d10482dd53e5 205 }
GregC 0:d10482dd53e5 206
GregC 0:d10482dd53e5 207 /////////////////////////////////////////////////////////////////////////////////////////////////////////////
GregC 0:d10482dd53e5 208 /////////////////////////////////////////////////////////////////////////////////////////////////////////////
GregC 0:d10482dd53e5 209 /////////////////////////////////////////////////////////////////////////////////////////////////////////////
GregC 0:d10482dd53e5 210 /**************************************************************************************************
GregC 0:d10482dd53e5 211 * Function CalculatePPM(Int times, bool amb)
GregC 0:d10482dd53e5 212 * -------------------------------------------------------------------------------------------------
GregC 0:d10482dd53e5 213 * Overview: Calculation of PPM
GregC 0:d10482dd53e5 214 * Input: times = Number of samples to take, amb sets either ambient reading or test reading (true for test)
GregC 0:d10482dd53e5 215 * Output: None
GregC 0:d10482dd53e5 216 **************************************************************************************************/
GregC 0:d10482dd53e5 217
GregC 0:d10482dd53e5 218 void CalculatePPM(int times, bool amb)
GregC 0:d10482dd53e5 219 {
GregC 0:d10482dd53e5 220 float lgPPM;
GregC 0:d10482dd53e5 221
GregC 0:d10482dd53e5 222 /* Read values x times */
GregC 0:d10482dd53e5 223 for(int x = 0; x < times; x++)
GregC 0:d10482dd53e5 224 {
GregC 0:d10482dd53e5 225 ReadSensor();
GregC 0:d10482dd53e5 226 value[x] = ((float)adc_rd * Vadc_3V3);
GregC 0:d10482dd53e5 227 StartHaptic();
GregC 0:d10482dd53e5 228 Thread::wait(50);
GregC 0:d10482dd53e5 229 }
GregC 0:d10482dd53e5 230
GregC 0:d10482dd53e5 231 /* Calculate the average value for accuratcy */
GregC 0:d10482dd53e5 232 for(int y = 0; y < times; y++)
GregC 0:d10482dd53e5 233 {
GregC 0:d10482dd53e5 234 Vrl += value[y];
GregC 0:d10482dd53e5 235 }
GregC 0:d10482dd53e5 236 Vrl = Vrl / times;
GregC 0:d10482dd53e5 237
GregC 0:d10482dd53e5 238 /* Set SensorRes reference value */
GregC 0:d10482dd53e5 239 SensorRes = (Vrl / 3.3);
GregC 0:d10482dd53e5 240
GregC 0:d10482dd53e5 241 /* Set ratio */
GregC 0:d10482dd53e5 242 ratio = SensorRes1 / SensorRes;
GregC 0:d10482dd53e5 243
GregC 0:d10482dd53e5 244 /* Convert to PPM */
GregC 0:d10482dd53e5 245 lgPPM = ( log10( ratio ) * -1.5512 ) + 2.5911;
GregC 0:d10482dd53e5 246
GregC 0:d10482dd53e5 247 /* If true create test result, flase creates reference result */
GregC 0:d10482dd53e5 248 if (amb == true)
GregC 0:d10482dd53e5 249 {
GregC 0:d10482dd53e5 250 ppm = pow( 10, lgPPM );
GregC 0:d10482dd53e5 251 }
GregC 0:d10482dd53e5 252 else
GregC 0:d10482dd53e5 253 {
GregC 0:d10482dd53e5 254 ppm_1 = pow( 10, lgPPM );
GregC 0:d10482dd53e5 255 }
GregC 0:d10482dd53e5 256 }
GregC 0:d10482dd53e5 257
GregC 0:d10482dd53e5 258 /////////////////////////////////////////////////////////////////////////////////////////////////////////////
GregC 0:d10482dd53e5 259 /////////////////////////////////////////////////////////////////////////////////////////////////////////////
GregC 0:d10482dd53e5 260 /////////////////////////////////////////////////////////////////////////////////////////////////////////////
GregC 0:d10482dd53e5 261 /**************************************************************************************************
GregC 0:d10482dd53e5 262 * Function void ambient(int times)
GregC 0:d10482dd53e5 263 * -------------------------------------------------------------------------------------------------
GregC 0:d10482dd53e5 264 * Overview: Reading of the Ambient Voltgage of the sensor for reference
GregC 0:d10482dd53e5 265 * Input: times = Number of samples to take
GregC 0:d10482dd53e5 266 * Output: None
GregC 0:d10482dd53e5 267 **************************************************************************************************/
GregC 0:d10482dd53e5 268
GregC 0:d10482dd53e5 269 void ambient(int times)
GregC 0:d10482dd53e5 270 {
GregC 0:d10482dd53e5 271 /* Read ambient values x times flashing green led*/
GregC 0:d10482dd53e5 272 for(int x = 0; x < times; x++)
GregC 0:d10482dd53e5 273 {
GregC 0:d10482dd53e5 274 redLed = LED_OFF;
GregC 0:d10482dd53e5 275 greenLed = LED_OFF;
GregC 0:d10482dd53e5 276 blueLed = LED_OFF;
GregC 0:d10482dd53e5 277
GregC 0:d10482dd53e5 278 ReadSensor();
GregC 0:d10482dd53e5 279 value1[x] = (float)adc_rd * Vadc_3V3;
GregC 0:d10482dd53e5 280
GregC 0:d10482dd53e5 281 redLed = LED_OFF;
GregC 0:d10482dd53e5 282 greenLed = LED_ON;
GregC 0:d10482dd53e5 283 blueLed = LED_OFF;
GregC 0:d10482dd53e5 284 Thread::wait(48);
GregC 0:d10482dd53e5 285 }
GregC 0:d10482dd53e5 286
GregC 0:d10482dd53e5 287 /* Calculate the average value for accuratcy */
GregC 0:d10482dd53e5 288 for(int y = 0; y < times; y++)
GregC 0:d10482dd53e5 289 {
GregC 0:d10482dd53e5 290 ambientAlc+=value1[y];
GregC 0:d10482dd53e5 291 }
GregC 0:d10482dd53e5 292 ambientAlc = ambientAlc / times;
GregC 0:d10482dd53e5 293
GregC 0:d10482dd53e5 294 /* Set SensorRes1 reference value */
GregC 0:d10482dd53e5 295 SensorRes1 = (ambientAlc / 3.3);
GregC 0:d10482dd53e5 296 }
GregC 0:d10482dd53e5 297
GregC 0:d10482dd53e5 298 /////////////////////////////////////////////////////////////////////////////////////////////////////////////
GregC 0:d10482dd53e5 299 /////////////////////////////////////////////////////////////////////////////////////////////////////////////
GregC 0:d10482dd53e5 300 /////////////////////////////////////////////////////////////////////////////////////////////////////////////
GregC 0:d10482dd53e5 301 /**************************************************************************************************
GregC 0:d10482dd53e5 302 * Function void StartHaptic(void)
GregC 0:d10482dd53e5 303 * -------------------------------------------------------------------------------------------------
GregC 0:d10482dd53e5 304 * Overview: Start Buzzing haptic motor
GregC 0:d10482dd53e5 305 * Input: None
GregC 0:d10482dd53e5 306 * Output: None
GregC 0:d10482dd53e5 307 **************************************************************************************************/
GregC 0:d10482dd53e5 308
GregC 0:d10482dd53e5 309 void StartHaptic(void)
GregC 0:d10482dd53e5 310 {
GregC 0:d10482dd53e5 311 hapticTimer.start(50);
GregC 0:d10482dd53e5 312 haptic = 1;
GregC 0:d10482dd53e5 313 }
GregC 0:d10482dd53e5 314
GregC 0:d10482dd53e5 315 /////////////////////////////////////////////////////////////////////////////////////////////////////////////
GregC 0:d10482dd53e5 316 /////////////////////////////////////////////////////////////////////////////////////////////////////////////
GregC 0:d10482dd53e5 317 /////////////////////////////////////////////////////////////////////////////////////////////////////////////
GregC 0:d10482dd53e5 318 /**************************************************************************************************
GregC 0:d10482dd53e5 319 * Function void StopHaptic(void)
GregC 0:d10482dd53e5 320 * -------------------------------------------------------------------------------------------------
GregC 0:d10482dd53e5 321 * Overview: Stop Buzzing haptic motor
GregC 0:d10482dd53e5 322 * Input: None
GregC 0:d10482dd53e5 323 * Output: None
GregC 0:d10482dd53e5 324 **************************************************************************************************/
GregC 0:d10482dd53e5 325
GregC 0:d10482dd53e5 326 void StopHaptic(void const *n) {
GregC 0:d10482dd53e5 327 haptic = 0;
GregC 0:d10482dd53e5 328 hapticTimer.stop();
GregC 0:d10482dd53e5 329 }
GregC 0:d10482dd53e5 330
GregC 0:d10482dd53e5 331 /////////////////////////////////////////////////////////////////////////////////////////////////////////////
GregC 0:d10482dd53e5 332 /////////////////////////////////////////////////////////////////////////////////////////////////////////////
GregC 0:d10482dd53e5 333 /////////////////////////////////////////////////////////////////////////////////////////////////////////////
GregC 0:d10482dd53e5 334 /**************************************************************************************************
GregC 0:d10482dd53e5 335 * Function void ButtonUp(void)
GregC 0:d10482dd53e5 336 * -------------------------------------------------------------------------------------------------
GregC 0:d10482dd53e5 337 * Overview: Function called whe up button pressed, Begins Breathilyzer testing procedure
GregC 0:d10482dd53e5 338 * Input: None
GregC 0:d10482dd53e5 339 * Output: None
GregC 0:d10482dd53e5 340 **************************************************************************************************/
GregC 0:d10482dd53e5 341
GregC 0:d10482dd53e5 342 void ButtonUp(void)
GregC 0:d10482dd53e5 343 {
GregC 0:d10482dd53e5 344 StartHaptic();
GregC 0:d10482dd53e5 345
GregC 0:d10482dd53e5 346 bool Ref = false;
GregC 0:d10482dd53e5 347 bool Test = true;
GregC 0:d10482dd53e5 348
GregC 0:d10482dd53e5 349 /* LED set to green for test beginning*/
GregC 0:d10482dd53e5 350 redLed = LED_OFF;
GregC 0:d10482dd53e5 351 greenLed = LED_ON;
GregC 0:d10482dd53e5 352 blueLed = LED_OFF;
GregC 0:d10482dd53e5 353
GregC 0:d10482dd53e5 354 /* Fill 96px by 96px Screen with 96px by 96px Initialising Image starting at x=0,y=0 */
GregC 0:d10482dd53e5 355 oled.DrawImage(ini,0,0);
GregC 0:d10482dd53e5 356
GregC 0:d10482dd53e5 357 /* first boot bug work around to stop junk values */
GregC 0:d10482dd53e5 358 if (isFirstBoot == true)
GregC 0:d10482dd53e5 359 {
GregC 0:d10482dd53e5 360 /*read ambient atmosphere levels with 10 samples and set flag to show it's ambient basline figure*/
GregC 0:d10482dd53e5 361 ambient(1);
GregC 0:d10482dd53e5 362 CalculatePPM(1,Ref);
GregC 0:d10482dd53e5 363 isFirstBoot = false;
GregC 0:d10482dd53e5 364 }
GregC 0:d10482dd53e5 365
GregC 0:d10482dd53e5 366 /*read ambient atmosphere levels with 10 samples and set flag to show it's ambient basline figure*/
GregC 0:d10482dd53e5 367 ambient(10);
GregC 0:d10482dd53e5 368 CalculatePPM(10,Ref);
GregC 0:d10482dd53e5 369
GregC 0:d10482dd53e5 370
GregC 0:d10482dd53e5 371 /* Fill 96px by 96px Screen with 96px by 96px Blowing Image starting at x=0,y=0 */
GregC 0:d10482dd53e5 372 oled.DrawImage(blow,0,0);
GregC 0:d10482dd53e5 373
GregC 0:d10482dd53e5 374 /*read breathe alcohol levels with 10 samples and set flag to show it's breathilyzer test figure*/
GregC 0:d10482dd53e5 375 CalculatePPM(10,Test);
GregC 0:d10482dd53e5 376
GregC 0:d10482dd53e5 377 /*Calculate the difference in Alcohol level based on Ambient and test sample*/
GregC 0:d10482dd53e5 378 ppm = ppm - ppm_1;
GregC 0:d10482dd53e5 379
GregC 0:d10482dd53e5 380 /*Throw away any values less than 0*/
GregC 0:d10482dd53e5 381 if (ppm < 0)
GregC 0:d10482dd53e5 382 {
GregC 0:d10482dd53e5 383 ppm = 0;
GregC 0:d10482dd53e5 384 }
GregC 0:d10482dd53e5 385
GregC 0:d10482dd53e5 386 /* Fill 96px by 96px Screen with 96px by 96px Blank Background Image starting at x=0,y=0 */
GregC 0:d10482dd53e5 387 oled.DrawImage(blank,0,0);
GregC 0:d10482dd53e5 388
GregC 0:d10482dd53e5 389 /* Show Calculated alcohol level in PPM and send data via bluetooth to the cloud */
GregC 0:d10482dd53e5 390 oled.SetTextProperties(&textProperties);
GregC 0:d10482dd53e5 391 oled.Label(ppmText,20,36);
GregC 0:d10482dd53e5 392 sprintf(text,"%.2f",ppm);
GregC 0:d10482dd53e5 393 oled.Label((uint8_t *)text,50,36);
GregC 0:d10482dd53e5 394 Thread::wait(1000);
GregC 0:d10482dd53e5 395
GregC 0:d10482dd53e5 396 /* Currently sending to the Pressure variable as a temp place holder */
GregC 0:d10482dd53e5 397 kw40z_device.SendPressure(ppm * 10);
GregC 0:d10482dd53e5 398
GregC 0:d10482dd53e5 399 /* You've got a Hangover coming!*/
GregC 0:d10482dd53e5 400 if ( ppm > 200)
GregC 0:d10482dd53e5 401 {
GregC 0:d10482dd53e5 402 redLed = LED_ON;
GregC 0:d10482dd53e5 403 greenLed = LED_OFF;
GregC 0:d10482dd53e5 404 blueLed = LED_OFF;
GregC 0:d10482dd53e5 405
GregC 0:d10482dd53e5 406 StartHaptic();
GregC 0:d10482dd53e5 407
GregC 0:d10482dd53e5 408 /* Fill 96px by 96px Screen with 96px by 96px Hangover Image starting at x=0,y=0 */
GregC 0:d10482dd53e5 409 oled.DrawImage(hang,0,0);
GregC 0:d10482dd53e5 410 }
GregC 0:d10482dd53e5 411
GregC 0:d10482dd53e5 412 /* You Shouldn't drive */
GregC 0:d10482dd53e5 413 else if (ppm < 200 && ppm > 150)
GregC 0:d10482dd53e5 414 {
GregC 0:d10482dd53e5 415 redLed = LED_ON;
GregC 0:d10482dd53e5 416 greenLed = LED_OFF;
GregC 0:d10482dd53e5 417 blueLed = LED_ON;
GregC 0:d10482dd53e5 418
GregC 0:d10482dd53e5 419 StartHaptic();
GregC 0:d10482dd53e5 420
GregC 0:d10482dd53e5 421 /* Fill 96px by 96px Screen with 96px by 96px Don't Drive Image starting at x=0,y=0 */
GregC 0:d10482dd53e5 422 oled.DrawImage(drive,0,0);
GregC 0:d10482dd53e5 423 }
GregC 0:d10482dd53e5 424
GregC 0:d10482dd53e5 425 /* You've had a drink */
GregC 0:d10482dd53e5 426 else if (ppm < 150 && ppm > 50)
GregC 0:d10482dd53e5 427 {
GregC 0:d10482dd53e5 428 redLed = LED_OFF;
GregC 0:d10482dd53e5 429 greenLed = LED_ON;
GregC 0:d10482dd53e5 430 blueLed = LED_ON;
GregC 0:d10482dd53e5 431
GregC 0:d10482dd53e5 432 StartHaptic();
GregC 0:d10482dd53e5 433
GregC 0:d10482dd53e5 434 /* Fill 96px by 96px Screen with 96px by 96px Had a drink Image starting at x=0,y=0 */
GregC 0:d10482dd53e5 435 oled.DrawImage(drink,0,0);
GregC 0:d10482dd53e5 436 }
GregC 0:d10482dd53e5 437
GregC 0:d10482dd53e5 438 /* Sober as a judge*/
GregC 0:d10482dd53e5 439 else
GregC 0:d10482dd53e5 440 {
GregC 0:d10482dd53e5 441 redLed = LED_OFF;
GregC 0:d10482dd53e5 442 greenLed = LED_ON;
GregC 0:d10482dd53e5 443 blueLed = LED_OFF;
GregC 0:d10482dd53e5 444
GregC 0:d10482dd53e5 445 StartHaptic();
GregC 0:d10482dd53e5 446 oled.DrawImage(sober,0,0);
GregC 0:d10482dd53e5 447 }
GregC 0:d10482dd53e5 448 Thread::wait(5000);
GregC 0:d10482dd53e5 449
GregC 0:d10482dd53e5 450 /* Go back to start screen */
GregC 0:d10482dd53e5 451 sysinit();
GregC 0:d10482dd53e5 452 }
GregC 0:d10482dd53e5 453
GregC 0:d10482dd53e5 454 /////////////////////////////////////////////////////////////////////////////////////////////////////////////
GregC 0:d10482dd53e5 455 /////////////////////////////////////////////////////////////////////////////////////////////////////////////
GregC 0:d10482dd53e5 456 /////////////////////////////////////////////////////////////////////////////////////////////////////////////
GregC 0:d10482dd53e5 457 /**************************************************************************************************
GregC 0:d10482dd53e5 458 * Function void sysint(void)
GregC 0:d10482dd53e5 459 * -------------------------------------------------------------------------------------------------
GregC 0:d10482dd53e5 460 * Overview: System Initial Values Set up
GregC 0:d10482dd53e5 461 * Input: None
GregC 0:d10482dd53e5 462 * Output: None
GregC 0:d10482dd53e5 463 **************************************************************************************************/
GregC 0:d10482dd53e5 464 void sysinit(void)
GregC 0:d10482dd53e5 465 {
GregC 0:d10482dd53e5 466 /* Set LED to Blue by default*/
GregC 0:d10482dd53e5 467 redLed = LED_OFF;
GregC 0:d10482dd53e5 468 greenLed = LED_OFF;
GregC 0:d10482dd53e5 469 blueLed = LED_ON;
GregC 0:d10482dd53e5 470
GregC 0:d10482dd53e5 471 /* Turn on the backlight of the OLED Display */
GregC 0:d10482dd53e5 472 // oled.DimScreenON();
GregC 0:d10482dd53e5 473
GregC 0:d10482dd53e5 474 /* Fill 96px by 96px Screen with 96px by 96px Welcome Image starting at x=0,y=0 */
GregC 0:d10482dd53e5 475 oled.DrawImage(welcome,0,0);
GregC 0:d10482dd53e5 476
GregC 0:d10482dd53e5 477 /* Register callbacks to application functions */
GregC 0:d10482dd53e5 478 kw40z_device.attach_buttonUp(&ButtonUp);
GregC 0:d10482dd53e5 479 kw40z_device.attach_buttonLeft(&ButtonLeft);
GregC 0:d10482dd53e5 480 kw40z_device.attach_buttonRight(&ButtonRight);
GregC 0:d10482dd53e5 481 kw40z_device.attach_passkey(&PassKey);
GregC 0:d10482dd53e5 482
GregC 0:d10482dd53e5 483 /* Send sensor data to bluetooth */
GregC 0:d10482dd53e5 484 kw40z_device.SendSetApplicationMode(GUI_CURRENT_APP_SENSOR_TAG);
GregC 0:d10482dd53e5 485
GregC 0:d10482dd53e5 486 /* Change font color to White */
GregC 0:d10482dd53e5 487 oled.GetTextProperties(&textProperties);
GregC 0:d10482dd53e5 488 textProperties.fontColor = COLOR_WHITE;
GregC 0:d10482dd53e5 489 oled.SetTextProperties(&textProperties);
GregC 0:d10482dd53e5 490 }