![](/media/cache/img/default_profile.jpg.50x50_q85.jpg)
run this here
Dependencies: Hexi_KW40Z Hexi_OLED_SSD1351
main.cpp
- Committer:
- trhackett
- Date:
- 2018-06-14
- Revision:
- 4:1ae9f76749b9
- Parent:
- 3:f34bbdea0786
File content as of revision 4:1ae9f76749b9:
#include "mbed.h" #include "Hexi_KW40Z.h" #include "Hexi_OLED_SSD1351.h" #include "Ticker.h" #include "timeHelp.h" void AlertReceived(uint8_t *data, uint8_t length); void displayTimeToScreen(); void clearScreen(); void updateError(); void updateDisplayString(); void txTask(); KW40Z kw40z_device(PTE24, PTE25); // oled driver and its text buffer SSD1351 oled(PTB22,PTB21,PTC13,PTB20,PTE6, PTD15); char text[20]; const float interval = 0.1; int numTicks = 0; int prevNumTicks = 0; float intervalError = 0.0; char prevTime[11] = "00:00:00.0"; char displayTime[11] = "00:00:00.0"; // important to know whether or not we've synced at least once with pi // because we don't have an initial time until we hear from pi bool firstSync = true; bool syncedTwice = false; DigitalOut pwm(PTA10); // bluetooth thread Thread txThread; // event queue for displaying the time EventQueue displayQueue; // event queue for receiving the time EventQueue receiveTimeQueue; int main() { kw40z_device.attach_alert(&AlertReceived); // thread that displays the time for us Thread displayThread; displayThread.start(callback(&displayQueue, &EventQueue::dispatch_forever)); // thread that responds to pi's time updates Thread receiveTimeThread; receiveTimeThread.start(callback(&receiveTimeQueue, &EventQueue::dispatch_forever)); // initialize the screen to blank displayQueue.call(&clearScreen); displayQueue.call(&displayTimeToScreen); // ticker that increments the time Ticker updateTimeTicker; updateTimeTicker.attach(receiveTimeQueue.event(&updateDisplayString), interval); // start toggling bluetooth so you can connect txThread.start(txTask); wait(osWaitForever); } /******************************End of Main*************************************/ // initialize the screen to black void clearScreen() { oled.FillScreen(COLOR_BLACK); } void displayTimeToScreen() { /* Get OLED Class Default Text Properties */ oled_text_properties_t textProperties = {0}; oled.GetTextProperties(&textProperties); /* Change font color to Blue */ textProperties.fontColor = COLOR_BLUE; oled.SetTextProperties(&textProperties); if (secondsAreEven(displayTime)) { pwm = 0 ; } else { pwm = 1; } /* Display time Label at x=20,y=40 */ strcpy((char *) text, displayTime); oled.Label((uint8_t *)text,20,40); } // the alert that we've received is always the updated time from raspberry pi // so we should put that in display time, calculate the new interval, and // display the new time void AlertReceived(uint8_t *data, uint8_t length) { char buf[10]; for (int i = 0; i < 10; ++i) { buf[i] = data[i]; } // copy in the new data, storing the old only if there is old to store for (int i = 0; i < 10; i++) { if (!firstSync) { prevTime[i] = displayTime[i]; } else { prevTime[i] = buf[i]; // if you get here, then you've synced once if (!syncedTwice) { syncedTwice = true; } } displayTime[i] = buf[i]; } // reset numTicks prevNumTicks = numTicks; numTicks = 0; // update the error as long as it isn't your first sync ... need two times if (!firstSync && syncedTwice) { receiveTimeQueue.call(&updateError); } firstSync = false; } // error is the total amount that hexiwear was off by // averaged over all of the ticks ... moving forward we // can add the error into out calculation of the current // time and hopefully it will be more accurate. void updateError() { // float secsToAdd = prevNumTicks * (interval + intervalError); float T1 = currTimeSecs(displayTime); float T0 = currTimeSecs(prevTime); intervalError = (T1 - (T0+secsToAdd)) / prevNumTicks; } int numPrints = 20; // you update the display string every 0.1 seconds, to add to the // number of ticks, calculate the offset from the previous time, // and display it void updateDisplayString() { numTicks++; float offset = numTicks * (interval + intervalError); addSecondsToCurrentTime(prevTime, displayTime, offset); displayQueue.call(&displayTimeToScreen); } // take care of the bluetooth toggling so that it can conect void txTask(){ while (true) { // there is about a half second delay before the hexiwear // realizes that the link state is down, so if you ever // do realize that, you should toggle the advertisement // state right away, I think. NO what you should do it, if // you ever realize that the link is down, wait a half a second // and then toggle advertisement mode to let it refresh // it seems like this doesn't perform quite as well, but I think // it is more robust... if (kw40z_device.GetLinkState() == 0) { Thread::wait(2500); if (kw40z_device.GetLinkState() == 0) { kw40z_device.ToggleAdvertisementMode(); } } Thread::wait(5000); } }