Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: Hexi_KW40Z Hexi_OLED_SSD1351
main.cpp
00001 #include "mbed.h" 00002 #include "Hexi_KW40Z.h" 00003 #include "Hexi_OLED_SSD1351.h" 00004 #include "Ticker.h" 00005 #include "timeHelp.h" 00006 00007 void AlertReceived(uint8_t *data, uint8_t length); 00008 void displayTimeToScreen(); 00009 void clearScreen(); 00010 void updateError(); 00011 void updateDisplayString(); 00012 void txTask(); 00013 00014 KW40Z kw40z_device(PTE24, PTE25); 00015 00016 // oled driver and its text buffer 00017 SSD1351 oled(PTB22,PTB21,PTC13,PTB20,PTE6, PTD15); 00018 char text[20]; 00019 00020 const float interval = 0.1; 00021 int numTicks = 0; 00022 int prevNumTicks = 0; 00023 float intervalError = 0.0; 00024 00025 char prevTime[11] = "00:00:00.0"; 00026 char displayTime[11] = "00:00:00.0"; 00027 00028 // important to know whether or not we've synced at least once with pi 00029 // because we don't have an initial time until we hear from pi 00030 bool firstSync = true; 00031 bool syncedTwice = false; 00032 00033 DigitalOut pwm(PTA10); 00034 00035 00036 // bluetooth thread 00037 Thread txThread; 00038 00039 // event queue for displaying the time 00040 EventQueue displayQueue; 00041 // event queue for receiving the time 00042 EventQueue receiveTimeQueue; 00043 00044 int main() { 00045 00046 kw40z_device.attach_alert(&AlertReceived); 00047 00048 // thread that displays the time for us 00049 Thread displayThread; 00050 displayThread.start(callback(&displayQueue, &EventQueue::dispatch_forever)); 00051 00052 // thread that responds to pi's time updates 00053 Thread receiveTimeThread; 00054 receiveTimeThread.start(callback(&receiveTimeQueue, &EventQueue::dispatch_forever)); 00055 00056 // initialize the screen to blank 00057 displayQueue.call(&clearScreen); 00058 displayQueue.call(&displayTimeToScreen); 00059 00060 // ticker that increments the time 00061 Ticker updateTimeTicker; 00062 updateTimeTicker.attach(receiveTimeQueue.event(&updateDisplayString), interval); 00063 00064 // start toggling bluetooth so you can connect 00065 txThread.start(txTask); 00066 00067 wait(osWaitForever); 00068 } 00069 00070 /******************************End of Main*************************************/ 00071 00072 // initialize the screen to black 00073 void clearScreen() { 00074 oled.FillScreen(COLOR_BLACK); 00075 } 00076 00077 void displayTimeToScreen() { 00078 /* Get OLED Class Default Text Properties */ 00079 oled_text_properties_t textProperties = {0}; 00080 oled.GetTextProperties(&textProperties); 00081 00082 /* Change font color to Blue */ 00083 textProperties.fontColor = COLOR_BLUE; 00084 oled.SetTextProperties(&textProperties); 00085 00086 if (secondsAreEven(displayTime)) { 00087 pwm = 0 ; 00088 } else { 00089 pwm = 1; 00090 } 00091 00092 /* Display time Label at x=20,y=40 */ 00093 strcpy((char *) text, displayTime); 00094 oled.Label((uint8_t *)text,20,40); 00095 } 00096 00097 // the alert that we've received is always the updated time from raspberry pi 00098 // so we should put that in display time, calculate the new interval, and 00099 // display the new time 00100 void AlertReceived(uint8_t *data, uint8_t length) { 00101 00102 char buf[10]; 00103 for (int i = 0; i < 10; ++i) { 00104 buf[i] = data[i]; 00105 } 00106 00107 // copy in the new data, storing the old only if there is old to store 00108 for (int i = 0; i < 10; i++) { 00109 if (!firstSync) { 00110 prevTime[i] = displayTime[i]; 00111 } 00112 00113 else { 00114 prevTime[i] = buf[i]; 00115 00116 // if you get here, then you've synced once 00117 if (!syncedTwice) { 00118 syncedTwice = true; 00119 } 00120 } 00121 displayTime[i] = buf[i]; 00122 } 00123 00124 // reset numTicks 00125 prevNumTicks = numTicks; 00126 numTicks = 0; 00127 00128 // update the error as long as it isn't your first sync ... need two times 00129 if (!firstSync && syncedTwice) { 00130 receiveTimeQueue.call(&updateError); 00131 } 00132 00133 firstSync = false; 00134 } 00135 00136 // error is the total amount that hexiwear was off by 00137 // averaged over all of the ticks ... moving forward we 00138 // can add the error into out calculation of the current 00139 // time and hopefully it will be more accurate. 00140 void updateError() { 00141 00142 // 00143 float secsToAdd = prevNumTicks * (interval + intervalError); 00144 00145 float T1 = currTimeSecs(displayTime); 00146 float T0 = currTimeSecs(prevTime); 00147 00148 intervalError = (T1 - (T0+secsToAdd)) / prevNumTicks; 00149 } 00150 00151 int numPrints = 20; 00152 00153 // you update the display string every 0.1 seconds, to add to the 00154 // number of ticks, calculate the offset from the previous time, 00155 // and display it 00156 void updateDisplayString() { 00157 numTicks++; 00158 00159 float offset = numTicks * (interval + intervalError); 00160 00161 addSecondsToCurrentTime(prevTime, displayTime, offset); 00162 00163 displayQueue.call(&displayTimeToScreen); 00164 } 00165 00166 // take care of the bluetooth toggling so that it can conect 00167 void txTask(){ 00168 00169 while (true) 00170 { 00171 // there is about a half second delay before the hexiwear 00172 // realizes that the link state is down, so if you ever 00173 // do realize that, you should toggle the advertisement 00174 // state right away, I think. NO what you should do it, if 00175 // you ever realize that the link is down, wait a half a second 00176 // and then toggle advertisement mode to let it refresh 00177 00178 // it seems like this doesn't perform quite as well, but I think 00179 // it is more robust... 00180 if (kw40z_device.GetLinkState() == 0) { 00181 Thread::wait(2500); 00182 if (kw40z_device.GetLinkState() == 0) { 00183 kw40z_device.ToggleAdvertisementMode(); 00184 } 00185 } 00186 00187 Thread::wait(5000); 00188 } 00189 }
Generated on Mon Jul 18 2022 04:23:21 by
1.7.2