Added clock-halt handling and improved display.
This commit is contained in:
		@@ -13,8 +13,8 @@ The tasks of the master clock / controller is:
 | 
				
			|||||||
## Links / References
 | 
					## Links / References
 | 
				
			||||||
 | 
					
 | 
				
			||||||
- Digitrax Loconet PE: http://www.digitrax.com/static/apps/cms/media/documents/loconet/loconetpersonaledition.pdf
 | 
					- Digitrax Loconet PE: http://www.digitrax.com/static/apps/cms/media/documents/loconet/loconetpersonaledition.pdf
 | 
				
			||||||
-- we do not support loconet yet, but it is an option to be added later
 | 
					  - we do not support loconet yet, but it is an option to be added later
 | 
				
			||||||
-- see page 14 ff. about FAST Clock definitions
 | 
					  - see page 14 ff. about FAST Clock definitions
 | 
				
			||||||
- Rocrail with a description of the loconet interface (German): https://wiki.rocrail.net/doku.php?id=loconet:ln-pe-de
 | 
					- Rocrail with a description of the loconet interface (German): https://wiki.rocrail.net/doku.php?id=loconet:ln-pe-de
 | 
				
			||||||
- List of loconet interfaces: http://loconetovertcp.sourceforge.net/Client/index.html, and here especially the fast clock: http://loconetovertcp.cvs.sourceforge.net/loconetovertcp/tcp/client/Clock/
 | 
					- List of loconet interfaces: http://loconetovertcp.sourceforge.net/Client/index.html, and here especially the fast clock: http://loconetovertcp.cvs.sourceforge.net/loconetovertcp/tcp/client/Clock/
 | 
				
			||||||
- FREMO had some discussions about fast clocks, see the forum (available to members only)
 | 
					- FREMO had some discussions about fast clocks, see the forum (available to members only)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -128,12 +128,18 @@ void Display::addLogMessage(const char *message) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
void Display::showDashboard(void) {
 | 
					void Display::showDashboard(void) {
 | 
				
			||||||
  static unsigned long lastDisplayUpdate_ms = 0;
 | 
					  static unsigned long lastDisplayUpdate_ms = 0;
 | 
				
			||||||
 | 
					  static unsigned long lastBlinkChange_ms = 0;
 | 
				
			||||||
 | 
					  static bool blinkOnCycle = false; // toggles the on/off blinking phase
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  currentScreen = DashboardScreen;
 | 
					  currentScreen = DashboardScreen;
 | 
				
			||||||
  // avoid flickering of the display:
 | 
					  // avoid flickering of the display:
 | 
				
			||||||
  if (millis() - lastDisplayUpdate_ms < TIME_BETWEEN_DISPLAY_UPDATES_ms) return;
 | 
					  if (millis() - lastDisplayUpdate_ms < TIME_BETWEEN_DISPLAY_UPDATES_ms) return;
 | 
				
			||||||
  lastDisplayUpdate_ms = millis();
 | 
					  lastDisplayUpdate_ms = millis();
 | 
				
			||||||
  
 | 
					  if (lastDisplayUpdate_ms - lastBlinkChange_ms > BLINK_ON_OFF_TIME_ms) {
 | 
				
			||||||
 | 
					    lastBlinkChange_ms = lastDisplayUpdate_ms;
 | 
				
			||||||
 | 
					    blinkOnCycle = !blinkOnCycle;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  u8g2.clearBuffer();
 | 
					  u8g2.clearBuffer();
 | 
				
			||||||
  u8g2.setDrawColor(1);
 | 
					  u8g2.setDrawColor(1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -143,26 +149,28 @@ void Display::showDashboard(void) {
 | 
				
			|||||||
  u8g2.print(clockName);
 | 
					  u8g2.print(clockName);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // ****** speed *****
 | 
					  // ****** speed *****
 | 
				
			||||||
  setNormalTextSize();
 | 
					  setSmallTextSize();
 | 
				
			||||||
  u8g2.setCursor(55, 2*getTextHeight()-1);
 | 
					  u8g2.setCursor(55, 2*getTextHeight());
 | 
				
			||||||
  u8g2.print(clockSpeed);
 | 
					  u8g2.print(clockSpeed);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // ***** time *****
 | 
					  // ***** time *****
 | 
				
			||||||
  setLargeTextSize();
 | 
					  if (!clockHalted || blinkOnCycle) {
 | 
				
			||||||
  u8g2.setCursor(0, u8g2.getDisplayHeight()-1);
 | 
					    setLargeTextSize();
 | 
				
			||||||
  if (clockHour < 10) u8g2.print("0");
 | 
					    u8g2.setCursor(0, u8g2.getDisplayHeight()-1);
 | 
				
			||||||
  u8g2.print(clockHour);
 | 
					    if (clockHour < 10) u8g2.print("0");
 | 
				
			||||||
  u8g2.print(":");
 | 
					    u8g2.print(clockHour);
 | 
				
			||||||
  if (clockMinute < 10) u8g2.print("0");
 | 
					    u8g2.print(":");
 | 
				
			||||||
  u8g2.print(clockMinute);
 | 
					    if (clockMinute < 10) u8g2.print("0");
 | 
				
			||||||
 | 
					    u8g2.print(clockMinute);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // ***** halt/go *****
 | 
					  // ***** halt/go *****
 | 
				
			||||||
  if (clockHalted) {
 | 
					  if (clockHalted) {
 | 
				
			||||||
    setSmallTextSize();
 | 
					    setSmallTextSize();
 | 
				
			||||||
    u8g2.setDrawColor(1);
 | 
					    u8g2.setDrawColor(blinkOnCycle ? 1 : 0);
 | 
				
			||||||
    u8g2.drawBox(55, u8g2.getDisplayHeight() - 2*getTextHeight()-3, 5*4+2, getTextHeight());
 | 
					    u8g2.drawBox(55, u8g2.getDisplayHeight() - 2*getTextHeight()-4, 4*u8g2.getMaxCharWidth()+3, getTextHeight()+1);
 | 
				
			||||||
    u8g2.setDrawColor(0);
 | 
					    u8g2.setDrawColor(blinkOnCycle ? 0 : 1);
 | 
				
			||||||
    u8g2.setCursor(57, u8g2.getDisplayHeight() - getTextHeight()-3);
 | 
					    u8g2.setCursor(57, u8g2.getDisplayHeight() - getTextHeight()-4);
 | 
				
			||||||
    u8g2.print("HALT");
 | 
					    u8g2.print("HALT");
 | 
				
			||||||
    u8g2.setDrawColor(1);
 | 
					    u8g2.setDrawColor(1);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -3,6 +3,7 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
// avoid flickering of the display:
 | 
					// avoid flickering of the display:
 | 
				
			||||||
#define TIME_BETWEEN_DISPLAY_UPDATES_ms 200
 | 
					#define TIME_BETWEEN_DISPLAY_UPDATES_ms 200
 | 
				
			||||||
 | 
					#define BLINK_ON_OFF_TIME_ms 1000
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define MAX_CLOCK_NAME_LEN 8
 | 
					#define MAX_CLOCK_NAME_LEN 8
 | 
				
			||||||
#define MAX_CLOCK_SPEED_LEN 8
 | 
					#define MAX_CLOCK_SPEED_LEN 8
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -53,6 +53,7 @@ void Fastclock::loop(void) {
 | 
				
			|||||||
    msPerModelSecond = 500;
 | 
					    msPerModelSecond = 500;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  if (newTimeTick - lastTimeTickUsed < MIN_TIME_ms_BETWEEN_CLOCK_UPDATES) return;
 | 
					  if (newTimeTick - lastTimeTickUsed < MIN_TIME_ms_BETWEEN_CLOCK_UPDATES) return;
 | 
				
			||||||
 | 
					  if (halted) { lastTimeTickUsed = newTimeTick; return; }
 | 
				
			||||||
  int fastclockTimeAdvance = (newTimeTick - lastTimeTickUsed) * 1000 / msPerModelSecond;
 | 
					  int fastclockTimeAdvance = (newTimeTick - lastTimeTickUsed) * 1000 / msPerModelSecond;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  oldMinute = minute;
 | 
					  oldMinute = minute;
 | 
				
			||||||
@@ -72,4 +73,9 @@ void Fastclock::loop(void) {
 | 
				
			|||||||
void Fastclock::begin(void) {
 | 
					void Fastclock::begin(void) {
 | 
				
			||||||
  lastTimeTickUsed = millis();
 | 
					  lastTimeTickUsed = millis();
 | 
				
			||||||
  Serial.print("*** Setting up Fastclock, init lastSentTimeTick="); Serial.println(lastTimeTickUsed);
 | 
					  Serial.print("*** Setting up Fastclock, init lastSentTimeTick="); Serial.println(lastTimeTickUsed);
 | 
				
			||||||
 | 
					  // following setters do not change anything, but they update the display as well
 | 
				
			||||||
 | 
					  setClockSpeed(msPerModelSecond);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  display->setClockHalted(halted);
 | 
				
			||||||
 | 
					  display->setTime(hour, minute);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -4,10 +4,11 @@
 | 
				
			|||||||
#include "display.h"
 | 
					#include "display.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define MIN_TIME_ms_BETWEEN_CLOCK_UPDATES 200
 | 
					#define MIN_TIME_ms_BETWEEN_CLOCK_UPDATES 200
 | 
				
			||||||
 | 
					#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=500; };
 | 
					  Fastclock(Display *d): display(d) { 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);
 | 
				
			||||||
@@ -16,6 +17,7 @@ public:
 | 
				
			|||||||
  void setTime(uint8_t hours, uint8_t minutes, uint8_t seconds) { hour = hours; minute = minutes; second = seconds; millisecond = 0; };
 | 
					  void setTime(uint8_t hours, uint8_t minutes, uint8_t seconds) { hour = hours; minute = minutes; second = seconds; millisecond = 0; };
 | 
				
			||||||
  void setTime(uint8_t hours, uint8_t minutes, uint8_t seconds, uint16_t milliseconds) { hour = hours; minute = minutes; second = seconds; millisecond = milliseconds; };
 | 
					  void setTime(uint8_t hours, uint8_t minutes, uint8_t seconds, uint16_t milliseconds) { hour = hours; minute = minutes; second = seconds; millisecond = milliseconds; };
 | 
				
			||||||
  void setWeekday(uint8_t _weekday) { weekday = _weekday; };
 | 
					  void setWeekday(uint8_t _weekday) { weekday = _weekday; };
 | 
				
			||||||
 | 
					  void setClockHalted(bool setToHalt) { halted = setToHalt; display->setClockHalted(halted); };
 | 
				
			||||||
private:
 | 
					private:
 | 
				
			||||||
  Display *display;
 | 
					  Display *display;
 | 
				
			||||||
  unsigned long lastTimeTickUsed; // used to calculate model time
 | 
					  unsigned long lastTimeTickUsed; // used to calculate model time
 | 
				
			||||||
@@ -25,6 +27,7 @@ private:
 | 
				
			|||||||
  uint8_t minute;
 | 
					  uint8_t minute;
 | 
				
			||||||
  uint8_t second;
 | 
					  uint8_t second;
 | 
				
			||||||
  uint16_t millisecond;
 | 
					  uint16_t millisecond;
 | 
				
			||||||
 | 
					  bool halted;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										16
									
								
								src/main.cpp
									
									
									
									
									
								
							
							
						
						
									
										16
									
								
								src/main.cpp
									
									
									
									
									
								
							@@ -15,6 +15,8 @@
 | 
				
			|||||||
#include "display.h"
 | 
					#include "display.h"
 | 
				
			||||||
#include "fastclock.h"
 | 
					#include "fastclock.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define AUTOSTART_CLOCK_AFTER_ms 10000
 | 
				
			||||||
 | 
					
 | 
				
			||||||
//define your default values here, if there are different values in config.json, they are overwritten.
 | 
					//define your default values here, if there are different values in config.json, they are overwritten.
 | 
				
			||||||
//length should be max size + 1
 | 
					//length should be max size + 1
 | 
				
			||||||
char mqtt_server[40] = "";
 | 
					char mqtt_server[40] = "";
 | 
				
			||||||
@@ -229,6 +231,20 @@ void loop(void)
 | 
				
			|||||||
    return;
 | 
					    return;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#if defined(AUTOSTART_CLOCK_AFTER_ms)
 | 
				
			||||||
 | 
					#if AUTOSTART_CLOCK_AFTER_ms > 0
 | 
				
			||||||
 | 
					  static unsigned long autostart_ms = 0;
 | 
				
			||||||
 | 
					  static bool autostartDone = false;
 | 
				
			||||||
 | 
					  if (autostart_ms == 0) {
 | 
				
			||||||
 | 
					    autostart_ms = millis() + AUTOSTART_CLOCK_AFTER_ms;
 | 
				
			||||||
 | 
					  } else if (!autostartDone && millis() > autostart_ms) {
 | 
				
			||||||
 | 
					    autostartDone = true;
 | 
				
			||||||
 | 
					    fastclock.setClockHalted(false);
 | 
				
			||||||
 | 
					    Serial.println("Clock started automatically");
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  fastclock.loop();
 | 
					  fastclock.loop();
 | 
				
			||||||
  display.showDashboard();
 | 
					  display.showDashboard();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user