run this here

Dependencies:   Hexi_KW40Z Hexi_OLED_SSD1351

Committer:
trhackett
Date:
Thu Jun 14 19:39:23 2018 +0000
Revision:
4:1ae9f76749b9
Parent:
3:f34bbdea0786
current time mbed post comp arch

Who changed what in which revision?

UserRevisionLine numberNew contents of line
trhackett 0:2b94f7017e4e 1 #include "mbed.h"
trhackett 3:f34bbdea0786 2 #include "Hexi_KW40Z.h"
trhackett 3:f34bbdea0786 3 #include "Hexi_OLED_SSD1351.h"
trhackett 0:2b94f7017e4e 4 #include "Ticker.h"
trhackett 3:f34bbdea0786 5 #include "timeHelp.h"
trhackett 0:2b94f7017e4e 6
trhackett 3:f34bbdea0786 7 void AlertReceived(uint8_t *data, uint8_t length);
trhackett 3:f34bbdea0786 8 void displayTimeToScreen();
trhackett 3:f34bbdea0786 9 void clearScreen();
trhackett 3:f34bbdea0786 10 void updateError();
trhackett 3:f34bbdea0786 11 void updateDisplayString();
trhackett 3:f34bbdea0786 12 void txTask();
trhackett 0:2b94f7017e4e 13
trhackett 3:f34bbdea0786 14 KW40Z kw40z_device(PTE24, PTE25);
trhackett 0:2b94f7017e4e 15
trhackett 3:f34bbdea0786 16 // oled driver and its text buffer
trhackett 3:f34bbdea0786 17 SSD1351 oled(PTB22,PTB21,PTC13,PTB20,PTE6, PTD15);
trhackett 3:f34bbdea0786 18 char text[20];
trhackett 3:f34bbdea0786 19
trhackett 3:f34bbdea0786 20 const float interval = 0.1;
trhackett 3:f34bbdea0786 21 int numTicks = 0;
trhackett 3:f34bbdea0786 22 int prevNumTicks = 0;
trhackett 4:1ae9f76749b9 23 float intervalError = 0.0;
trhackett 0:2b94f7017e4e 24
trhackett 3:f34bbdea0786 25 char prevTime[11] = "00:00:00.0";
trhackett 3:f34bbdea0786 26 char displayTime[11] = "00:00:00.0";
trhackett 0:2b94f7017e4e 27
trhackett 3:f34bbdea0786 28 // important to know whether or not we've synced at least once with pi
trhackett 3:f34bbdea0786 29 // because we don't have an initial time until we hear from pi
trhackett 3:f34bbdea0786 30 bool firstSync = true;
trhackett 3:f34bbdea0786 31 bool syncedTwice = false;
trhackett 3:f34bbdea0786 32
trhackett 3:f34bbdea0786 33 DigitalOut pwm(PTA10);
trhackett 0:2b94f7017e4e 34
trhackett 3:f34bbdea0786 35
trhackett 3:f34bbdea0786 36 // bluetooth thread
trhackett 3:f34bbdea0786 37 Thread txThread;
trhackett 0:2b94f7017e4e 38
trhackett 3:f34bbdea0786 39 // event queue for displaying the time
trhackett 3:f34bbdea0786 40 EventQueue displayQueue;
trhackett 3:f34bbdea0786 41 // event queue for receiving the time
trhackett 3:f34bbdea0786 42 EventQueue receiveTimeQueue;
trhackett 0:2b94f7017e4e 43
trhackett 3:f34bbdea0786 44 int main() {
trhackett 3:f34bbdea0786 45
trhackett 3:f34bbdea0786 46 kw40z_device.attach_alert(&AlertReceived);
trhackett 3:f34bbdea0786 47
trhackett 3:f34bbdea0786 48 // thread that displays the time for us
trhackett 3:f34bbdea0786 49 Thread displayThread;
trhackett 3:f34bbdea0786 50 displayThread.start(callback(&displayQueue, &EventQueue::dispatch_forever));
trhackett 3:f34bbdea0786 51
trhackett 3:f34bbdea0786 52 // thread that responds to pi's time updates
trhackett 3:f34bbdea0786 53 Thread receiveTimeThread;
trhackett 3:f34bbdea0786 54 receiveTimeThread.start(callback(&receiveTimeQueue, &EventQueue::dispatch_forever));
trhackett 3:f34bbdea0786 55
trhackett 3:f34bbdea0786 56 // initialize the screen to blank
trhackett 3:f34bbdea0786 57 displayQueue.call(&clearScreen);
trhackett 3:f34bbdea0786 58 displayQueue.call(&displayTimeToScreen);
trhackett 3:f34bbdea0786 59
trhackett 3:f34bbdea0786 60 // ticker that increments the time
trhackett 3:f34bbdea0786 61 Ticker updateTimeTicker;
trhackett 3:f34bbdea0786 62 updateTimeTicker.attach(receiveTimeQueue.event(&updateDisplayString), interval);
trhackett 3:f34bbdea0786 63
trhackett 3:f34bbdea0786 64 // start toggling bluetooth so you can connect
trhackett 3:f34bbdea0786 65 txThread.start(txTask);
trhackett 3:f34bbdea0786 66
trhackett 3:f34bbdea0786 67 wait(osWaitForever);
trhackett 0:2b94f7017e4e 68 }
trhackett 0:2b94f7017e4e 69
trhackett 3:f34bbdea0786 70 /******************************End of Main*************************************/
trhackett 3:f34bbdea0786 71
trhackett 3:f34bbdea0786 72 // initialize the screen to black
trhackett 3:f34bbdea0786 73 void clearScreen() {
trhackett 3:f34bbdea0786 74 oled.FillScreen(COLOR_BLACK);
trhackett 0:2b94f7017e4e 75 }
trhackett 0:2b94f7017e4e 76
trhackett 3:f34bbdea0786 77 void displayTimeToScreen() {
trhackett 3:f34bbdea0786 78 /* Get OLED Class Default Text Properties */
trhackett 3:f34bbdea0786 79 oled_text_properties_t textProperties = {0};
trhackett 3:f34bbdea0786 80 oled.GetTextProperties(&textProperties);
trhackett 0:2b94f7017e4e 81
trhackett 3:f34bbdea0786 82 /* Change font color to Blue */
trhackett 3:f34bbdea0786 83 textProperties.fontColor = COLOR_BLUE;
trhackett 3:f34bbdea0786 84 oled.SetTextProperties(&textProperties);
trhackett 3:f34bbdea0786 85
trhackett 3:f34bbdea0786 86 if (secondsAreEven(displayTime)) {
trhackett 3:f34bbdea0786 87 pwm = 0 ;
trhackett 3:f34bbdea0786 88 } else {
trhackett 3:f34bbdea0786 89 pwm = 1;
trhackett 0:2b94f7017e4e 90 }
trhackett 0:2b94f7017e4e 91
trhackett 3:f34bbdea0786 92 /* Display time Label at x=20,y=40 */
trhackett 3:f34bbdea0786 93 strcpy((char *) text, displayTime);
trhackett 3:f34bbdea0786 94 oled.Label((uint8_t *)text,20,40);
trhackett 0:2b94f7017e4e 95 }
trhackett 0:2b94f7017e4e 96
trhackett 3:f34bbdea0786 97 // the alert that we've received is always the updated time from raspberry pi
trhackett 3:f34bbdea0786 98 // so we should put that in display time, calculate the new interval, and
trhackett 3:f34bbdea0786 99 // display the new time
trhackett 3:f34bbdea0786 100 void AlertReceived(uint8_t *data, uint8_t length) {
trhackett 3:f34bbdea0786 101
trhackett 3:f34bbdea0786 102 char buf[10];
trhackett 3:f34bbdea0786 103 for (int i = 0; i < 10; ++i) {
trhackett 3:f34bbdea0786 104 buf[i] = data[i];
trhackett 3:f34bbdea0786 105 }
trhackett 0:2b94f7017e4e 106
trhackett 3:f34bbdea0786 107 // copy in the new data, storing the old only if there is old to store
trhackett 3:f34bbdea0786 108 for (int i = 0; i < 10; i++) {
trhackett 3:f34bbdea0786 109 if (!firstSync) {
trhackett 3:f34bbdea0786 110 prevTime[i] = displayTime[i];
trhackett 3:f34bbdea0786 111 }
trhackett 3:f34bbdea0786 112
trhackett 3:f34bbdea0786 113 else {
trhackett 3:f34bbdea0786 114 prevTime[i] = buf[i];
trhackett 3:f34bbdea0786 115
trhackett 3:f34bbdea0786 116 // if you get here, then you've synced once
trhackett 3:f34bbdea0786 117 if (!syncedTwice) {
trhackett 3:f34bbdea0786 118 syncedTwice = true;
trhackett 3:f34bbdea0786 119 }
trhackett 3:f34bbdea0786 120 }
trhackett 3:f34bbdea0786 121 displayTime[i] = buf[i];
trhackett 0:2b94f7017e4e 122 }
trhackett 0:2b94f7017e4e 123
trhackett 3:f34bbdea0786 124 // reset numTicks
trhackett 3:f34bbdea0786 125 prevNumTicks = numTicks;
trhackett 3:f34bbdea0786 126 numTicks = 0;
trhackett 3:f34bbdea0786 127
trhackett 3:f34bbdea0786 128 // update the error as long as it isn't your first sync ... need two times
trhackett 3:f34bbdea0786 129 if (!firstSync && syncedTwice) {
trhackett 3:f34bbdea0786 130 receiveTimeQueue.call(&updateError);
trhackett 0:2b94f7017e4e 131 }
trhackett 0:2b94f7017e4e 132
trhackett 3:f34bbdea0786 133 firstSync = false;
trhackett 3:f34bbdea0786 134 }
trhackett 3:f34bbdea0786 135
trhackett 3:f34bbdea0786 136 // error is the total amount that hexiwear was off by
trhackett 3:f34bbdea0786 137 // averaged over all of the ticks ... moving forward we
trhackett 3:f34bbdea0786 138 // can add the error into out calculation of the current
trhackett 3:f34bbdea0786 139 // time and hopefully it will be more accurate.
trhackett 3:f34bbdea0786 140 void updateError() {
trhackett 0:2b94f7017e4e 141
trhackett 4:1ae9f76749b9 142 //
trhackett 4:1ae9f76749b9 143 float secsToAdd = prevNumTicks * (interval + intervalError);
trhackett 3:f34bbdea0786 144
trhackett 3:f34bbdea0786 145 float T1 = currTimeSecs(displayTime);
trhackett 3:f34bbdea0786 146 float T0 = currTimeSecs(prevTime);
trhackett 3:f34bbdea0786 147
trhackett 4:1ae9f76749b9 148 intervalError = (T1 - (T0+secsToAdd)) / prevNumTicks;
trhackett 0:2b94f7017e4e 149 }
trhackett 0:2b94f7017e4e 150
trhackett 3:f34bbdea0786 151 int numPrints = 20;
trhackett 3:f34bbdea0786 152
trhackett 3:f34bbdea0786 153 // you update the display string every 0.1 seconds, to add to the
trhackett 3:f34bbdea0786 154 // number of ticks, calculate the offset from the previous time,
trhackett 3:f34bbdea0786 155 // and display it
trhackett 3:f34bbdea0786 156 void updateDisplayString() {
trhackett 3:f34bbdea0786 157 numTicks++;
trhackett 0:2b94f7017e4e 158
trhackett 4:1ae9f76749b9 159 float offset = numTicks * (interval + intervalError);
trhackett 0:2b94f7017e4e 160
trhackett 3:f34bbdea0786 161 addSecondsToCurrentTime(prevTime, displayTime, offset);
trhackett 0:2b94f7017e4e 162
trhackett 3:f34bbdea0786 163 displayQueue.call(&displayTimeToScreen);
trhackett 3:f34bbdea0786 164 }
trhackett 3:f34bbdea0786 165
trhackett 3:f34bbdea0786 166 // take care of the bluetooth toggling so that it can conect
trhackett 3:f34bbdea0786 167 void txTask(){
trhackett 3:f34bbdea0786 168
trhackett 3:f34bbdea0786 169 while (true)
trhackett 3:f34bbdea0786 170 {
trhackett 3:f34bbdea0786 171 // there is about a half second delay before the hexiwear
trhackett 3:f34bbdea0786 172 // realizes that the link state is down, so if you ever
trhackett 3:f34bbdea0786 173 // do realize that, you should toggle the advertisement
trhackett 3:f34bbdea0786 174 // state right away, I think. NO what you should do it, if
trhackett 3:f34bbdea0786 175 // you ever realize that the link is down, wait a half a second
trhackett 3:f34bbdea0786 176 // and then toggle advertisement mode to let it refresh
trhackett 3:f34bbdea0786 177
trhackett 3:f34bbdea0786 178 // it seems like this doesn't perform quite as well, but I think
trhackett 3:f34bbdea0786 179 // it is more robust...
trhackett 3:f34bbdea0786 180 if (kw40z_device.GetLinkState() == 0) {
trhackett 3:f34bbdea0786 181 Thread::wait(2500);
trhackett 3:f34bbdea0786 182 if (kw40z_device.GetLinkState() == 0) {
trhackett 3:f34bbdea0786 183 kw40z_device.ToggleAdvertisementMode();
trhackett 3:f34bbdea0786 184 }
trhackett 3:f34bbdea0786 185 }
trhackett 3:f34bbdea0786 186
trhackett 3:f34bbdea0786 187 Thread::wait(5000);
trhackett 3:f34bbdea0786 188 }
trhackett 2:75253a344332 189 }