Refactoring: created Display class.
This commit is contained in:
		
							
								
								
									
										198
									
								
								src/Display.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										198
									
								
								src/Display.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,198 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
 | 
					#include "Display.h"
 | 
				
			||||||
 | 
					#include <MD_Parola.h>
 | 
				
			||||||
 | 
					#include <MD_MAX72xx.h>
 | 
				
			||||||
 | 
					#include <SPI.h>
 | 
				
			||||||
 | 
					#include "MD_RobotEyes.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define DISPLAY_CLK_PIN D5
 | 
				
			||||||
 | 
					#define DISPLAY_DATA_PIN D7
 | 
				
			||||||
 | 
					#define DISPLAY_CS_PIN D6
 | 
				
			||||||
 | 
					#define VERTICAL_BAR_STARTS_TOP false
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define HARDWARE_TYPE MD_MAX72XX::FC16_HW
 | 
				
			||||||
 | 
					#define MAX_DISPLAY_DEVICES 4
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static MD_Parola P = MD_Parola(HARDWARE_TYPE, DISPLAY_DATA_PIN, DISPLAY_CLK_PIN, DISPLAY_CS_PIN, MAX_DISPLAY_DEVICES);
 | 
				
			||||||
 | 
					static MD_RobotEyes E;
 | 
				
			||||||
 | 
					static MD_MAX72XX *graphicDisplay = NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void Display::begin() {
 | 
				
			||||||
 | 
					  int charCode;
 | 
				
			||||||
 | 
					#if VERTICAL_BAR_STARTS_TOP
 | 
				
			||||||
 | 
					  static uint8_t verticalBarFont[] = {
 | 
				
			||||||
 | 
					    1, 0x00, /* blank */
 | 
				
			||||||
 | 
					    1, 0x01, /* 1 dot */
 | 
				
			||||||
 | 
					    1, 0x03, /* 2 dots */
 | 
				
			||||||
 | 
					    1, 0x07,
 | 
				
			||||||
 | 
					    1, 0x0f,
 | 
				
			||||||
 | 
					    1, 0x1f,
 | 
				
			||||||
 | 
					    1, 0x3f,
 | 
				
			||||||
 | 
					    1, 0x7f,
 | 
				
			||||||
 | 
					    1, 0xff, /* vertical bar completely set */
 | 
				
			||||||
 | 
					  }; // columns from right to left, each byte is a single column
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
					  static uint8_t verticalBarFont[] = {
 | 
				
			||||||
 | 
					    1, 0x00, /* blank */
 | 
				
			||||||
 | 
					    1, 0x80, /* 1 dot */
 | 
				
			||||||
 | 
					    1, 0xc0, /* 2 dots */
 | 
				
			||||||
 | 
					    1, 0xe0,
 | 
				
			||||||
 | 
					    1, 0xf0,
 | 
				
			||||||
 | 
					    1, 0xf8,
 | 
				
			||||||
 | 
					    1, 0xfc,
 | 
				
			||||||
 | 
					    1, 0xfe,
 | 
				
			||||||
 | 
					    1, 0xff, /* vertical bar completely set */
 | 
				
			||||||
 | 
					  }; // columns from right to left, each byte is a single column
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					  static uint8_t newZero[] = {0x05, 0x3e, 0x41, 0x41, 0x41, 0x3e, 0x00};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  P.begin();
 | 
				
			||||||
 | 
					  // P.setZoneEffect(0, true, PA_FLIP_LR);
 | 
				
			||||||
 | 
					  graphicDisplay = P.getGraphicObject();
 | 
				
			||||||
 | 
					  E.begin(graphicDisplay);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  P.setIntensity(1);
 | 
				
			||||||
 | 
					  for (charCode=1; charCode<=9; ++charCode) {
 | 
				
			||||||
 | 
					    P.addChar(charCode, verticalBarFont+2*(charCode-1));
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  // replace the 0 characters, we do not like the "slash"
 | 
				
			||||||
 | 
					  P.addChar('0', newZero);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  char intro[] = {':', '-', ')', ' ', 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x00};
 | 
				
			||||||
 | 
					  P.print(intro);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					typedef struct
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  char name[7];
 | 
				
			||||||
 | 
					  MD_RobotEyes::emotion_t e;
 | 
				
			||||||
 | 
					  uint16_t timePause;  // in milliseconds
 | 
				
			||||||
 | 
					} sampleItem_t;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static const sampleItem_t eSeq[] =
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  { "Nutral", MD_RobotEyes::E_NEUTRAL, 1000 },
 | 
				
			||||||
 | 
					  { "Blink" , MD_RobotEyes::E_BLINK, 1000 },
 | 
				
			||||||
 | 
					  { "Wink"  , MD_RobotEyes::E_WINK, 1000 },
 | 
				
			||||||
 | 
					  { "Left"  , MD_RobotEyes::E_LOOK_L, 1000 },
 | 
				
			||||||
 | 
					  { "Right" , MD_RobotEyes::E_LOOK_R, 1000 },
 | 
				
			||||||
 | 
					  { "Up"    , MD_RobotEyes::E_LOOK_U, 1000 },
 | 
				
			||||||
 | 
					  { "Down"  , MD_RobotEyes::E_LOOK_D, 1000 },
 | 
				
			||||||
 | 
					  { "Angry" , MD_RobotEyes::E_ANGRY, 1000 },
 | 
				
			||||||
 | 
					  { "Sad"   , MD_RobotEyes::E_SAD, 1000 },
 | 
				
			||||||
 | 
					  { "Evil"  , MD_RobotEyes::E_EVIL, 1000 },
 | 
				
			||||||
 | 
					  { "Evil2" , MD_RobotEyes::E_EVIL2, 1000 },
 | 
				
			||||||
 | 
					  { "Squint", MD_RobotEyes::E_SQUINT, 1000 },
 | 
				
			||||||
 | 
					  { "Dead"  , MD_RobotEyes::E_DEAD, 1000 },
 | 
				
			||||||
 | 
					  { "ScanV" , MD_RobotEyes::E_SCAN_UD, 1000 },
 | 
				
			||||||
 | 
					  { "ScanH" , MD_RobotEyes::E_SCAN_LR, 1000 },
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					#define DISPLAY_ANIM_NAME false
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void Display::loopEyeAnimation() {
 | 
				
			||||||
 | 
					  // show startup animation
 | 
				
			||||||
 | 
					  boolean animationFinished = false;
 | 
				
			||||||
 | 
					  static uint32_t timeStartDelay;
 | 
				
			||||||
 | 
					  static uint8_t index = ARRAY_SIZE(eSeq);
 | 
				
			||||||
 | 
					  static enum { S_IDLE, S_TEXT, S_ANIM, S_PAUSE } state = S_IDLE;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  animationFinished = E.runAnimation();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  switch (state)
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    case S_IDLE:
 | 
				
			||||||
 | 
					      index++;
 | 
				
			||||||
 | 
					      if (index >= ARRAY_SIZE(eSeq))
 | 
				
			||||||
 | 
					        index = 0;
 | 
				
			||||||
 | 
					      P.displayClear();
 | 
				
			||||||
 | 
					      #if DISPLAY_ANIM_NAME
 | 
				
			||||||
 | 
					        E.setText(eSeq[index].name);
 | 
				
			||||||
 | 
					      #endif
 | 
				
			||||||
 | 
					      state = S_TEXT;
 | 
				
			||||||
 | 
					      break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    case S_TEXT: // wait for the text to finish
 | 
				
			||||||
 | 
					      if (animationFinished)  // text animation is finished
 | 
				
			||||||
 | 
					      {
 | 
				
			||||||
 | 
					        E.setAnimation(eSeq[index].e, true);
 | 
				
			||||||
 | 
					        state = S_ANIM;
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					      break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    case S_ANIM:  // checking animation is completed
 | 
				
			||||||
 | 
					      if (animationFinished)  // animation is finished
 | 
				
			||||||
 | 
					      {
 | 
				
			||||||
 | 
					        timeStartDelay = millis();
 | 
				
			||||||
 | 
					        state = S_PAUSE;
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					      break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    case S_PAUSE: // non blocking waiting for a period between animations
 | 
				
			||||||
 | 
					      if (millis() - timeStartDelay >= eSeq[index].timePause)
 | 
				
			||||||
 | 
					        state = S_IDLE;
 | 
				
			||||||
 | 
					      break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      default:
 | 
				
			||||||
 | 
					      state = S_IDLE;
 | 
				
			||||||
 | 
					      break;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void Display::loop() {
 | 
				
			||||||
 | 
					  char minuteProgressIndicator;
 | 
				
			||||||
 | 
					  char timeBuffer[10];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  minuteProgressIndicator = currentTime->getSeconds()/6.7 + 1; // char code 1-8 show vertical bar
 | 
				
			||||||
 | 
					  if (minuteProgressIndicator > 9) minuteProgressIndicator = 9;
 | 
				
			||||||
 | 
					  snprintf(timeBuffer, 10, "%c %2d:%02d", minuteProgressIndicator, currentTime->getHours(), currentTime->getMinutes());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // standard procedure to display
 | 
				
			||||||
 | 
					  static uint32_t last_clock_refresh = 0;
 | 
				
			||||||
 | 
					  static uint32_t lastTimeClockNameShown = 0;
 | 
				
			||||||
 | 
					  static boolean showingClockName = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if (showingClockName) {
 | 
				
			||||||
 | 
					    if (millis() - lastTimeClockNameShown > clockNameDurationTime_ms) {
 | 
				
			||||||
 | 
					      // stop showingClockName
 | 
				
			||||||
 | 
					      showingClockName = false;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  } else {
 | 
				
			||||||
 | 
					    if ((millis() - lastTimeClockNameShown > displayClockNameEvery_ms)
 | 
				
			||||||
 | 
					        && (currentTime->getSeconds() < 60-doNotShowClockNameBeforeAndAfterMinuteChange_s)
 | 
				
			||||||
 | 
					        && (currentTime->getSeconds() > doNotShowClockNameBeforeAndAfterMinuteChange_s)) {
 | 
				
			||||||
 | 
					      // re-initialize, that fixes display problems due to electrical relais feedbacks
 | 
				
			||||||
 | 
					      reInitializeDisplay();
 | 
				
			||||||
 | 
					      P.setIntensity(2);
 | 
				
			||||||
 | 
					      P.print(currentTime->getClockName());
 | 
				
			||||||
 | 
					      lastTimeClockNameShown = millis();
 | 
				
			||||||
 | 
					      showingClockName = true;
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					      // showing clock
 | 
				
			||||||
 | 
					      if (millis() - last_clock_refresh > displayRefresh_ms) {
 | 
				
			||||||
 | 
					        // re-initialize, that fixes display problems due to electrical relais feedbacks
 | 
				
			||||||
 | 
					        reInitializeDisplay();
 | 
				
			||||||
 | 
					        P.setIntensity(1);
 | 
				
			||||||
 | 
					        P.print(timeBuffer);
 | 
				
			||||||
 | 
					        last_clock_refresh = millis();
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void Display::reInitializeDisplay() {
 | 
				
			||||||
 | 
					  #define REINIT_AFTER_ms 5000
 | 
				
			||||||
 | 
					  #define AVOID_REINIT_BEFORE_AND_AFTER_FULLMINUTE_FOR_s 3
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if (last_reinit_ts == 0) last_reinit_ts = millis();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if (millis() - last_reinit_ts > REINIT_AFTER_ms
 | 
				
			||||||
 | 
					      && currentTime->getSeconds() < 60 - AVOID_REINIT_BEFORE_AND_AFTER_FULLMINUTE_FOR_s
 | 
				
			||||||
 | 
					      && currentTime->getSeconds() > AVOID_REINIT_BEFORE_AND_AFTER_FULLMINUTE_FOR_s) {
 | 
				
			||||||
 | 
					    P.begin();
 | 
				
			||||||
 | 
					    last_reinit_ts = millis();
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void Display::print(const char *s) { P.print(s); }
 | 
				
			||||||
 | 
					void Display::print(const String s) { P.print(s); }
 | 
				
			||||||
							
								
								
									
										40
									
								
								src/Display.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										40
									
								
								src/Display.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,40 @@
 | 
				
			|||||||
 | 
					#ifndef DISPLAY_h_included
 | 
				
			||||||
 | 
					#define DISPLAY_h_included
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <Arduino.h>
 | 
				
			||||||
 | 
					#include "Clock.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class Display {
 | 
				
			||||||
 | 
					public:
 | 
				
			||||||
 | 
					  Display(Clock *real, Clock *model):
 | 
				
			||||||
 | 
					    last_reinit_ts(0),
 | 
				
			||||||
 | 
					    realTime(real),
 | 
				
			||||||
 | 
					    modelTime(model),
 | 
				
			||||||
 | 
					    displayClockNameEvery_ms(16000),
 | 
				
			||||||
 | 
					    clockNameDurationTime_ms(1200),
 | 
				
			||||||
 | 
					    doNotShowClockNameBeforeAndAfterMinuteChange_s(2),
 | 
				
			||||||
 | 
					    displayRefresh_ms(200)
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    showRealTime();
 | 
				
			||||||
 | 
					  };
 | 
				
			||||||
 | 
					  void begin();
 | 
				
			||||||
 | 
					  void loop();
 | 
				
			||||||
 | 
					  void loopEyeAnimation();
 | 
				
			||||||
 | 
					  void reInitializeDisplay();
 | 
				
			||||||
 | 
					  void showRealTime() { showRealTimeFlag=true; currentTime = realTime; };
 | 
				
			||||||
 | 
					  void showModelTime() { showRealTimeFlag=false; currentTime = modelTime; };
 | 
				
			||||||
 | 
					  void setClockNameDurationTime_ms(unsigned long val) { clockNameDurationTime_ms=val; };
 | 
				
			||||||
 | 
					  void setClockNameDisplayEvery_ms(unsigned long val) { displayClockNameEvery_ms=val; };
 | 
				
			||||||
 | 
					  void print(const char *s);
 | 
				
			||||||
 | 
					  void print(const String s);
 | 
				
			||||||
 | 
					protected:
 | 
				
			||||||
 | 
					  unsigned long last_reinit_ts;
 | 
				
			||||||
 | 
					  Clock *realTime, *modelTime, *currentTime;
 | 
				
			||||||
 | 
					  boolean showRealTimeFlag;
 | 
				
			||||||
 | 
					  unsigned long displayClockNameEvery_ms;
 | 
				
			||||||
 | 
					  unsigned long clockNameDurationTime_ms;
 | 
				
			||||||
 | 
					  unsigned int doNotShowClockNameBeforeAndAfterMinuteChange_s;
 | 
				
			||||||
 | 
					  unsigned long displayRefresh_ms;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
							
								
								
									
										266
									
								
								src/main.cpp
									
									
									
									
									
								
							
							
						
						
									
										266
									
								
								src/main.cpp
									
									
									
									
									
								
							@@ -4,74 +4,55 @@
 | 
				
			|||||||
#define COMPDATE __DATE__ __TIME__
 | 
					#define COMPDATE __DATE__ __TIME__
 | 
				
			||||||
#define APP_VERSION "0.2.18"
 | 
					#define APP_VERSION "0.2.18"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Button pin on the esp for selecting modes. 0 for Generic devices!
 | 
					 | 
				
			||||||
#define MODEBUTTON D3
 | 
					 | 
				
			||||||
#define RELAY1_PIN D1
 | 
					 | 
				
			||||||
#define RELAY2_PIN D2
 | 
					 | 
				
			||||||
#define DISPLAY_CLK_PIN D5
 | 
					 | 
				
			||||||
#define DISPLAY_DATA_PIN D7
 | 
					 | 
				
			||||||
#define DISPLAY_CS_PIN D6
 | 
					 | 
				
			||||||
#define VERTICAL_BAR_STARTS_TOP false
 | 
					 | 
				
			||||||
#define DEBUG_RELAYS false
 | 
					 | 
				
			||||||
#define DEBUG_DISPLAY false
 | 
					 | 
				
			||||||
#define STARTUP1_ANIMATION_DURATION_ms 2000
 | 
					 | 
				
			||||||
#define STARTUP2_ANIMATION_DURATION_ms 33000
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#include <Arduino.h>
 | 
					#include <Arduino.h>
 | 
				
			||||||
#include <IOTAppStory.h>
 | 
					#include <IOTAppStory.h>
 | 
				
			||||||
#include <MD_Parola.h>
 | 
					 | 
				
			||||||
#include <MD_MAX72xx.h>
 | 
					 | 
				
			||||||
#include <SPI.h>
 | 
					 | 
				
			||||||
#include <NTPClient.h>
 | 
					#include <NTPClient.h>
 | 
				
			||||||
#include <ESP8266WiFi.h>
 | 
					#include <ESP8266WiFi.h>
 | 
				
			||||||
#include <WiFiUdp.h>
 | 
					#include <WiFiUdp.h>
 | 
				
			||||||
#include "MD_RobotEyes.h"
 | 
					 | 
				
			||||||
#include <FS.h>
 | 
					#include <FS.h>
 | 
				
			||||||
#include "WebServer.h"
 | 
					#include "WebServer.h"
 | 
				
			||||||
#include <ESP8266HTTPClient.h>
 | 
					#include <ESP8266HTTPClient.h>
 | 
				
			||||||
#include "Relays.h"
 | 
					#include "Relays.h"
 | 
				
			||||||
#include "Clock.h"
 | 
					#include "Clock.h"
 | 
				
			||||||
 | 
					#include "Display.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Button pin on the esp for selecting modes. 0 for Generic devices!
 | 
				
			||||||
 | 
					#define MODEBUTTON D3
 | 
				
			||||||
 | 
					#define RELAY1_PIN D1
 | 
				
			||||||
 | 
					#define RELAY2_PIN D2
 | 
				
			||||||
 | 
					#define DEBUG_RELAYS false
 | 
				
			||||||
 | 
					#define DEBUG_DISPLAY false
 | 
				
			||||||
 | 
					#define STARTUP1_ANIMATION_DURATION_ms 2000
 | 
				
			||||||
 | 
					#define STARTUP2_ANIMATION_DURATION_ms 33000
 | 
				
			||||||
 | 
					
 | 
				
			||||||
IOTAppStory IAS(COMPDATE, MODEBUTTON);
 | 
					IOTAppStory IAS(COMPDATE, MODEBUTTON);
 | 
				
			||||||
String deviceName = "wemosMatrixDisplay";
 | 
					String deviceName = "wemosMatrixDisplay";
 | 
				
			||||||
String chipId;
 | 
					String chipId;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define HARDWARE_TYPE MD_MAX72XX::FC16_HW
 | 
					 | 
				
			||||||
#define MAX_DISPLAY_DEVICES 4
 | 
					 | 
				
			||||||
Clock realTime("real");
 | 
					Clock realTime("real");
 | 
				
			||||||
Clock modelTime("Fremo");
 | 
					Clock modelTime("Fremo");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
MD_Parola P = MD_Parola(HARDWARE_TYPE, DISPLAY_DATA_PIN, DISPLAY_CLK_PIN, DISPLAY_CS_PIN, MAX_DISPLAY_DEVICES);
 | 
					 | 
				
			||||||
MD_RobotEyes E;
 | 
					 | 
				
			||||||
Relays R;
 | 
					Relays R;
 | 
				
			||||||
WebServer W(&R, &realTime, &modelTime);
 | 
					WebServer W(&R, &realTime, &modelTime);
 | 
				
			||||||
 | 
					Display D(&realTime, &modelTime);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
WiFiUDP ntpUDP;
 | 
					WiFiUDP ntpUDP;
 | 
				
			||||||
NTPClient timeClient(ntpUDP, "europe.pool.ntp.org", 3600, 60000);
 | 
					NTPClient timeClient(ntpUDP, "europe.pool.ntp.org", 3600, 60000);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define mkstring(x) #x
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Field default values
 | 
					// Field default values
 | 
				
			||||||
char *clockName = "FREMO";
 | 
					char *clockName = "FREMO";
 | 
				
			||||||
char *clockSpeed_modelMsPerRealSec_String = "250";
 | 
					char *clockSpeed_modelMsPerRealSec_String = "250";
 | 
				
			||||||
int clockSpeed_modelMsPerRealSec = 250;
 | 
					char *relay1Pin_String = mkstring(RELAY1_PIN);
 | 
				
			||||||
char *relay1Pin_String = "D1";
 | 
					char *relay2Pin_String = mkstring(RELAY2_PIN);
 | 
				
			||||||
char *relay2Pin_String = "D2";
 | 
					int relay1Pin = RELAY1_PIN, relay2Pin = RELAY2_PIN;
 | 
				
			||||||
int relay1Pin = D1, relay2Pin = D2;
 | 
					 | 
				
			||||||
char *relayHoldTime_ms_String = "200";
 | 
					char *relayHoldTime_ms_String = "200";
 | 
				
			||||||
char *relayMinOffTime_ms_String = "100";
 | 
					char *relayMinOffTime_ms_String = "100";
 | 
				
			||||||
unsigned int displayRefresh_ms = 200;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Clock Display Config Parameter
 | 
					// Clock Display Config Parameter
 | 
				
			||||||
static char * displayClockNameEvery_ms_String = "16000";
 | 
					static char * displayClockNameEvery_ms_String = "16000";
 | 
				
			||||||
static char * displayClockNameDuration_ms_String = "1200";
 | 
					static char * displayClockNameDuration_ms_String = "1200";
 | 
				
			||||||
static uint32_t displayClockNameEvery_ms = 16000;
 | 
					 | 
				
			||||||
static uint32_t displayClockNameDuration_ms = 1200;
 | 
					 | 
				
			||||||
static uint16_t doNotShowClockNameBeforeAndAfterMinuteChange_s = 2;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static uint16_t hours, minutes, seconds;
 | 
					 | 
				
			||||||
static char minuteProgressIndicator;
 | 
					 | 
				
			||||||
static char timeBuffer[10];
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
void setupIAS(void) {
 | 
					void setupIAS(void) {
 | 
				
			||||||
  #if defined  ESP8266
 | 
					  #if defined  ESP8266
 | 
				
			||||||
@@ -100,41 +81,41 @@ void setupIAS(void) {
 | 
				
			|||||||
  IAS.onModeButtonShortPress([]() {
 | 
					  IAS.onModeButtonShortPress([]() {
 | 
				
			||||||
    Serial.println(F(" If mode button is released, I will enter firmware update mode."));
 | 
					    Serial.println(F(" If mode button is released, I will enter firmware update mode."));
 | 
				
			||||||
    Serial.println(F("*----------------------------------------------------------------------*"));
 | 
					    Serial.println(F("*----------------------------------------------------------------------*"));
 | 
				
			||||||
    P.print("|updt");
 | 
					    D.print("|updt");
 | 
				
			||||||
  });
 | 
					  });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  IAS.onModeButtonLongPress([]() {
 | 
					  IAS.onModeButtonLongPress([]() {
 | 
				
			||||||
    Serial.println(F(" If mode button is released, I will enter configuration mode."));
 | 
					    Serial.println(F(" If mode button is released, I will enter configuration mode."));
 | 
				
			||||||
    Serial.println(F("*----------------------------------------------------------------------*"));
 | 
					    Serial.println(F("*----------------------------------------------------------------------*"));
 | 
				
			||||||
    P.print("|cfg");
 | 
					    D.print("|cfg");
 | 
				
			||||||
  });
 | 
					  });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  IAS.onFirstBoot([]() {
 | 
					  IAS.onFirstBoot([]() {
 | 
				
			||||||
    Serial.println(F(" Manual reset necessary after serial upload!"));
 | 
					    Serial.println(F(" Manual reset necessary after serial upload!"));
 | 
				
			||||||
    Serial.println(F("*----------------------------------------------------------------------*"));
 | 
					    Serial.println(F("*----------------------------------------------------------------------*"));
 | 
				
			||||||
    P.print("|rst");
 | 
					    D.print("|rst");
 | 
				
			||||||
    ESP.reset();
 | 
					    ESP.reset();
 | 
				
			||||||
  });
 | 
					  });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  IAS.onConfigMode([]() {
 | 
					  IAS.onConfigMode([]() {
 | 
				
			||||||
    P.print(" WiFi");
 | 
					    D.print(" WiFi");
 | 
				
			||||||
    delay(400);
 | 
					    delay(400);
 | 
				
			||||||
    P.print(":" + chipId);
 | 
					    D.print(":" + chipId);
 | 
				
			||||||
    Serial.print(F("Entered config mode for Wifi, device=")); Serial.println(chipId);
 | 
					    Serial.print(F("Entered config mode for Wifi, device=")); Serial.println(chipId);
 | 
				
			||||||
  });
 | 
					  });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  IAS.onFirmwareUpdateCheck([]() {
 | 
					  IAS.onFirmwareUpdateCheck([]() {
 | 
				
			||||||
    // P.print("chk upd");
 | 
					    // D.print("chk upd");
 | 
				
			||||||
    Serial.println(F("Firmware update check"));
 | 
					    Serial.println(F("Firmware update check"));
 | 
				
			||||||
  });
 | 
					  });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  IAS.onFirmwareUpdateDownload([]() {
 | 
					  IAS.onFirmwareUpdateDownload([]() {
 | 
				
			||||||
    P.print("dl+instl");
 | 
					    D.print("dl+instl");
 | 
				
			||||||
    Serial.println(F("Download and install new firmware"));
 | 
					    Serial.println(F("Download and install new firmware"));
 | 
				
			||||||
  });
 | 
					  });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  IAS.onFirmwareUpdateError([]() {
 | 
					  IAS.onFirmwareUpdateError([]() {
 | 
				
			||||||
    // P.print("Err fwu");
 | 
					    // D.print("Err fwu");
 | 
				
			||||||
    Serial.println(F("Firmware update error"));
 | 
					    Serial.println(F("Firmware update error"));
 | 
				
			||||||
  });
 | 
					  });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -148,71 +129,24 @@ void setupIAS(void) {
 | 
				
			|||||||
  // Please change it to at least 2 hours in production
 | 
					  // Please change it to at least 2 hours in production
 | 
				
			||||||
  IAS.setCallHomeInterval(120);
 | 
					  IAS.setCallHomeInterval(120);
 | 
				
			||||||
  IAS.callHome(true /*SPIFFS-check*/);
 | 
					  IAS.callHome(true /*SPIFFS-check*/);
 | 
				
			||||||
  clockSpeed_modelMsPerRealSec = atoi(clockSpeed_modelMsPerRealSec_String);
 | 
					  modelTime.setSpeed_modelMsPerRealSecond(atoi(clockSpeed_modelMsPerRealSec_String));
 | 
				
			||||||
  relay1Pin = IAS.dPinConv(relay1Pin_String);
 | 
					  relay1Pin = IAS.dPinConv(relay1Pin_String);
 | 
				
			||||||
  relay2Pin = IAS.dPinConv(relay2Pin_String);
 | 
					  relay2Pin = IAS.dPinConv(relay2Pin_String);
 | 
				
			||||||
  R.setHoldTime_ms(atoi(relayHoldTime_ms_String));
 | 
					  R.setHoldTime_ms(atoi(relayHoldTime_ms_String));
 | 
				
			||||||
  R.setMinOffTime_ms(atoi(relayMinOffTime_ms_String));
 | 
					  R.setMinOffTime_ms(atoi(relayMinOffTime_ms_String));
 | 
				
			||||||
  displayClockNameEvery_ms = atoi(displayClockNameEvery_ms_String);
 | 
					  D.setClockNameDisplayEvery_ms(atoi(displayClockNameEvery_ms_String));
 | 
				
			||||||
  displayClockNameDuration_ms = atoi(displayClockNameDuration_ms_String);
 | 
					  D.setClockNameDurationTime_ms(atoi(displayClockNameDuration_ms_String));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  Serial.println(F("Configuration used:"));
 | 
					  Serial.println(F("Configuration used:"));
 | 
				
			||||||
  Serial.print(F("Relay1 Pin: ")); Serial.println(relay1Pin);
 | 
					  Serial.print(F("Relay1 Pin: ")); Serial.println(relay1Pin);
 | 
				
			||||||
  Serial.print(F("Relay2 Pin: ")); Serial.println(relay2Pin);
 | 
					  Serial.print(F("Relay2 Pin: ")); Serial.println(relay2Pin);
 | 
				
			||||||
  Serial.print(F("Clock speed: ")); Serial.print(clockSpeed_modelMsPerRealSec); Serial.println(F(" model ms per real sec"));
 | 
					 | 
				
			||||||
  Serial.print(F("Relay hold time (ms): ")); Serial.println(relayHoldTime_ms_String);
 | 
					  Serial.print(F("Relay hold time (ms): ")); Serial.println(relayHoldTime_ms_String);
 | 
				
			||||||
  Serial.print(F("Relay min off time (ms): ")); Serial.println(relayMinOffTime_ms_String);
 | 
					  Serial.print(F("Relay min off time (ms): ")); Serial.println(relayMinOffTime_ms_String);
 | 
				
			||||||
  Serial.print(F("Clock speed (model ms per real time s): ")); Serial.println(clockSpeed_modelMsPerRealSec);
 | 
					  Serial.print(F("Clock speed (model ms per real time s): ")); Serial.println(clockSpeed_modelMsPerRealSec_String);
 | 
				
			||||||
  Serial.print(F("Show clock name every (ms): ")); Serial.println(displayClockNameEvery_ms);
 | 
					  Serial.print(F("Show clock name every (ms): ")); Serial.println(displayClockNameEvery_ms_String);
 | 
				
			||||||
  Serial.print(F("Show clock name for (ms): ")); Serial.println(displayClockNameDuration_ms);
 | 
					  Serial.print(F("Show clock name for (ms): ")); Serial.println(displayClockNameDuration_ms_String);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static MD_MAX72XX *graphicDisplay = NULL;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void setupDisplay() {
 | 
					 | 
				
			||||||
  int charCode;
 | 
					 | 
				
			||||||
#if VERTICAL_BAR_STARTS_TOP
 | 
					 | 
				
			||||||
  static uint8_t verticalBarFont[] = {
 | 
					 | 
				
			||||||
    1, 0x00, /* blank */
 | 
					 | 
				
			||||||
    1, 0x01, /* 1 dot */
 | 
					 | 
				
			||||||
    1, 0x03, /* 2 dots */
 | 
					 | 
				
			||||||
    1, 0x07,
 | 
					 | 
				
			||||||
    1, 0x0f,
 | 
					 | 
				
			||||||
    1, 0x1f,
 | 
					 | 
				
			||||||
    1, 0x3f,
 | 
					 | 
				
			||||||
    1, 0x7f,
 | 
					 | 
				
			||||||
    1, 0xff, /* vertical bar completely set */
 | 
					 | 
				
			||||||
  }; // columns from right to left, each byte is a single column
 | 
					 | 
				
			||||||
#else
 | 
					 | 
				
			||||||
  static uint8_t verticalBarFont[] = {
 | 
					 | 
				
			||||||
    1, 0x00, /* blank */
 | 
					 | 
				
			||||||
    1, 0x80, /* 1 dot */
 | 
					 | 
				
			||||||
    1, 0xc0, /* 2 dots */
 | 
					 | 
				
			||||||
    1, 0xe0,
 | 
					 | 
				
			||||||
    1, 0xf0,
 | 
					 | 
				
			||||||
    1, 0xf8,
 | 
					 | 
				
			||||||
    1, 0xfc,
 | 
					 | 
				
			||||||
    1, 0xfe,
 | 
					 | 
				
			||||||
    1, 0xff, /* vertical bar completely set */
 | 
					 | 
				
			||||||
  }; // columns from right to left, each byte is a single column
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
  static uint8_t newZero[] = {0x05, 0x3e, 0x41, 0x41, 0x41, 0x3e, 0x00};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  P.begin();
 | 
					 | 
				
			||||||
  // P.setZoneEffect(0, true, PA_FLIP_LR);
 | 
					 | 
				
			||||||
  graphicDisplay = P.getGraphicObject();
 | 
					 | 
				
			||||||
  E.begin(graphicDisplay);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  P.setIntensity(1);
 | 
					 | 
				
			||||||
  for (charCode=1; charCode<=9; ++charCode) {
 | 
					 | 
				
			||||||
    P.addChar(charCode, verticalBarFont+2*(charCode-1));
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
  char intro[] = {':', '-', ')', ' ', 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x00};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  // replace the 0 characters, we do not like the "slash"
 | 
					 | 
				
			||||||
  P.addChar('0', newZero);
 | 
					 | 
				
			||||||
  P.print(intro);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
void setupFS() {
 | 
					void setupFS() {
 | 
				
			||||||
  if(!SPIFFS.begin()){
 | 
					  if(!SPIFFS.begin()){
 | 
				
			||||||
@@ -224,7 +158,7 @@ void setupFS() {
 | 
				
			|||||||
void setup(void)
 | 
					void setup(void)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  Serial.println(F("setup():"));
 | 
					  Serial.println(F("setup():"));
 | 
				
			||||||
  setupDisplay();
 | 
					  D.begin();
 | 
				
			||||||
  setupFS();
 | 
					  setupFS();
 | 
				
			||||||
  setupIAS();
 | 
					  setupIAS();
 | 
				
			||||||
  W.begin();
 | 
					  W.begin();
 | 
				
			||||||
@@ -240,97 +174,6 @@ static unsigned long lastTimeOutput_ms = 0;
 | 
				
			|||||||
#define TIME_BETWEEN_REALTIME_UPDATE_ms 60000
 | 
					#define TIME_BETWEEN_REALTIME_UPDATE_ms 60000
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
typedef struct
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
  char name[7];
 | 
					 | 
				
			||||||
  MD_RobotEyes::emotion_t e;
 | 
					 | 
				
			||||||
  uint16_t timePause;  // in milliseconds
 | 
					 | 
				
			||||||
} sampleItem_t;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static const sampleItem_t eSeq[] =
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
  { "Nutral", MD_RobotEyes::E_NEUTRAL, 1000 },
 | 
					 | 
				
			||||||
  { "Blink" , MD_RobotEyes::E_BLINK, 1000 },
 | 
					 | 
				
			||||||
  { "Wink"  , MD_RobotEyes::E_WINK, 1000 },
 | 
					 | 
				
			||||||
  { "Left"  , MD_RobotEyes::E_LOOK_L, 1000 },
 | 
					 | 
				
			||||||
  { "Right" , MD_RobotEyes::E_LOOK_R, 1000 },
 | 
					 | 
				
			||||||
  { "Up"    , MD_RobotEyes::E_LOOK_U, 1000 },
 | 
					 | 
				
			||||||
  { "Down"  , MD_RobotEyes::E_LOOK_D, 1000 },
 | 
					 | 
				
			||||||
  { "Angry" , MD_RobotEyes::E_ANGRY, 1000 },
 | 
					 | 
				
			||||||
  { "Sad"   , MD_RobotEyes::E_SAD, 1000 },
 | 
					 | 
				
			||||||
  { "Evil"  , MD_RobotEyes::E_EVIL, 1000 },
 | 
					 | 
				
			||||||
  { "Evil2" , MD_RobotEyes::E_EVIL2, 1000 },
 | 
					 | 
				
			||||||
  { "Squint", MD_RobotEyes::E_SQUINT, 1000 },
 | 
					 | 
				
			||||||
  { "Dead"  , MD_RobotEyes::E_DEAD, 1000 },
 | 
					 | 
				
			||||||
  { "ScanV" , MD_RobotEyes::E_SCAN_UD, 1000 },
 | 
					 | 
				
			||||||
  { "ScanH" , MD_RobotEyes::E_SCAN_LR, 1000 },
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
#define DISPLAY_ANIM_NAME false
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void loopStartupAnimation() {
 | 
					 | 
				
			||||||
  // show startup animation
 | 
					 | 
				
			||||||
  boolean animationFinished = false;
 | 
					 | 
				
			||||||
  static uint32_t timeStartDelay;
 | 
					 | 
				
			||||||
  static uint8_t index = ARRAY_SIZE(eSeq);
 | 
					 | 
				
			||||||
  static enum { S_IDLE, S_TEXT, S_ANIM, S_PAUSE } state = S_IDLE;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  animationFinished = E.runAnimation();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  switch (state)
 | 
					 | 
				
			||||||
  {
 | 
					 | 
				
			||||||
    case S_IDLE:
 | 
					 | 
				
			||||||
      index++;
 | 
					 | 
				
			||||||
      if (index >= ARRAY_SIZE(eSeq))
 | 
					 | 
				
			||||||
        index = 0;
 | 
					 | 
				
			||||||
      P.displayClear();
 | 
					 | 
				
			||||||
      #if DISPLAY_ANIM_NAME
 | 
					 | 
				
			||||||
        E.setText(eSeq[index].name);
 | 
					 | 
				
			||||||
      #endif
 | 
					 | 
				
			||||||
      state = S_TEXT;
 | 
					 | 
				
			||||||
      break;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    case S_TEXT: // wait for the text to finish
 | 
					 | 
				
			||||||
      if (animationFinished)  // text animation is finished
 | 
					 | 
				
			||||||
      {
 | 
					 | 
				
			||||||
        E.setAnimation(eSeq[index].e, true);
 | 
					 | 
				
			||||||
        state = S_ANIM;
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
      break;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    case S_ANIM:  // checking animation is completed
 | 
					 | 
				
			||||||
      if (animationFinished)  // animation is finished
 | 
					 | 
				
			||||||
      {
 | 
					 | 
				
			||||||
        timeStartDelay = millis();
 | 
					 | 
				
			||||||
        state = S_PAUSE;
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
      break;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    case S_PAUSE: // non blocking waiting for a period between animations
 | 
					 | 
				
			||||||
      if (millis() - timeStartDelay >= eSeq[index].timePause)
 | 
					 | 
				
			||||||
        state = S_IDLE;
 | 
					 | 
				
			||||||
      break;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      default:
 | 
					 | 
				
			||||||
      state = S_IDLE;
 | 
					 | 
				
			||||||
      break;
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void reInitializeDisplay() {
 | 
					 | 
				
			||||||
  static unsigned long last_reinit_ts = 0;
 | 
					 | 
				
			||||||
  #define REINIT_AFTER_ms 5000
 | 
					 | 
				
			||||||
  #define AVOID_REINIT_BEFORE_AND_AFTER_FULLMINUTE_FOR_s 3
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  if (last_reinit_ts == 0) last_reinit_ts = millis();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  if (millis() - last_reinit_ts > REINIT_AFTER_ms
 | 
					 | 
				
			||||||
      && seconds < 60 - AVOID_REINIT_BEFORE_AND_AFTER_FULLMINUTE_FOR_s
 | 
					 | 
				
			||||||
      && seconds > AVOID_REINIT_BEFORE_AND_AFTER_FULLMINUTE_FOR_s) {
 | 
					 | 
				
			||||||
    P.begin();
 | 
					 | 
				
			||||||
    last_reinit_ts = millis();
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void loop(void)
 | 
					void loop(void)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  static int lastMinutes = 0;
 | 
					  static int lastMinutes = 0;
 | 
				
			||||||
@@ -358,59 +201,22 @@ void loop(void)
 | 
				
			|||||||
    return;
 | 
					    return;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  if (millis() < firstLoop_ts + STARTUP1_ANIMATION_DURATION_ms + STARTUP2_ANIMATION_DURATION_ms) {
 | 
					  if (millis() < firstLoop_ts + STARTUP1_ANIMATION_DURATION_ms + STARTUP2_ANIMATION_DURATION_ms) {
 | 
				
			||||||
    loopStartupAnimation();
 | 
					    D.loopEyeAnimation();
 | 
				
			||||||
    return;
 | 
					    return;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if (timeClientInitialized) {
 | 
					  if (timeClientInitialized) {
 | 
				
			||||||
    hours = timeClient.getHours();
 | 
					    realTime.setTime(timeClient.getHours(), timeClient.getMinutes(), timeClient.getSeconds());
 | 
				
			||||||
    minutes = timeClient.getMinutes();
 | 
					 | 
				
			||||||
    seconds = timeClient.getSeconds();
 | 
					 | 
				
			||||||
  } else {
 | 
					  } else {
 | 
				
			||||||
    hours = (millis() / 60 * 60 * 1000) % 24;
 | 
					    realTime.setTime((millis() / 60 * 60 * 1000) % 24, (millis() / 60 * 1000) % 60, (millis() / 1000) % 60);
 | 
				
			||||||
    minutes = (millis() / 60 * 1000) % 60;
 | 
					 | 
				
			||||||
    seconds = (millis() / 1000) % 60;
 | 
					 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  minuteProgressIndicator = seconds/6.7 + 1; // char code 1-8 show vertical bar
 | 
					 | 
				
			||||||
  if (minuteProgressIndicator > 9) minuteProgressIndicator = 9;
 | 
					 | 
				
			||||||
  snprintf(timeBuffer, 10, "%c %2d:%02d", minuteProgressIndicator, hours, minutes);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // standard procedure to display
 | 
					  D.loop();
 | 
				
			||||||
  static uint32_t last_clock_refresh = 0;
 | 
					 | 
				
			||||||
  static uint32_t lastTimeClockNameShown = 0;
 | 
					 | 
				
			||||||
  static boolean showingClockName = false;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  if (showingClockName) {
 | 
					 | 
				
			||||||
    if (millis() - lastTimeClockNameShown > displayClockNameDuration_ms) {
 | 
					 | 
				
			||||||
      // stop showingClockName
 | 
					 | 
				
			||||||
      showingClockName = false;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
  } else {
 | 
					 | 
				
			||||||
    if ((millis() - lastTimeClockNameShown > displayClockNameEvery_ms)
 | 
					 | 
				
			||||||
        && (seconds < 60-doNotShowClockNameBeforeAndAfterMinuteChange_s)
 | 
					 | 
				
			||||||
        && (seconds > doNotShowClockNameBeforeAndAfterMinuteChange_s)) {
 | 
					 | 
				
			||||||
      //P.begin(); // re-initialize, that fixes display problems due to electrical relais feedbacks
 | 
					 | 
				
			||||||
      reInitializeDisplay();
 | 
					 | 
				
			||||||
      P.setIntensity(2);
 | 
					 | 
				
			||||||
      P.print(clockName);
 | 
					 | 
				
			||||||
      lastTimeClockNameShown = millis();
 | 
					 | 
				
			||||||
      showingClockName = true;
 | 
					 | 
				
			||||||
    } else {
 | 
					 | 
				
			||||||
      // showing clock
 | 
					 | 
				
			||||||
      if (millis() - last_clock_refresh > displayRefresh_ms) {
 | 
					 | 
				
			||||||
        // P.begin(); // re-initialize, that fixes display problems due to electrical relais feedbacks
 | 
					 | 
				
			||||||
        reInitializeDisplay();
 | 
					 | 
				
			||||||
        P.setIntensity(1);
 | 
					 | 
				
			||||||
        P.print(timeBuffer);
 | 
					 | 
				
			||||||
        last_clock_refresh = millis();
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // toggle relays
 | 
					  // toggle relays
 | 
				
			||||||
  if (lastMinutes != minutes) {
 | 
					  if (lastMinutes != realTime.getMinutes()) {
 | 
				
			||||||
    R.toggle();
 | 
					    R.toggle();
 | 
				
			||||||
    lastMinutes = minutes;
 | 
					    lastMinutes = realTime.getMinutes();
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  R.loop();
 | 
					  R.loop();
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user