Example of using Hexiwear buttons and declaring screens.
Dependencies: FXOS8700 FXAS21002 Hexi_KW40Z Hexi_OLED_SSD1351
main.cpp@3:53c096a80151, 2018-11-21 (annotated)
- Committer:
- asong
- Date:
- Wed Nov 21 17:56:31 2018 +0000
- Revision:
- 3:53c096a80151
- Parent:
- 2:824ed4ae8d52
Example created
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
asong | 1:e4b38d6918ba | 1 | /********************************************************************** |
asong | 1:e4b38d6918ba | 2 | Texas State University Senior Project - HexiHeart |
nbaker | 0:d1d36a3da39b | 3 | Team Zeta: Alex Song, Jasmine Rounsaville, Issam Hichami, Neil Baker |
nbaker | 0:d1d36a3da39b | 4 | Version: HexiHeart_1st 11/12/17 |
nbaker | 0:d1d36a3da39b | 5 | This version has basic menu layout and screen timeout feature. The menu |
asong | 1:e4b38d6918ba | 6 | are just placeholders (for the most part) and will be either adjusted or |
nbaker | 0:d1d36a3da39b | 7 | replaced with graphic images. |
nbaker | 0:d1d36a3da39b | 8 | |
nbaker | 0:d1d36a3da39b | 9 | ***********************************************************************/ |
nbaker | 0:d1d36a3da39b | 10 | |
nbaker | 0:d1d36a3da39b | 11 | #include "mbed.h" |
nbaker | 0:d1d36a3da39b | 12 | #include "Hexi_KW40Z.h" // Button and BLE fuctions |
nbaker | 0:d1d36a3da39b | 13 | #include "FXOS8700.h" // 3D Accelorometer & Mag |
nbaker | 0:d1d36a3da39b | 14 | #include "FXAS21002.h" // 3-Axis Gyroscope |
nbaker | 0:d1d36a3da39b | 15 | #include "Hexi_OLED_SSD1351.h" // OLED fuctions |
nbaker | 0:d1d36a3da39b | 16 | #include "OLED_types.h" // Text attributs |
nbaker | 0:d1d36a3da39b | 17 | #include "string.h" |
nbaker | 0:d1d36a3da39b | 18 | #include "OpenSans_Font.h" |
asong | 1:e4b38d6918ba | 19 | |
asong | 2:824ed4ae8d52 | 20 | |
asong | 1:e4b38d6918ba | 21 | /* We need to confirm whether it's better to include and |
asong | 1:e4b38d6918ba | 22 | configure every module for lowest power, or whether it's |
nbaker | 0:d1d36a3da39b | 23 | better to save memory by not doing that |
nbaker | 0:d1d36a3da39b | 24 | */ |
nbaker | 0:d1d36a3da39b | 25 | |
nbaker | 0:d1d36a3da39b | 26 | // Definitions |
asong | 2:824ed4ae8d52 | 27 | #define LED_ON 0 |
asong | 2:824ed4ae8d52 | 28 | #define LED_OFF 1 |
asong | 3:53c096a80151 | 29 | #define SCRN_TIME 60.0 |
asong | 2:824ed4ae8d52 | 30 | |
asong | 1:e4b38d6918ba | 31 | |
nbaker | 0:d1d36a3da39b | 32 | void StartHaptic(void); |
asong | 1:e4b38d6918ba | 33 | void StartHaptic(int x); |
nbaker | 0:d1d36a3da39b | 34 | void StopHaptic(void const *n); |
nbaker | 0:d1d36a3da39b | 35 | void error_screen(void); |
nbaker | 0:d1d36a3da39b | 36 | void update_display(void); |
nbaker | 0:d1d36a3da39b | 37 | |
asong | 1:e4b38d6918ba | 38 | |
nbaker | 0:d1d36a3da39b | 39 | // ***************** Global variables *********************** |
nbaker | 0:d1d36a3da39b | 40 | char text_1[20]; // Text buffer - Do we need more? |
asong | 2:824ed4ae8d52 | 41 | char display_buff[30]; //Buffer for conversion to char to display |
asong | 3:53c096a80151 | 42 | bool OLED_ON = 1; |
nbaker | 0:d1d36a3da39b | 43 | uint8_t Screen_Num = 0; // Initialize to main screen |
asong | 3:53c096a80151 | 44 | uint8_t variableExample = 0; |
asong | 3:53c096a80151 | 45 | |
asong | 3:53c096a80151 | 46 | |
nbaker | 0:d1d36a3da39b | 47 | // ***************** Define pins ***************************** |
asong | 3:53c096a80151 | 48 | DigitalOut chips(PTB12); |
asong | 3:53c096a80151 | 49 | |
nbaker | 0:d1d36a3da39b | 50 | FXAS21002 gyro(PTC11,PTC10); // Gyroscope |
nbaker | 0:d1d36a3da39b | 51 | SSD1351 oled(PTB22,PTB21,PTC13,PTB20,PTE6, PTD15); // SSD1351 OLED Driver (MOSI,SCLK,POWER,CS,RST,DC) |
nbaker | 0:d1d36a3da39b | 52 | FXOS8700 accel(PTC11, PTC10); // Accelorometer |
nbaker | 0:d1d36a3da39b | 53 | FXOS8700 mag(PTC11, PTC10); // Mag (same chip as Accel) |
asong | 3:53c096a80151 | 54 | |
nbaker | 0:d1d36a3da39b | 55 | |
nbaker | 0:d1d36a3da39b | 56 | DigitalOut RED_Led(LED1); |
nbaker | 0:d1d36a3da39b | 57 | DigitalOut GRN_Led(LED2); |
nbaker | 0:d1d36a3da39b | 58 | DigitalOut BLU_Led(LED3); |
nbaker | 0:d1d36a3da39b | 59 | DigitalOut haptic(PTB9); |
nbaker | 0:d1d36a3da39b | 60 | |
asong | 1:e4b38d6918ba | 61 | /* Instantiate the Hexi KW40Z Driver (UART TX, UART RX) */ |
nbaker | 0:d1d36a3da39b | 62 | KW40Z kw40z_device(PTE24, PTE25); |
nbaker | 0:d1d36a3da39b | 63 | |
nbaker | 0:d1d36a3da39b | 64 | /* Define timer for haptic feedback */ |
nbaker | 0:d1d36a3da39b | 65 | RtosTimer hapticTimer(StopHaptic, osTimerOnce); |
nbaker | 0:d1d36a3da39b | 66 | |
nbaker | 0:d1d36a3da39b | 67 | //***************** Tickers and Timers ***************** |
nbaker | 0:d1d36a3da39b | 68 | Ticker Screen_Timer;// use ticker to turn off OLED |
nbaker | 0:d1d36a3da39b | 69 | |
asong | 1:e4b38d6918ba | 70 | void timout_timer() // turn off display mode |
asong | 1:e4b38d6918ba | 71 | { |
asong | 1:e4b38d6918ba | 72 | oled.FillScreen(COLOR_BLACK); // Clear screen.. is there a better command for this? |
asong | 1:e4b38d6918ba | 73 | OLED_ON = 0; // set flag to off |
asong | 1:e4b38d6918ba | 74 | Screen_Timer.detach(); |
asong | 1:e4b38d6918ba | 75 | }//end routine |
asong | 1:e4b38d6918ba | 76 | |
nbaker | 0:d1d36a3da39b | 77 | void ButtonUp(void) |
nbaker | 0:d1d36a3da39b | 78 | { |
asong | 1:e4b38d6918ba | 79 | Screen_Timer.attach(&timout_timer,(SCRN_TIME));//Is this sufficient to reset/restart ticker timer for OLED? |
asong | 1:e4b38d6918ba | 80 | if (OLED_ON == 0) { |
asong | 1:e4b38d6918ba | 81 | OLED_ON = 1; // Scree was off, set to On |
asong | 1:e4b38d6918ba | 82 | update_display(); |
asong | 1:e4b38d6918ba | 83 | } else { |
asong | 1:e4b38d6918ba | 84 | switch(Screen_Num) { |
asong | 1:e4b38d6918ba | 85 | case 0: {// We're in Main Screen |
asong | 1:e4b38d6918ba | 86 | StartHaptic(); |
asong | 1:e4b38d6918ba | 87 | update_display(); |
asong | 1:e4b38d6918ba | 88 | break; |
asong | 1:e4b38d6918ba | 89 | } |
asong | 3:53c096a80151 | 90 | case 1: {// Second Screen |
asong | 3:53c096a80151 | 91 | |
asong | 1:e4b38d6918ba | 92 | update_display(); |
asong | 1:e4b38d6918ba | 93 | StartHaptic(); |
asong | 3:53c096a80151 | 94 | |
asong | 1:e4b38d6918ba | 95 | } |
asong | 1:e4b38d6918ba | 96 | default: { |
asong | 1:e4b38d6918ba | 97 | break; |
asong | 1:e4b38d6918ba | 98 | } |
asong | 1:e4b38d6918ba | 99 | } |
nbaker | 0:d1d36a3da39b | 100 | } |
asong | 1:e4b38d6918ba | 101 | |
nbaker | 0:d1d36a3da39b | 102 | } |
nbaker | 0:d1d36a3da39b | 103 | |
nbaker | 0:d1d36a3da39b | 104 | void ButtonDown(void) |
nbaker | 0:d1d36a3da39b | 105 | { |
asong | 1:e4b38d6918ba | 106 | Screen_Timer.attach(&timout_timer,(SCRN_TIME));//Is this sufficient to reset/restart ticker timer for OLED? |
asong | 1:e4b38d6918ba | 107 | if (OLED_ON == 0) { |
asong | 1:e4b38d6918ba | 108 | OLED_ON = 1; // Screen was off, set to On |
asong | 1:e4b38d6918ba | 109 | update_display(); |
asong | 1:e4b38d6918ba | 110 | } else { |
nbaker | 0:d1d36a3da39b | 111 | |
asong | 1:e4b38d6918ba | 112 | switch(Screen_Num) { |
asong | 1:e4b38d6918ba | 113 | case 0: {// We're in Main Screen |
asong | 3:53c096a80151 | 114 | StartHaptic(); |
asong | 1:e4b38d6918ba | 115 | update_display(); |
asong | 1:e4b38d6918ba | 116 | break; |
asong | 1:e4b38d6918ba | 117 | } |
asong | 3:53c096a80151 | 118 | case 1: {// Second Screen |
asong | 1:e4b38d6918ba | 119 | StartHaptic(); |
asong | 1:e4b38d6918ba | 120 | break; |
asong | 1:e4b38d6918ba | 121 | } |
asong | 1:e4b38d6918ba | 122 | default: { |
asong | 1:e4b38d6918ba | 123 | break; |
asong | 1:e4b38d6918ba | 124 | } |
asong | 1:e4b38d6918ba | 125 | } |
nbaker | 0:d1d36a3da39b | 126 | } |
nbaker | 0:d1d36a3da39b | 127 | } |
nbaker | 0:d1d36a3da39b | 128 | |
nbaker | 0:d1d36a3da39b | 129 | void ButtonRight(void) |
nbaker | 0:d1d36a3da39b | 130 | { |
asong | 1:e4b38d6918ba | 131 | Screen_Timer.attach(&timout_timer,(SCRN_TIME));//Is this sufficient to reset/restart ticker timer for OLED? |
asong | 1:e4b38d6918ba | 132 | if (OLED_ON == 0) { |
asong | 1:e4b38d6918ba | 133 | OLED_ON = 1; // Screen was off, set to On |
asong | 1:e4b38d6918ba | 134 | update_display(); |
asong | 1:e4b38d6918ba | 135 | } else { |
asong | 3:53c096a80151 | 136 | switch(Screen_Num) |
asong | 3:53c096a80151 | 137 | { |
asong | 1:e4b38d6918ba | 138 | case 0: {// We're in Main Screen |
asong | 1:e4b38d6918ba | 139 | StartHaptic(); |
asong | 3:53c096a80151 | 140 | variableExample++; |
asong | 2:824ed4ae8d52 | 141 | update_display(); |
asong | 1:e4b38d6918ba | 142 | break; |
asong | 1:e4b38d6918ba | 143 | } |
asong | 3:53c096a80151 | 144 | default:{ |
asong | 1:e4b38d6918ba | 145 | break; |
asong | 1:e4b38d6918ba | 146 | } |
asong | 1:e4b38d6918ba | 147 | } |
nbaker | 0:d1d36a3da39b | 148 | } |
nbaker | 0:d1d36a3da39b | 149 | } |
nbaker | 0:d1d36a3da39b | 150 | void ButtonLeft(void) |
nbaker | 0:d1d36a3da39b | 151 | { |
asong | 1:e4b38d6918ba | 152 | Screen_Timer.attach(&timout_timer,(SCRN_TIME));//Is this sufficient to reset/restart ticker timer for OLED? |
asong | 1:e4b38d6918ba | 153 | if (OLED_ON == 0) { |
asong | 1:e4b38d6918ba | 154 | OLED_ON = 1; // Screen was off, set to On |
asong | 1:e4b38d6918ba | 155 | update_display(); |
asong | 1:e4b38d6918ba | 156 | } else { |
asong | 1:e4b38d6918ba | 157 | switch(Screen_Num) { |
asong | 1:e4b38d6918ba | 158 | case 0: {// We're in Main Screen |
asong | 3:53c096a80151 | 159 | StartHaptic(); |
asong | 3:53c096a80151 | 160 | variableExample--; |
asong | 1:e4b38d6918ba | 161 | update_display(); |
asong | 1:e4b38d6918ba | 162 | break; |
asong | 1:e4b38d6918ba | 163 | } |
asong | 3:53c096a80151 | 164 | case 1:{ |
asong | 1:e4b38d6918ba | 165 | Screen_Num = 0; |
asong | 1:e4b38d6918ba | 166 | update_display(); |
asong | 3:53c096a80151 | 167 | break; |
asong | 1:e4b38d6918ba | 168 | } |
asong | 1:e4b38d6918ba | 169 | } |
nbaker | 0:d1d36a3da39b | 170 | } |
nbaker | 0:d1d36a3da39b | 171 | } |
nbaker | 0:d1d36a3da39b | 172 | |
nbaker | 0:d1d36a3da39b | 173 | |
nbaker | 0:d1d36a3da39b | 174 | int main() |
nbaker | 0:d1d36a3da39b | 175 | { |
nbaker | 0:d1d36a3da39b | 176 | oled.FillScreen(COLOR_BLACK); // Clear screen |
asong | 1:e4b38d6918ba | 177 | // ***************** Local variables *********************** |
asong | 1:e4b38d6918ba | 178 | // float accel_data[3]; float accel_rms=0.0; |
asong | 1:e4b38d6918ba | 179 | |
nbaker | 0:d1d36a3da39b | 180 | // ************** configure sensor modules ****************** |
nbaker | 0:d1d36a3da39b | 181 | accel.accel_config(); |
nbaker | 0:d1d36a3da39b | 182 | mag.mag_config(); |
nbaker | 0:d1d36a3da39b | 183 | // gyro.gyro_config(); |
asong | 3:53c096a80151 | 184 | // maxim = 1; |
asong | 3:53c096a80151 | 185 | chips = 1; |
asong | 1:e4b38d6918ba | 186 | |
nbaker | 0:d1d36a3da39b | 187 | RED_Led = LED_OFF; |
nbaker | 0:d1d36a3da39b | 188 | GRN_Led = LED_OFF; |
nbaker | 0:d1d36a3da39b | 189 | BLU_Led = LED_OFF; |
nbaker | 0:d1d36a3da39b | 190 | // ***** Register callbacks/interupts to application functions ********* |
nbaker | 0:d1d36a3da39b | 191 | kw40z_device.attach_buttonUp(&ButtonUp); |
nbaker | 0:d1d36a3da39b | 192 | kw40z_device.attach_buttonDown(&ButtonDown); |
nbaker | 0:d1d36a3da39b | 193 | kw40z_device.attach_buttonLeft(&ButtonLeft); |
nbaker | 0:d1d36a3da39b | 194 | kw40z_device.attach_buttonRight(&ButtonRight); |
nbaker | 0:d1d36a3da39b | 195 | |
nbaker | 0:d1d36a3da39b | 196 | // **** Get OLED Class Default Text Properties **************** |
asong | 1:e4b38d6918ba | 197 | oled_text_properties_t textProperties = {0}; |
asong | 1:e4b38d6918ba | 198 | oled.GetTextProperties(&textProperties); |
asong | 1:e4b38d6918ba | 199 | |
nbaker | 0:d1d36a3da39b | 200 | // *********Set text color and screen alignment ************** |
asong | 1:e4b38d6918ba | 201 | textProperties.fontColor = COLOR_WHITE; |
asong | 1:e4b38d6918ba | 202 | textProperties.alignParam = OLED_TEXT_ALIGN_LEFT; |
asong | 1:e4b38d6918ba | 203 | oled.SetTextProperties(&textProperties); |
asong | 1:e4b38d6918ba | 204 | |
nbaker | 0:d1d36a3da39b | 205 | // ************** Display spash screen ********************** |
nbaker | 0:d1d36a3da39b | 206 | textProperties.fontColor = COLOR_RED; |
asong | 1:e4b38d6918ba | 207 | oled.SetTextProperties(&textProperties); |
asong | 3:53c096a80151 | 208 | oled.Label((uint8_t *)"Example",20,5); // Display red "Heart" at x,y |
nbaker | 0:d1d36a3da39b | 209 | |
nbaker | 0:d1d36a3da39b | 210 | textProperties.fontColor = COLOR_WHITE; |
nbaker | 0:d1d36a3da39b | 211 | oled.SetTextProperties(&textProperties); |
nbaker | 0:d1d36a3da39b | 212 | wait(3); // wait 3 seconds |
asong | 1:e4b38d6918ba | 213 | update_display(); // Displays current screen (screen 0) |
nbaker | 0:d1d36a3da39b | 214 | Screen_Timer.attach(&timout_timer,(SCRN_TIME));//start ticker timer for turning off LCD |
asong | 1:e4b38d6918ba | 215 | // ******************* Main Loop ************************* |
nbaker | 0:d1d36a3da39b | 216 | while (true) { |
nbaker | 0:d1d36a3da39b | 217 | |
asong | 1:e4b38d6918ba | 218 | Thread::wait(500); // wait half a sec in each loop |
nbaker | 0:d1d36a3da39b | 219 | } |
nbaker | 0:d1d36a3da39b | 220 | } |
nbaker | 0:d1d36a3da39b | 221 | // ************** end of main() |
nbaker | 0:d1d36a3da39b | 222 | |
nbaker | 0:d1d36a3da39b | 223 | void update_display(void) |
nbaker | 0:d1d36a3da39b | 224 | { |
asong | 1:e4b38d6918ba | 225 | oled_text_properties_t textProperties = {0}; // Need these to change font color |
asong | 1:e4b38d6918ba | 226 | oled.GetTextProperties(&textProperties); // Need these to change font color |
asong | 1:e4b38d6918ba | 227 | switch(Screen_Num) { |
asong | 1:e4b38d6918ba | 228 | case 0: {// Main Screen |
asong | 1:e4b38d6918ba | 229 | oled.FillScreen(COLOR_BLACK); // Clear screen |
asong | 3:53c096a80151 | 230 | oled.Label((uint8_t *)"Test Screen",15,10); // Display "" at x,y |
asong | 3:53c096a80151 | 231 | oled.Label((uint8_t *)"*",85,15); // "*" at x,y |
asong | 3:53c096a80151 | 232 | oled.Label((uint8_t *)"*",85,60); // "*" at x,y |
asong | 3:53c096a80151 | 233 | oled.Label((uint8_t *)"-1",10,80); // Display "Back" at x,y |
asong | 3:53c096a80151 | 234 | oled.Label((uint8_t *)"+1",60,80); //Display "enter" at x,y |
asong | 3:53c096a80151 | 235 | sprintf(display_buff, "%u", variableExample); |
asong | 3:53c096a80151 | 236 | oled.Label((uint8_t *)display_buff,15,40); //Display "enter" at x,y |
asong | 1:e4b38d6918ba | 237 | break; |
asong | 1:e4b38d6918ba | 238 | } |
asong | 1:e4b38d6918ba | 239 | case 1: {// Panic Alert option |
asong | 1:e4b38d6918ba | 240 | oled.FillScreen(COLOR_BLACK); // Clear screen |
asong | 3:53c096a80151 | 241 | oled.Label((uint8_t *)"Second Screen",20,5); // Display at x,y |
asong | 1:e4b38d6918ba | 242 | oled.Label((uint8_t *)"Back",10,80); // Display "Back" at x,y |
asong | 2:824ed4ae8d52 | 243 | } |
nbaker | 0:d1d36a3da39b | 244 | } |
asong | 3:53c096a80151 | 245 | |
asong | 3:53c096a80151 | 246 | |
nbaker | 0:d1d36a3da39b | 247 | } |
asong | 2:824ed4ae8d52 | 248 | |
asong | 2:824ed4ae8d52 | 249 | /***************************************************************************** |
asong | 2:824ed4ae8d52 | 250 | Name: StartHaptic |
asong | 2:824ed4ae8d52 | 251 | Purpose: Cause the HexiHeart device to vibrate for a predetermined amount of |
asong | 2:824ed4ae8d52 | 252 | time |
asong | 2:824ed4ae8d52 | 253 | Inputs: None |
asong | 2:824ed4ae8d52 | 254 | Returns: None |
asong | 2:824ed4ae8d52 | 255 | ******************************************************************************/ |
nbaker | 0:d1d36a3da39b | 256 | void StartHaptic(void) |
nbaker | 0:d1d36a3da39b | 257 | { |
nbaker | 0:d1d36a3da39b | 258 | hapticTimer.start(30); // was originaly 50 |
nbaker | 0:d1d36a3da39b | 259 | haptic = 1; |
nbaker | 0:d1d36a3da39b | 260 | } |
nbaker | 0:d1d36a3da39b | 261 | |
asong | 2:824ed4ae8d52 | 262 | /***************************************************************************** |
asong | 2:824ed4ae8d52 | 263 | Name: StartHaptic |
asong | 2:824ed4ae8d52 | 264 | Purpose: Cause the HexiHeart device to vibrate for x amount of time |
asong | 2:824ed4ae8d52 | 265 | Inputs: An int representing the duration of the vibration |
asong | 2:824ed4ae8d52 | 266 | Returns: None |
asong | 2:824ed4ae8d52 | 267 | ******************************************************************************/ |
asong | 3:53c096a80151 | 268 | |
asong | 1:e4b38d6918ba | 269 | void StartHaptic(int x) |
asong | 1:e4b38d6918ba | 270 | { |
asong | 1:e4b38d6918ba | 271 | hapticTimer.start(x); |
asong | 2:824ed4ae8d52 | 272 | haptic = 1; |
asong | 1:e4b38d6918ba | 273 | } |
asong | 1:e4b38d6918ba | 274 | |
asong | 1:e4b38d6918ba | 275 | void StopHaptic(void const *n) |
asong | 1:e4b38d6918ba | 276 | { |
nbaker | 0:d1d36a3da39b | 277 | haptic = 0; |
nbaker | 0:d1d36a3da39b | 278 | hapticTimer.stop(); |
nbaker | 0:d1d36a3da39b | 279 | } |
asong | 2:824ed4ae8d52 | 280 | |
asong | 2:824ed4ae8d52 | 281 | |
asong | 2:824ed4ae8d52 | 282 | |
asong | 3:53c096a80151 | 283 |