From 2fb0f4fb1b7c73e6402e95df183c7817f6b1ce29 Mon Sep 17 00:00:00 2001 From: Asbelos Date: Thu, 2 Jan 2025 11:01:46 +0000 Subject: [PATCH] DCC setTime packet --- CommandDistributor.cpp | 3 +++ DCC.cpp | 38 ++++++++++++++++++++++++++++++++++++++ DCC.h | 1 + 3 files changed, 42 insertions(+) diff --git a/CommandDistributor.cpp b/CommandDistributor.cpp index e889f62..50a89ef 100644 --- a/CommandDistributor.cpp +++ b/CommandDistributor.cpp @@ -185,6 +185,9 @@ void CommandDistributor::setClockTime(int16_t clocktime, int8_t clockrate, byte { case 1: if (clocktime != lastclocktime){ + auto difference = clocktime - lastclocktime; + if (difference<0) difference+=1440; + DCC::setTime(clocktime,clockrate,difference>2); // CAH. DIAG removed because LCD does it anyway. LCD(6,F("Clk Time:%d Sp %d"), clocktime, clockrate); // look for an event for this time diff --git a/DCC.cpp b/DCC.cpp index 4a1cedd..9e54abd 100644 --- a/DCC.cpp +++ b/DCC.cpp @@ -371,6 +371,44 @@ whole range of the 11 bits sent to track. return true; } +bool DCC::setTime(uint16_t minutes,uint8_t speed, bool suddenChange) { + /* see rcn-122 + 5 Global commands +These commands are sent and begin exclusively with a broadcast address 0 +always with {synchronous bits} 0 0000-0000 … and end with the checksum +... PPPPPPPP 1. Therefore, only the bytes of the commands and not that of +shown below whole package shown. The commands can be used by vehicle and +accessory decoders alike. + + 5.1 Time command +This command is four bytes long and has the format: +1100-0001 CCxx-xxxx xxxx-xxxxx xxxx-xxxx +CC indicates what data is transmitted in the packet: +CC = 00 Model Time +1100-0001 00MM-MMMM WWWH-HHHH U0BB-BBBB with: +MMMMMM = Minutes, Value range: 0..59 +WWW = Day of the Week, Value range: 0 = Monday, 1 = Tuesday, 2 = Wednesday, +3 = Thursday, 4 = Friday, 5 = Saturday, 6 = Sunday, 7 = Weekday +is not supported. +HHHHH = Hours, value range: 0..23 +U = +Update, i.e. the time has changed suddenly, e.g. by a new one timetable to start. +Up to 4 can occur per sudden change commands can be marked like this. +BBBBBB = Acceleration factor, value range 0..63. An acceleration factor of 0 means the +model clock has been stopped, a factor of 1 corresponds to real time, at 2 the +clock runs twice as fast, at three times as fast as real time, etc. +*/ +if (minutes>=1440 || speed>63 ) return false; +byte b[5]; +b[0]=0; // broadcast address +b[1]=0b11000001; // 1100-0001 (model time) +b[2]=minutes % 60 ; // MM +b[3]= 0b11100000 | (minutes/60); // 111H-HHHH weekday not supported +b[4]= (suddenChange ? 0b10000000 : 0) | speed; +DCCWaveform::mainTrack.schedulePacket(b, sizeof(b), 2); +return true; +} + // // writeCVByteMain: Write a byte with PoM on main. This writes // the 5 byte sized packet to implement this DCC function diff --git a/DCC.h b/DCC.h index e6e4965..adc269c 100644 --- a/DCC.h +++ b/DCC.h @@ -77,6 +77,7 @@ public: static void setAccessory(int address, byte port, bool gate, byte onoff = 2); static bool setExtendedAccessory(int16_t address, int16_t value, byte repeats=3); static bool writeTextPacket(byte *b, int nBytes); + static bool setTime(uint16_t minutes,uint8_t speed, bool suddenChange); // ACKable progtrack calls bitresults callback 0,0 or -1, cv returns value or -1 static void readCV(int16_t cv, ACK_CALLBACK callback);