Sends broadcast time message over radio.

This commit is contained in:
Dirk Jahnke 2018-11-15 13:03:01 +01:00
parent 672d5baf23
commit fbf8af5684
8 changed files with 97 additions and 51 deletions

View File

@ -8,15 +8,18 @@
; Please visit documentation for the other options and examples ; Please visit documentation for the other options and examples
; https://docs.platformio.org/page/projectconf.html ; https://docs.platformio.org/page/projectconf.html
[env:d1_mini_pro] [platformio]
platform = espressif8266 env_default = heltec_wifi_kit_8
board = d1_mini_pro
framework = arduino
[env:heltec_wifi_kit_8] [env:heltec_wifi_kit_8]
platform = espressif8266 platform = espressif8266
board = heltec_wifi_kit_8 board = heltec_wifi_kit_8
framework = arduino framework = arduino
[env:d1_mini_pro]
platform = espressif8266
board = d1_mini_pro
framework = arduino
[lib_deps] [lib_deps]
library = WifiManager, RF24, U8g2 library = WifiManager, RF24, U8g2

14
src/clockMsg.h Normal file
View File

@ -0,0 +1,14 @@
#ifndef clockMsg_h_included
#define clockMsg_h_included
#include <Arduino.h>
struct clockMsg_s {
uint8_t msgType;
uint8_t hour;
uint8_t minute;
uint8_t second;
};
#define msgType_Clock 'c'
#endif

View File

@ -4,7 +4,6 @@
#include "display.h" #include "display.h"
// display // 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, /* clock=*/ 5, /* data=*/ 4);
U8G2_SSD1306_128X32_UNIVISION_F_HW_I2C u8g2(U8G2_R0, /* reset=16*/ -1, /* clock=*/ 5, /* data=*/ 4); U8G2_SSD1306_128X32_UNIVISION_F_HW_I2C u8g2(U8G2_R0, /* reset=16*/ -1, /* clock=*/ 5, /* data=*/ 4);

View File

@ -67,6 +67,7 @@ void Fastclock::loop(void) {
// time has changed, send an update via rf // time has changed, send an update via rf
// @TODO implement sending radio message // @TODO implement sending radio message
Serial.println("Would send new time"); Serial.println("Would send new time");
radio->broadcastClock(hour, minute, second);
} }
} }

View File

@ -2,13 +2,14 @@
#define fastclock_h_included #define fastclock_h_included
#include "display.h" #include "display.h"
#include "radio.h"
#define MIN_TIME_ms_BETWEEN_CLOCK_UPDATES 200 #define MIN_TIME_ms_BETWEEN_CLOCK_UPDATES 200
#define DEFAULT_ms_PER_MODEL_SECOND 250 #define DEFAULT_ms_PER_MODEL_SECOND 250
class Fastclock { class Fastclock {
public: 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 begin(void);
void loop(void); void loop(void);
void incrementClockByMilliseconds(int amount); void incrementClockByMilliseconds(int amount);
@ -20,6 +21,7 @@ public:
void setClockHalted(bool setToHalt) { halted = setToHalt; display->setClockHalted(halted); }; void setClockHalted(bool setToHalt) { halted = setToHalt; display->setClockHalted(halted); };
private: private:
Display *display; Display *display;
Radio *radio;
unsigned long lastTimeTickUsed; // used to calculate model time unsigned long lastTimeTickUsed; // used to calculate model time
unsigned long msPerModelSecond; // 500 = twice as fast as real time unsigned long msPerModelSecond; // 500 = twice as fast as real time
uint8_t weekday; uint8_t weekday;

View File

@ -34,8 +34,8 @@ bool shouldSaveConfig = false;
bool isMaster = true; bool isMaster = true;
Display display; Display display;
Fastclock fastclock(&display);
Radio radio(&display, true /*isMaster*/); Radio radio(&display, true /*isMaster*/);
Fastclock fastclock(&display, &radio);
//callback notifying us of the need to save config //callback notifying us of the need to save config
void saveConfigCallback () { void saveConfigCallback () {

View File

@ -3,6 +3,8 @@
#include <RF24.h> #include <RF24.h>
#include "config.h" #include "config.h"
#include "radio.h" #include "radio.h"
#include "clockMsg.h"
static RF24 rf24(PIN_NRF24_CE, PIN_NRF24_CSN); // 10, 8 static RF24 rf24(PIN_NRF24_CE, PIN_NRF24_CSN); // 10, 8
static byte addresses[][6] = {NETWORK_ADDRESS_MASTER_SEND, NETWORK_ADDRESS_MASTER_RECEIVE}; 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"); display->addLogMessage("Start RF24 radio");
pinMode(PIN_NRF24_CSN, OUTPUT); pinMode(PIN_NRF24_CSN, OUTPUT);
pinMode(PIN_NRF24_CE, OUTPUT); pinMode(PIN_NRF24_CE, OUTPUT);
return;
rf24.begin(); rf24.begin();
if (rf24.isChipConnected()) { display->addLogMessage("*** RF chip found"); } if (rf24.isChipConnected()) { display->addLogMessage("*** RF chip found"); }
else { display->addLogMessage("*** ERROR: RF chip not found!"); } else { display->addLogMessage("*** ERROR: RF chip not found!"); }
@ -24,11 +26,12 @@ void Radio::begin(void) {
rf24.openWritingPipe(addresses[0]); rf24.openWritingPipe(addresses[0]);
rf24.openReadingPipe(1, addresses[1]); rf24.openReadingPipe(1, addresses[1]);
rf24.startListening(); rf24.startListening();
rf24.printDetails(); Serial.println("*** Check");
//rf24.printDetails();
rf24.powerUp();
// @TODO: real random seed! // @TODO: real random seed!
//randomSeed(analogRead(0)); //randomSeed(analogRead(0));
//randomSeed(22); //randomSeed(22);
rf24.powerUp();
Serial.print("*** RF payload size="); Serial.print(rf24.getPayloadSize()); Serial.println(" bytes"); 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.testCarrier() || rf24.testRPD()) { display->addLogMessage("*** Carrier/RPD seen on radio"); }
if (rf24.failureDetected) { display->addLogMessage("*** Radio error detected!"); } if (rf24.failureDetected) { display->addLogMessage("*** Radio error detected!"); }
@ -50,57 +53,80 @@ void Radio::begin(void) {
rf24.startListening(); 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) { void Radio::loop(void) {
#if 0
// put your main code here, to run repeatedly: // put your main code here, to run repeatedly:
/****************** Ping Out Role ***************************/ /****************** Ping Out Role ***************************/
if (isMaster) { if (isMaster) {
switchToReceiverRole(rf24);
radio.stopListening(); if (rf24.available()) {
struct clockMsg_s clockMsg;
Serial.println(F("Now sending")); rf24.read(&clockMsg, sizeof(struct clockMsg_s));
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 // Spew it
Serial.print(F("Sent ")); Serial.print(F("Received clock message, type="));
Serial.print(start_time); Serial.print(clockMsg.msgType);
Serial.print(F(", Got response ")); Serial.print(F(", time="));
Serial.print(got_time); Serial.print(clockMsg.hour);
Serial.print(F(", Round-trip delay ")); Serial.print(":");
Serial.print(end_time-start_time); Serial.print(clockMsg.minute);
Serial.println(F(" microseconds")); Serial.print(":");
Serial.println(clockMsg.second);
} }
// Try again 1s later
delay(1000);
} }
#if 0
/****************** Pong Back Role ***************************/ /****************** Pong Back Role ***************************/
if (!isMaster) if (!isMaster)

View File

@ -8,6 +8,7 @@ public:
Radio(Display *d, bool _isMaster):display(d), isMaster(_isMaster) { }; Radio(Display *d, bool _isMaster):display(d), isMaster(_isMaster) { };
void begin(void); void begin(void);
void loop(void); void loop(void);
void broadcastClock(int hour, int minute, int second);
private: private:
Display *display; Display *display;
bool isMaster; bool isMaster;