FremoClockRF/src/master.cpp

172 lines
5.4 KiB
C++

#include <Arduino.h>
#include "config.h"
#include "clockMsg.h"
#include "master.h"
static struct clockMsg_s clockMsg;
static unsigned long lastSentTimeTick = 0;
static unsigned long sendFastclockTimer_ms = 3000;
static unsigned long msPerModelSecond = 50; // 500 = real time
static unsigned long sendFailedCounter = 0, pauseTime = 0, stopTime = 0;
static struct clock_s {
uint8_t day;
uint8_t hour;
uint8_t minute;
uint8_t second;
uint16_t millisecond;
} fastclock;
void masterInit() {
clockMsg.hour = 0;
clockMsg.minute = 0;
clockMsg.second = 0;
lastSentTimeTick = millis();
Serial.print("*** Setting up master, init lastSentTimeTick="); Serial.println(lastSentTimeTick);
fastclock.day = 0;
fastclock.hour = 0;
fastclock.minute = 0;
fastclock.second = 0;
fastclock.millisecond = 0;
}
static void incrementClockByMilliseconds(int amount) {
fastclock.millisecond += amount;
if (fastclock.millisecond >= 1000) {
int carryover = fastclock.millisecond / 1000;
fastclock.millisecond = fastclock.millisecond % 1000;
fastclock.second += carryover;
if (fastclock.second >= 60) {
carryover = fastclock.second / 60;
fastclock.second = fastclock.second % 60;
fastclock.minute += carryover;
if (fastclock.minute >= 60) {
carryover = fastclock.minute / 60;
fastclock.minute = fastclock.minute % 60;
fastclock.hour += carryover;
if (fastclock.hour >= 24) {
carryover = fastclock.hour / 24;
fastclock.hour = fastclock.hour % 24;
fastclock.day += carryover;
if (fastclock.day >= 7) {
fastclock.day = fastclock.day % 7;
}
}
}
}
}
Serial.print("*** new clock: ");
Serial.print(fastclock.hour); Serial.print(":");
Serial.print(fastclock.minute); Serial.print(":");
Serial.print(fastclock.second); Serial.print(".");
Serial.print(fastclock.millisecond);
Serial.print(" day "); Serial.print(fastclock.day);
Serial.print(", incBy_ms="); Serial.print(amount);
}
static void timeTick(void) {
long newTimeTick = millis();
int fastclockTimeAdvance = (newTimeTick - lastSentTimeTick) * 1000 / msPerModelSecond;
incrementClockByMilliseconds(fastclockTimeAdvance);
lastSentTimeTick = newTimeTick;
Serial.print("*** tick (adv="); Serial.print(fastclockTimeAdvance); Serial.println("%d)");
}
#ifdef FCRF_RadioHead
void masterLoop(RHDatagram Datagram)
{
static unsigned long nextTimeTick_ms = millis();
static unsigned long updateEvery_ms = 1000;
static uint8_t hour=0, minute=0, second=0;
timeTick();
if (Datagram.available())
{
// Should be a message for us now
uint8_t buf[RH_MAX_MESSAGE_LEN];
uint8_t len = sizeof(buf);
uint8_t from, to, id, flags;
if (Datagram.recvfrom(buf, &len, &from, &to, &id, &flags)) {
Serial.print("got request: ");
Serial.println((char*)buf);
}
else
{
Serial.println("*** Datagram.recvfrom failed");
}
} else {
clockMsg.msgType = msgType_Clock;
clockMsg.hour = fastclock.hour;
clockMsg.minute = fastclock.minute;
clockMsg.second = fastclock.second;
// send clock info as a broadcast message
if (Datagram.sendto((uint8_t *) &clockMsg, sizeof(clockMsg), RH_BROADCAST_ADDRESS)) {
Serial.print(hour); Serial.print(":");
Serial.print(minute); Serial.print(":");
Serial.print(second); Serial.print(" - ");
Serial.println("Sent new clock tick");
}
}
}
}
#endif
#ifdef FCRF_RF24
extern const byte *addresses[];
static bool TX=1,RX=0,role=RX;
static void switchToSenderRole(RF24 radio)
{
Serial.println("*** master: CHANGING TO TRANSMIT ROLE");
radio.openWritingPipe(addresses[1]);
radio.openReadingPipe(1,addresses[0]);
radio.stopListening();
role = TX; // 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 = RX; // Become the primary receiver (pong back)
}
*/
void masterLoop(RF24 radio) {
timeTick();
if (millis() - lastSentTimeTick > sendFastclockTimer_ms) {
lastSentTimeTick = millis();
clockMsg.msgType = msgType_Clock;
clockMsg.hour = fastclock.hour;
clockMsg.minute = fastclock.minute;
clockMsg.second = fastclock.second;
switchToSenderRole(radio);
if (!radio.write(&clockMsg, sizeof(clockMsg), true /*multicast*/)) {
sendFailedCounter++;
}
//This is only required when NO ACK ( enableAutoAck(0) ) payloads are used
if (millis() - pauseTime > 3) {
pauseTime = millis();
radio.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 (!radio.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.println("*** send finished");
}
}
#endif