From fbf8af56848fa2a1aaecd72efcfb075de2767af9 Mon Sep 17 00:00:00 2001 From: Dirk Jahnke Date: Thu, 15 Nov 2018 13:03:01 +0100 Subject: [PATCH] Sends broadcast time message over radio. --- platformio.ini | 11 +++-- src/clockMsg.h | 14 ++++++ src/display.cpp | 1 - src/fastclock.cpp | 1 + src/fastclock.h | 4 +- src/main.cpp | 2 +- src/radio.cpp | 114 ++++++++++++++++++++++++++++------------------ src/radio.h | 1 + 8 files changed, 97 insertions(+), 51 deletions(-) create mode 100644 src/clockMsg.h diff --git a/platformio.ini b/platformio.ini index db4748c..af4439d 100644 --- a/platformio.ini +++ b/platformio.ini @@ -8,15 +8,18 @@ ; Please visit documentation for the other options and examples ; https://docs.platformio.org/page/projectconf.html -[env:d1_mini_pro] -platform = espressif8266 -board = d1_mini_pro -framework = arduino +[platformio] +env_default = heltec_wifi_kit_8 [env:heltec_wifi_kit_8] platform = espressif8266 board = heltec_wifi_kit_8 framework = arduino +[env:d1_mini_pro] +platform = espressif8266 +board = d1_mini_pro +framework = arduino + [lib_deps] library = WifiManager, RF24, U8g2 diff --git a/src/clockMsg.h b/src/clockMsg.h new file mode 100644 index 0000000..af430d3 --- /dev/null +++ b/src/clockMsg.h @@ -0,0 +1,14 @@ +#ifndef clockMsg_h_included +#define clockMsg_h_included + +#include + +struct clockMsg_s { + uint8_t msgType; + uint8_t hour; + uint8_t minute; + uint8_t second; +}; +#define msgType_Clock 'c' + +#endif diff --git a/src/display.cpp b/src/display.cpp index 540b665..501e8bb 100644 --- a/src/display.cpp +++ b/src/display.cpp @@ -4,7 +4,6 @@ #include "display.h" - // display //U8G2_SSD1306_128X32_UNIVISION_F_HW_I2C u8g2(U8G2_R0, /* reset=*/ 16, /* clock=*/ 5, /* data=*/ 4); U8G2_SSD1306_128X32_UNIVISION_F_HW_I2C u8g2(U8G2_R0, /* reset=16*/ -1, /* clock=*/ 5, /* data=*/ 4); diff --git a/src/fastclock.cpp b/src/fastclock.cpp index 2bc24aa..c4bc69d 100644 --- a/src/fastclock.cpp +++ b/src/fastclock.cpp @@ -67,6 +67,7 @@ void Fastclock::loop(void) { // time has changed, send an update via rf // @TODO implement sending radio message Serial.println("Would send new time"); + radio->broadcastClock(hour, minute, second); } } diff --git a/src/fastclock.h b/src/fastclock.h index e9d0778..563e58d 100644 --- a/src/fastclock.h +++ b/src/fastclock.h @@ -2,13 +2,14 @@ #define fastclock_h_included #include "display.h" +#include "radio.h" #define MIN_TIME_ms_BETWEEN_CLOCK_UPDATES 200 #define DEFAULT_ms_PER_MODEL_SECOND 250 class Fastclock { public: - Fastclock(Display *d): display(d) { weekday=0; hour=0; minute=0; second=0; millisecond=0; msPerModelSecond=DEFAULT_ms_PER_MODEL_SECOND; halted = true; }; + Fastclock(Display *d, Radio *r): display(d), radio(r) { weekday=0; hour=0; minute=0; second=0; millisecond=0; msPerModelSecond=DEFAULT_ms_PER_MODEL_SECOND; halted = true; }; void begin(void); void loop(void); void incrementClockByMilliseconds(int amount); @@ -20,6 +21,7 @@ public: void setClockHalted(bool setToHalt) { halted = setToHalt; display->setClockHalted(halted); }; private: Display *display; + Radio *radio; unsigned long lastTimeTickUsed; // used to calculate model time unsigned long msPerModelSecond; // 500 = twice as fast as real time uint8_t weekday; diff --git a/src/main.cpp b/src/main.cpp index 154b1e3..1e2f151 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -34,8 +34,8 @@ bool shouldSaveConfig = false; bool isMaster = true; Display display; -Fastclock fastclock(&display); Radio radio(&display, true /*isMaster*/); +Fastclock fastclock(&display, &radio); //callback notifying us of the need to save config void saveConfigCallback () { diff --git a/src/radio.cpp b/src/radio.cpp index 5a1f4c6..37eff42 100644 --- a/src/radio.cpp +++ b/src/radio.cpp @@ -3,6 +3,8 @@ #include #include "config.h" #include "radio.h" +#include "clockMsg.h" + static RF24 rf24(PIN_NRF24_CE, PIN_NRF24_CSN); // 10, 8 static byte addresses[][6] = {NETWORK_ADDRESS_MASTER_SEND, NETWORK_ADDRESS_MASTER_RECEIVE}; @@ -11,7 +13,7 @@ void Radio::begin(void) { display->addLogMessage("Start RF24 radio"); pinMode(PIN_NRF24_CSN, OUTPUT); pinMode(PIN_NRF24_CE, OUTPUT); - return; + rf24.begin(); if (rf24.isChipConnected()) { display->addLogMessage("*** RF chip found"); } else { display->addLogMessage("*** ERROR: RF chip not found!"); } @@ -24,11 +26,12 @@ void Radio::begin(void) { rf24.openWritingPipe(addresses[0]); rf24.openReadingPipe(1, addresses[1]); rf24.startListening(); - rf24.printDetails(); + Serial.println("*** Check"); + //rf24.printDetails(); + rf24.powerUp(); // @TODO: real random seed! //randomSeed(analogRead(0)); //randomSeed(22); - rf24.powerUp(); Serial.print("*** RF payload size="); Serial.print(rf24.getPayloadSize()); Serial.println(" bytes"); if (rf24.testCarrier() || rf24.testRPD()) { display->addLogMessage("*** Carrier/RPD seen on radio"); } if (rf24.failureDetected) { display->addLogMessage("*** Radio error detected!"); } @@ -50,57 +53,80 @@ void Radio::begin(void) { rf24.startListening(); } +static bool inTX=1, inRX=0, role=inRX; + +static void switchToSenderRole(RF24 radio) +{ + Serial.println("*** master: CHANGING TO TRANSMIT ROLE"); + radio.openWritingPipe(addresses[1]); + radio.openReadingPipe(1,addresses[0]); + radio.stopListening(); + role = inTX; // Become the primary transmitter (ping out) +} + +static void switchToReceiverRole(RF24 radio) +{ + Serial.println("*** master: CHANGING TO RECEIVER ROLE"); + radio.openWritingPipe(addresses[0]); + radio.openReadingPipe(1,addresses[1]); + radio.startListening(); + role = inRX; // Become the primary receiver (pong back) +} + +static int sendFailedCounter = 0; +static unsigned long stopTime = 0, pauseTime = 0; + +void Radio::broadcastClock(int hour, int minute, int second) { + struct clockMsg_s clockMsg; + + clockMsg.msgType = msgType_Clock; + clockMsg.hour = hour; + clockMsg.minute = minute; + clockMsg.second = second; + switchToSenderRole(rf24); + if (!rf24.write(&clockMsg, sizeof(clockMsg), true /*multicast*/)) { + sendFailedCounter++; + Serial.print("*** ERROR: failed to send clock msg for "); Serial.print(hour); Serial.print(":"); Serial.print(minute); Serial.print(":"); Serial.println(second); + } + //This is only required when NO ACK ( enableAutoAck(0) ) payloads are used + if (millis() - pauseTime > 3) { + pauseTime = millis(); + rf24.txStandBy(); // Need to drop out of TX mode every 4ms if sending a steady stream of multicast data + //delayMicroseconds(130); // This gives the PLL time to sync back up + } + stopTime = millis(); + //This should be called to wait for completion and put the radio in standby mode after transmission, returns 0 if data still in FIFO (timed out), 1 if success + if (!rf24.txStandBy()) { sendFailedCounter += 3; } //Standby, block only until FIFO empty or auto-retry timeout. Flush TX FIFO if failed + //radio.txStandBy(1000); //Standby, using extended timeout period of 1 second + + Serial.print("*** send finished, fail-counter="); Serial.println(sendFailedCounter); +} void Radio::loop(void) { - #if 0 // put your main code here, to run repeatedly: /****************** Ping Out Role ***************************/ if (isMaster) { + switchToReceiverRole(rf24); + if (rf24.available()) { + struct clockMsg_s clockMsg; + rf24.read(&clockMsg, sizeof(struct clockMsg_s)); - radio.stopListening(); - - Serial.println(F("Now sending")); - - unsigned long start_time = micros(); - if (!radio.write(&start_time, sizeof(unsigned long))) { - Serial.println(F("failed")); - } - - radio.startListening(); - - unsigned long started_waiting_at = micros(); - boolean timeout = false; - - while (!radio.available()) { - if (micros() - started_waiting_at > 200000 ) { // If waited longer than 200ms, indicate timeout and exit while loop - timeout = true; - break; - } - } - - if (timeout) { - Serial.println(F("Failed, response timed out.")); - } else { - unsigned long got_time; - radio.read( &got_time, sizeof(unsigned long) ); - unsigned long end_time = micros(); - - // Spew it - Serial.print(F("Sent ")); - Serial.print(start_time); - Serial.print(F(", Got response ")); - Serial.print(got_time); - Serial.print(F(", Round-trip delay ")); - Serial.print(end_time-start_time); - Serial.println(F(" microseconds")); - } - - // Try again 1s later - delay(1000); + // Spew it + Serial.print(F("Received clock message, type=")); + Serial.print(clockMsg.msgType); + Serial.print(F(", time=")); + Serial.print(clockMsg.hour); + Serial.print(":"); + Serial.print(clockMsg.minute); + Serial.print(":"); + Serial.println(clockMsg.second); } + } + #if 0 + /****************** Pong Back Role ***************************/ if (!isMaster) diff --git a/src/radio.h b/src/radio.h index 2cf0c5f..c35c57e 100644 --- a/src/radio.h +++ b/src/radio.h @@ -8,6 +8,7 @@ public: Radio(Display *d, bool _isMaster):display(d), isMaster(_isMaster) { }; void begin(void); void loop(void); + void broadcastClock(int hour, int minute, int second); private: Display *display; bool isMaster;