Very advanced Click Air Quality example for Hexiwear featuring OLED Display, Bluetooth, Cloud and Touch

Dependencies:   Hexi_KW40Z Hexi_OLED_SSD1351

This project has been developed by mbed user daveyclk

This project demonstrates the use of the Mikroelektronika Click Air Quality module with hexiwear featuring the OLED display, the Bluetooth for Cloud connectivity and Touch buttons

Plug Hexiwear into the Docking Station and the Air Quality Click to the Click Socket 1
Connect the USB cable to your computer and to the micro-USB port of the Docking Station

Compile the project and copy the binary "Hexi_Click_AirQuality_Example_HEXIWEAR.bin" in the DAP-LINK drive from your computer file explorer
Press the K64F-RESET button on the docking station to start the program on your board

The OLED screen will display some graphics and the Air Quality measurement in ppm below
Blow gently on the sensor and see the value changing
Graphic displayed will move the Arrow from Green to Purple depending from the ppm value measured by the Air Quality sensor
Download the cell phone App Hexiwear from iOS or Android stores to connect your board to your phone
Type the pin displayed on the screen and give a name to your board to pair it via the App
Congratulation your data are now streamed directly to Wolkabout Cloud...
To visualize the data remotely (over cloud not bluetooth), you can go to Wolksense.com or download the Wolksense iOS/Android App and login with same account

Committer:
GregC
Date:
Fri Nov 04 23:11:29 2016 +0000
Revision:
3:97bc87323258
Parent:
2:8e7d89c2cbde
Very advanced Click Air Quality example for Hexiwear featuring OLED Display, Bluetooth, Cloud and Touch

Who changed what in which revision?

UserRevisionLine numberNew contents of line
daveyclk 2:8e7d89c2cbde 1
daveyclk 2:8e7d89c2cbde 2
GregC 0:4cf89612afab 3 /******************************************************************************
GregC 0:4cf89612afab 4 * Includes
GregC 0:4cf89612afab 5 *******************************************************************************/
GregC 0:4cf89612afab 6
GregC 0:4cf89612afab 7 #include "mbed.h"
GregC 0:4cf89612afab 8 #include "Hexi_OLED_SSD1351.h"
GregC 3:97bc87323258 9 #include "Hexi_KW40Z.h"
GregC 0:4cf89612afab 10 #include "images.h"
daveyclk 2:8e7d89c2cbde 11 #include "new_images.h"
GregC 0:4cf89612afab 12 #include "string.h"
daveyclk 2:8e7d89c2cbde 13 #include "stdbool.h"
GregC 0:4cf89612afab 14
GregC 0:4cf89612afab 15 /******************************************************************************
GregC 0:4cf89612afab 16 * Input and Output Pinout
GregC 0:4cf89612afab 17 *******************************************************************************/
GregC 0:4cf89612afab 18
GregC 0:4cf89612afab 19 AnalogIn ain(PTB2);
GregC 0:4cf89612afab 20 SSD1351 oled(PTB22,PTB21,PTC13,PTB20,PTE6, PTD15); // SSD1351 OLED Driver (MOSI,SCLK,POWER,CS,RST,DC)
GregC 3:97bc87323258 21 KW40Z kw40z_device(PTE24, PTE25); // Instantiate the Hexi KW40Z Driver (UART TX, UART RX)
GregC 3:97bc87323258 22 DigitalOut blueLed(LED3,1);
GregC 0:4cf89612afab 23 Serial pc(USBTX, USBRX);
GregC 0:4cf89612afab 24
GregC 3:97bc87323258 25 Thread txThread;
GregC 3:97bc87323258 26
GregC 3:97bc87323258 27 /******************************************************************************
GregC 3:97bc87323258 28 * prototypes
GregC 3:97bc87323258 29 *******************************************************************************/
GregC 3:97bc87323258 30 void InitModules();
GregC 3:97bc87323258 31 void ReadSensor();
GregC 3:97bc87323258 32 void CalculatePPM();
GregC 3:97bc87323258 33 void DisplayAirQValue(uint16_t value);
GregC 3:97bc87323258 34
GregC 3:97bc87323258 35
GregC 0:4cf89612afab 36 /******************************************************************************
GregC 0:4cf89612afab 37 * Module Variable Definitions
GregC 0:4cf89612afab 38 *******************************************************************************/
GregC 0:4cf89612afab 39
GregC 3:97bc87323258 40 uint16_t ppm;
GregC 0:4cf89612afab 41
GregC 3:97bc87323258 42 uint16_t value = 0;
GregC 3:97bc87323258 43 uint16_t value_old = 0;
GregC 0:4cf89612afab 44 uint16_t adc_rd;
GregC 0:4cf89612afab 45
daveyclk 2:8e7d89c2cbde 46 //const uint8_t *image1; // old cover image
daveyclk 2:8e7d89c2cbde 47 const uint8_t *green_arrow; // Pointer for the image to be displayed
daveyclk 2:8e7d89c2cbde 48 const uint8_t *yellow_arrow; // Pointer for the image to be displayed
daveyclk 2:8e7d89c2cbde 49 const uint8_t *orange_arrow; // Pointer for the image to be displayed
daveyclk 2:8e7d89c2cbde 50 const uint8_t *red_arrow; // Pointer for the image to be displayed
daveyclk 2:8e7d89c2cbde 51 const uint8_t *purple_arrow; // Pointer for the image to be displayed
daveyclk 2:8e7d89c2cbde 52
daveyclk 2:8e7d89c2cbde 53 char text[20]; // Text Buffer for dynamic value displayed
daveyclk 2:8e7d89c2cbde 54
daveyclk 2:8e7d89c2cbde 55 bool test = false; // used to put the program in text mode to check images
GregC 0:4cf89612afab 56
GregC 3:97bc87323258 57 /**************************************************************************************************
GregC 3:97bc87323258 58 * Call Back Functions
GregC 3:97bc87323258 59 **************************************************************************************************/
GregC 3:97bc87323258 60
GregC 3:97bc87323258 61 void ButtonRight(void)
GregC 3:97bc87323258 62 {
GregC 3:97bc87323258 63 kw40z_device.ToggleAdvertisementMode();
GregC 3:97bc87323258 64 }
GregC 3:97bc87323258 65
GregC 3:97bc87323258 66 void ButtonLeft(void)
GregC 3:97bc87323258 67 {
GregC 3:97bc87323258 68 kw40z_device.ToggleAdvertisementMode();
GregC 3:97bc87323258 69 }
GregC 3:97bc87323258 70
GregC 3:97bc87323258 71 void PassKey(void)
GregC 3:97bc87323258 72 {
GregC 3:97bc87323258 73 /* Display Bond Pass Key in a 95px by 18px textbox at x=0,y=40 */
GregC 3:97bc87323258 74 sprintf(text,"%d", kw40z_device.GetPassKey());
GregC 3:97bc87323258 75 oled.TextBox((uint8_t *)text,0,72,95,18);
GregC 3:97bc87323258 76 }
GregC 3:97bc87323258 77
GregC 3:97bc87323258 78
GregC 3:97bc87323258 79
GregC 3:97bc87323258 80 /**************************************************************************************************
GregC 3:97bc87323258 81 * Function Main()
GregC 3:97bc87323258 82 * -------------------------------------------------------------------------------------------------
GregC 3:97bc87323258 83 * Overview:
GregC 3:97bc87323258 84 * Input: None
GregC 3:97bc87323258 85 * Output: None
GregC 3:97bc87323258 86 **************************************************************************************************/
GregC 3:97bc87323258 87
GregC 3:97bc87323258 88 int main()
GregC 3:97bc87323258 89 {
GregC 3:97bc87323258 90
GregC 3:97bc87323258 91 InitModules();
GregC 3:97bc87323258 92
GregC 3:97bc87323258 93 while (true)
GregC 3:97bc87323258 94 {
GregC 3:97bc87323258 95
GregC 3:97bc87323258 96 ReadSensor();
GregC 3:97bc87323258 97 pc.printf("Sensor Value 0x%04X\n\r",ain.read_u16());
GregC 3:97bc87323258 98
GregC 3:97bc87323258 99 blueLed = !kw40z_device.GetAdvertisementMode(); /*Indicate BLE Advertisment Mode*/
GregC 3:97bc87323258 100
GregC 3:97bc87323258 101
GregC 3:97bc87323258 102 CalculatePPM();
GregC 3:97bc87323258 103 DisplayAirQValue(ppm);
GregC 3:97bc87323258 104
GregC 3:97bc87323258 105 Thread::wait(500);
GregC 3:97bc87323258 106
GregC 3:97bc87323258 107 }
GregC 3:97bc87323258 108 }
GregC 3:97bc87323258 109
GregC 3:97bc87323258 110 /**************************************************************************************************
GregC 3:97bc87323258 111 * Function TxTask()
GregC 3:97bc87323258 112 **************************************************************************************************/
GregC 3:97bc87323258 113
GregC 3:97bc87323258 114 void txTask(void){
GregC 3:97bc87323258 115
GregC 3:97bc87323258 116 while (true)
GregC 3:97bc87323258 117 {
GregC 3:97bc87323258 118
GregC 3:97bc87323258 119 /*Notify Hexiwear App that it is running Sensor Tag mode*/
GregC 3:97bc87323258 120 kw40z_device.SendSetApplicationMode(GUI_CURRENT_APP_SENSOR_TAG);
GregC 3:97bc87323258 121
GregC 3:97bc87323258 122 kw40z_device.SendPressure(10*ppm); //send ppm Air Quality Click value
GregC 3:97bc87323258 123
GregC 3:97bc87323258 124 Thread::wait(1000);
GregC 3:97bc87323258 125 }
GregC 3:97bc87323258 126 }
GregC 0:4cf89612afab 127
GregC 0:4cf89612afab 128 /**************************************************************************************************
GregC 0:4cf89612afab 129 * Function InitModules()
GregC 0:4cf89612afab 130 * -------------------------------------------------------------------------------------------------
GregC 0:4cf89612afab 131 * Overview:
GregC 0:4cf89612afab 132 * Input: None
GregC 0:4cf89612afab 133 * Output: None
GregC 0:4cf89612afab 134 **************************************************************************************************/
GregC 0:4cf89612afab 135
GregC 0:4cf89612afab 136 void InitModules()
GregC 0:4cf89612afab 137 {
daveyclk 2:8e7d89c2cbde 138 //image1 = AirQuality; // Setting pointer location of the 96 by 96 pixel bitmap
daveyclk 2:8e7d89c2cbde 139 //oled.DrawImage(image1,0,0); // Fill 96px by 96px Screen with 96px by 96px NXP Image starting at x=0,y=0
daveyclk 2:8e7d89c2cbde 140
daveyclk 2:8e7d89c2cbde 141 green_arrow = Green_arrow_bmp; // Setting pointer location of the 96 by 96 pixel bitmap Arrow Point to Green To begin
daveyclk 2:8e7d89c2cbde 142 yellow_arrow = Yellow_arrow_bmp; // Setting pointer location of the 96 by 96 pixel bitmap
daveyclk 2:8e7d89c2cbde 143 orange_arrow = Orange_arrow_bmp; // Setting pointer location of the 96 by 96 pixel bitmap
daveyclk 2:8e7d89c2cbde 144 red_arrow = Red_arrow_bmp; // Setting pointer location of the 96 by 96 pixel bitmap
daveyclk 2:8e7d89c2cbde 145 purple_arrow = Purple_arrow_bmp; // Setting pointer location of the 96 by 96 pixel bitmap
daveyclk 2:8e7d89c2cbde 146
daveyclk 2:8e7d89c2cbde 147 oled.DrawImage(green_arrow,0,0); // Fill 96px by 96px Screen with 96px by 96px NXP Image starting at x=0,y=0
GregC 0:4cf89612afab 148
GregC 0:4cf89612afab 149 oled_text_properties_t textProperties = {0}; // Get OLED Class Default Text Properties
GregC 0:4cf89612afab 150 oled.GetTextProperties(&textProperties);
GregC 3:97bc87323258 151
GregC 3:97bc87323258 152 /* Register callbacks to application functions */
GregC 3:97bc87323258 153 kw40z_device.attach_buttonLeft(&ButtonLeft);
GregC 3:97bc87323258 154 kw40z_device.attach_buttonRight(&ButtonRight);
GregC 3:97bc87323258 155 kw40z_device.attach_passkey(&PassKey);
GregC 0:4cf89612afab 156
daveyclk 2:8e7d89c2cbde 157 //PPM text now in the Bitmap
daveyclk 2:8e7d89c2cbde 158
daveyclk 2:8e7d89c2cbde 159 //textProperties.fontColor = COLOR_BLUE; // Set text properties to white and right aligned for the dynamic text
daveyclk 2:8e7d89c2cbde 160 //textProperties.alignParam = OLED_TEXT_ALIGN_LEFT;
daveyclk 2:8e7d89c2cbde 161 //oled.SetTextProperties(&textProperties);
GregC 0:4cf89612afab 162
daveyclk 2:8e7d89c2cbde 163 //strcpy((char *) text,"ppm:"); // Display Legends
daveyclk 2:8e7d89c2cbde 164 // oled.Label((uint8_t *)text,15,75);
GregC 0:4cf89612afab 165
daveyclk 2:8e7d89c2cbde 166 textProperties.fontColor = COLOR_WHITE; // Set text properties to white and right aligned for the dynamic text
GregC 0:4cf89612afab 167 textProperties.alignParam = OLED_TEXT_ALIGN_RIGHT;
GregC 0:4cf89612afab 168 oled.SetTextProperties(&textProperties);
GregC 0:4cf89612afab 169
GregC 0:4cf89612afab 170 sprintf(text,"%i",value); // Format the value
daveyclk 2:8e7d89c2cbde 171 oled.TextBox((uint8_t *)text,55,76,20,15); //Increase textbox for more digits
GregC 3:97bc87323258 172
GregC 3:97bc87323258 173 txThread.start(txTask); /*Start transmitting Sensor Tag Data */
GregC 0:4cf89612afab 174
GregC 0:4cf89612afab 175 }
GregC 0:4cf89612afab 176
GregC 0:4cf89612afab 177
GregC 0:4cf89612afab 178 /**************************************************************************************************
GregC 0:4cf89612afab 179 * Function ReadSensor()
GregC 0:4cf89612afab 180 * -------------------------------------------------------------------------------------------------
GregC 0:4cf89612afab 181 * Overview: Read sensor.
GregC 0:4cf89612afab 182 * Input: None
GregC 0:4cf89612afab 183 * Output: None
GregC 0:4cf89612afab 184 **************************************************************************************************/
GregC 0:4cf89612afab 185
GregC 0:4cf89612afab 186 void ReadSensor()
GregC 0:4cf89612afab 187 {
GregC 0:4cf89612afab 188 adc_rd = ain.read_u16();
GregC 0:4cf89612afab 189 wait_ms(10);
GregC 0:4cf89612afab 190 }
GregC 0:4cf89612afab 191
GregC 0:4cf89612afab 192
GregC 0:4cf89612afab 193 /**************************************************************************************************
GregC 0:4cf89612afab 194 * Function CalculatePPM()
GregC 0:4cf89612afab 195 * -------------------------------------------------------------------------------------------------
GregC 0:4cf89612afab 196 * Overview: Calculation of PPM.
GregC 0:4cf89612afab 197 * Input: None
GregC 0:4cf89612afab 198 * Output: None
GregC 0:4cf89612afab 199 **************************************************************************************************/
GregC 0:4cf89612afab 200
GregC 0:4cf89612afab 201 void CalculatePPM()
GregC 0:4cf89612afab 202 {
GregC 0:4cf89612afab 203 const double Rl = 5000.0; // Rl (Ohm) - Load resistance
daveyclk 1:7b9c19276087 204 const double Vadc_33 = 0.0000503548; // ADC step 3,3V/65535 0.00503mV (16bit ADC)
GregC 0:4cf89612afab 205 double Vrl; // Output voltage
GregC 0:4cf89612afab 206 double Rs; // Rs (Ohm) - Sensor resistance
GregC 0:4cf89612afab 207 double ratio; // Rs/Rl ratio
GregC 0:4cf89612afab 208 double lgPPM;
GregC 0:4cf89612afab 209
GregC 0:4cf89612afab 210 Vrl = (double)adc_rd * Vadc_33; // For 3.3V Vcc use Vadc_33
daveyclk 1:7b9c19276087 211 Rs = Rl * (3.3 - Vrl)/Vrl; // Calculate sensor resistance
GregC 0:4cf89612afab 212 ratio = Rs/Rl; // Calculate ratio
GregC 0:4cf89612afab 213 lgPPM = (log10(ratio) * -0.8) + 0.9; // Calculate ppm
GregC 3:97bc87323258 214 ppm = 6* pow(10,lgPPM); // Calculate ppm
GregC 0:4cf89612afab 215 }
GregC 0:4cf89612afab 216
GregC 0:4cf89612afab 217
GregC 0:4cf89612afab 218
GregC 0:4cf89612afab 219 /**************************************************************************************************
GregC 0:4cf89612afab 220 * Function DisplayAirQValue()
GregC 0:4cf89612afab 221 * -------------------------------------------------------------------------------------------------
GregC 0:4cf89612afab 222 * Overview:
GregC 0:4cf89612afab 223 * Input: None
GregC 0:4cf89612afab 224 * Output: None
GregC 0:4cf89612afab 225 **************************************************************************************************/
GregC 0:4cf89612afab 226
GregC 3:97bc87323258 227 void DisplayAirQValue(uint16_t value )
GregC 0:4cf89612afab 228 {
GregC 0:4cf89612afab 229 if (value_old != value)
GregC 0:4cf89612afab 230 {
GregC 0:4cf89612afab 231
daveyclk 2:8e7d89c2cbde 232 if( value > 200)
daveyclk 2:8e7d89c2cbde 233 oled.DrawImage(purple_arrow,0,0); // Fill 96px by 96px Screen with 96px by 96px NXP Image starting at x=0,y=0
daveyclk 2:8e7d89c2cbde 234 else if (value < 200 && value > 150)
daveyclk 2:8e7d89c2cbde 235 oled.DrawImage(red_arrow,0,0);
daveyclk 2:8e7d89c2cbde 236 else if (value < 150 && value > 100)
daveyclk 2:8e7d89c2cbde 237 oled.DrawImage(orange_arrow,0,0);
daveyclk 2:8e7d89c2cbde 238 else if (value < 100 && value > 50)
daveyclk 2:8e7d89c2cbde 239 oled.DrawImage(yellow_arrow,0,0);
daveyclk 2:8e7d89c2cbde 240 else
daveyclk 2:8e7d89c2cbde 241 oled.DrawImage(green_arrow,0,0);
daveyclk 2:8e7d89c2cbde 242
GregC 0:4cf89612afab 243 oled_text_properties_t textProperties = {0}; // Get OLED Class Default Text Properties
GregC 0:4cf89612afab 244 oled.GetTextProperties(&textProperties);
GregC 0:4cf89612afab 245
GregC 0:4cf89612afab 246 // clear the previous value
GregC 0:4cf89612afab 247 textProperties.fontColor = COLOR_WHITE; // Set text properties to white and right aligned for the dynamic text
GregC 0:4cf89612afab 248 textProperties.alignParam = OLED_TEXT_ALIGN_RIGHT;
GregC 0:4cf89612afab 249 oled.SetTextProperties(&textProperties);
GregC 0:4cf89612afab 250
GregC 0:4cf89612afab 251 sprintf(text,"%i",value_old); // Format the value
daveyclk 2:8e7d89c2cbde 252 oled.TextBox((uint8_t *)text,55,76,20,15); //Increase textbox for more digits
GregC 0:4cf89612afab 253
GregC 0:4cf89612afab 254 // display the new value
GregC 0:4cf89612afab 255 textProperties.fontColor = COLOR_WHITE; // Set text properties to white and right aligned for the dynamic text
GregC 0:4cf89612afab 256 textProperties.alignParam = OLED_TEXT_ALIGN_RIGHT;
GregC 0:4cf89612afab 257 oled.SetTextProperties(&textProperties);
GregC 0:4cf89612afab 258
GregC 0:4cf89612afab 259 sprintf(text,"%i",value); // Format the value
daveyclk 2:8e7d89c2cbde 260 oled.TextBox((uint8_t *)text,55,76,20,15); //Increase textbox for more digits
GregC 0:4cf89612afab 261 }
GregC 0:4cf89612afab 262 value_old = value;
GregC 0:4cf89612afab 263 }