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: TextLCD nRF24L01P mbed
Diff: main.cpp
- Revision:
- 9:53da36425601
- Parent:
- 8:0de75e0480aa
- Child:
- 10:3417715786be
--- a/main.cpp Thu Jan 12 16:43:57 2017 +0000
+++ b/main.cpp Tue Jan 17 21:42:42 2017 +0000
@@ -2,7 +2,9 @@
#include "rtos.h"
#include "TextLCD.h"
#include "custom-chars.h"
+#include "melodies.h"
#include "nRF24L01P.h"
+#include <string>
// Host PC Communication channels
Serial pc(USBTX, USBRX); // tx, rx
@@ -54,6 +56,22 @@
radio.enable();
};
+//TODO: I don't think it needs to be in a separate thread,
+//we probably can just put it into the main loop.
+void radio_recv(void const* args){
+ char rxData[TRANSFER_SIZE+1];
+ while (1) {
+ int rx_bytes=0;
+
+ if(radio.readable(NRF24L01P_PIPE_P1)){
+ rx_bytes = radio.read(NRF24L01P_PIPE_P1, rxData, TRANSFER_SIZE);
+ rxData[TRANSFER_SIZE] = '\0';
+ pc.printf("Received %d >>%s<<\r\n",rx_bytes, rxData);
+ }
+
+ }
+}
+
//Display
void backlightTimeout(void const *arg);
RtosTimer backlightTimer(&backlightTimeout, osTimerPeriodic, (void*)0);
@@ -152,20 +170,122 @@
backlightTimedOut = 1;
}
-//TODO: I don't think it needs to be in a separate thread,
-//we probably can just put it into the main loop.
-void radio_recv(void const* args){
- char rxData[TRANSFER_SIZE+1];
- while (1) {
- int rx_bytes=0;
+//Wi-Fi communication
+#define WIFI_SIZE 1000
+Serial wifi(PA_9, PA_10);
+char wifiData[WIFI_SIZE];
+bool wifiDataReady = false;
+bool readInProgress = false;
+int currentReadIndex = 0;
+
+void wifiCallback() {
+ char c = wifi.getc();
+ if (c == '*') {
+ readInProgress = !readInProgress;
+ wifiData[currentReadIndex] = '\0';
+ currentReadIndex = 0;
+ wifiDataReady = true;
+ } else if (readInProgress) {
+ wifiData[currentReadIndex++] = c;
+ }
+}
+
+std::string wifiGetData(){
+ if (!wifiDataReady)
+ return "";
+
+ std::string result = wifiData;
+ wifiDataReady = false;
+ return result;
+}
+
+std::string httpGETWithRetry(const char* query, float timeout, int retries){
+ Timer t;
+ for (int retry = 0; retry<retries; retry++){
+ wifi.printf(query);
+ t.reset();
+ t.start();
+ while (!wifiDataReady && t <= timeout){
+ wait(0.01f);
+ }
+ pc.printf("http GET trying #%d\r\n", retry);
+ if (wifiDataReady)
+ break;
+ }
+ return wifiGetData();
+}
+
+//Synchronization
+time_t next_sync = 0;
+bool sync_in_progress = false;
+time_t next_alarm = (time_t)-1; //TODO: bardzo brzydki hack
+
+time_t getNextSync(){
+ //TODO: zmiennej czasu nie powinno sie chyba tak modyfikowac
+ return time (NULL) + 123;
+}
- if(radio.readable(NRF24L01P_PIPE_P1)){
- rx_bytes = radio.read(NRF24L01P_PIPE_P1, rxData, TRANSFER_SIZE);
- rxData[TRANSFER_SIZE] = '\0';
- pc.printf("Received %d >>%s<<\r\n",rx_bytes, rxData);
+//Reads are blocking now, so we need to put it into a different thread
+void syncThreadFunction(void const* args){
+ std::string time_string = httpGETWithRetry("GET "
+ "/time/current/ "
+ "HTTP/1.1\r\n"
+ "Host: 10.1.8.202:8080\r\n\r\n", 5.0, 5);
+ if (time_string == ""){
+ lcd.locate(0,1);
+ lcd.printf("Blad synchroniz."); //TODO: to nie bedzie dzialac, trzeba przekazac te dane do obiektu disp
+ }
+ else {
+ set_time(atoi(time_string.c_str()));
+ }
+
+ time_string = httpGETWithRetry("GET "
+ "/alarm/latest/ "
+ "HTTP/1.1\r\n"
+ "Host: 10.1.8.202:8080\r\n\r\n", 5.0, 5); //TODO: Jaki endpoint do alarmow?
+ if (time_string == ""){
+ lcd.locate(0,1);
+ lcd.printf("Blad synchroniz.");
+ }
+ else {
+ next_alarm = atoi(time_string.c_str());
+ }
+
+ next_sync = getNextSync();
+ sync_in_progress = false;
+}
+
+//Alarm
+PwmOut sound(D2);
+bool alarm_playing = false;
+bool alarm_stopped = false;
+
+//We probably could do sound playback with timers and whatnot
+//but why when we have THREADS!
+void alarmThreadFunction(void const* args){
+ //TODO: opcja wyboru dzwonka? whatever, i tak tego nie dokonczymy
+ const int* freq = axelf_freq;
+ const int* per = axelf_per;
+ float bpm = 100.0f; //tempo
+ alarm_stopped = false;
+ while (!alarm_stopped){
+ float base_period = 0.5f;
+ float base_time = bpm / 60.0f;
+ for (int i = 0; i < 100; i++){ //TODO: no bounds checking, -1 sentinel at the end required
+ if (per[i] == -1)
+ break;
+ if (freq[i] != 0) {
+ sound.period(base_period/freq[i]);
+ sound = 0.5f;
+ }
+ else {
+ sound = 0.0f;
+ }
+ wait(base_time/per[i]);
}
-
+ sound = 0.0f;
}
+ alarm_playing = false;
}
Ticker display_update_ticker;
@@ -176,6 +296,26 @@
button.rise(&userButtonPress);
button.fall(&userButtonRelease);
+ wifi.baud(115200);
+ wifi.attach(&wifiCallback);
+
+ pc.printf("Waiting for time\r\n");
+
+ std::string time_string = httpGETWithRetry("GET "
+ "/time/current/ "
+ "HTTP/1.1\r\n"
+ "Host: 10.1.8.202:8080\r\n\r\n", 5.0, 5);
+
+ pc.printf("Get time returned >>%s<<", time_string.c_str());
+
+ if (time_string == ""){
+ lcd.locate(0,1); //Put in top row
+ lcd.printf("Blad synchroniz.");
+ wait(1);
+ }
+ else {
+ set_time(atoi(time_string.c_str()));
+ }
initRadio(6, NRF24L01P_TX_PWR_ZERO_DB, NRF24L01P_DATARATE_250_KBPS);
Thread radio_thread(radio_recv);
@@ -195,7 +335,10 @@
userButtonTimer.stop();
if (userButtonTimer.read_ms() > userButtonLongPress){
pc.printf("User button long pressed");
- disp.backlightOff();
+ //disp.backlightOff(); //that was just debug code anyway
+ if (alarm_playing){
+ alarm_stopped = true;
+ }
}
else {
pc.printf("User button short pressed");
@@ -209,6 +352,18 @@
disp.backlightOff();
}
+ //Synchronize with server
+ if (time(NULL) >= next_sync && !sync_in_progress){
+ sync_in_progress = true;
+ Thread sync_thread(syncThreadFunction);
+ }
+
+ //Check if alarm should be played
+ if (time(NULL) >= next_alarm && !alarm_playing){
+ alarm_playing = true;
+ Thread alarm_thread(alarmThreadFunction);
+ }
+
//Updating display
disp.update();

