Fix of NTP logic. Minor refactoring.
This commit is contained in:
@@ -2,6 +2,7 @@
|
||||
#define WORDCLOCK_ESP8266_H
|
||||
|
||||
#include <Arduino.h>
|
||||
#include <stdlib.h>
|
||||
#include <ESP8266WebServer.h>
|
||||
#include "led_matrix.h"
|
||||
#include "udp_logger.h"
|
||||
@@ -11,6 +12,13 @@
|
||||
|
||||
#define EEPROM_SIZE (sizeof(EepromLayout_st) / sizeof(uint8_t))
|
||||
|
||||
#define BUILD_YEAR (__DATE__ + 7) /* Will expand to current year at compile time as string. */
|
||||
#define NTP_MININUM_RX_YEAR (atoi(BUILD_YEAR) - 1) /* Will expand to current year at compile time minus one. */
|
||||
#define NTP_MININUM_YEAR (1900) // NTP minimum year is 1900
|
||||
#define NTP_MAX_UPDATE_TIME_US (500000) // 500ms max update time
|
||||
#define NTP_NEXT_UPDATE_DELAY_US (10000000) // 10s delay time between updates
|
||||
#define NTP_WATCHDOG_COUNTER_INIT (30) // Watchdog value, count of retries before restart
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int start_hour;
|
||||
@@ -54,6 +62,7 @@ typedef enum
|
||||
NUM_STATES
|
||||
} ClockState_en;
|
||||
|
||||
bool get_ntp_time(uint32 usec);
|
||||
String leading_zero2digit(int value);
|
||||
uint8_t calculate_dynamic_brightness(uint8_t min_brightness, uint8_t max_brightness, int hours, int minutes, bool summertime);
|
||||
uint8_t update_brightness(void);
|
||||
@@ -67,8 +76,7 @@ void handle_data_request(void);
|
||||
void handle_led_direct(void);
|
||||
void limit_value_ranges(void);
|
||||
void log_time(tm local_time);
|
||||
void ntp_time_update(uint32 *last_ntp_update_us);
|
||||
void ntp_time_update(uint32 *last_ntp_update_us);
|
||||
void ntp_time_update(uint32 max_update_time);
|
||||
void on_state_entry(uint8_t state);
|
||||
void read_settings_from_EEPROM(void);
|
||||
void reset_wifi_credentials(void);
|
||||
|
||||
@@ -48,15 +48,14 @@
|
||||
// ----------------------------------------------------------------------------------
|
||||
// GLOBAL VARIABLES
|
||||
// ----------------------------------------------------------------------------------
|
||||
UDPLogger logger; // Logger
|
||||
UDPLogger logger; // Global UDP logger instance
|
||||
Adafruit_NeoMatrix matrix = Adafruit_NeoMatrix(MATRIX_WIDTH, MATRIX_HEIGHT + 1, NEOPIXEL_PIN,
|
||||
NEO_MATRIX_TOP + NEO_MATRIX_LEFT + NEO_MATRIX_ROWS + NEO_MATRIX_ZIGZAG,
|
||||
NEO_GRB + NEO_KHZ800); // NeoMatrix
|
||||
char strftime_buf[64]; // Time string buffer
|
||||
ESP8266WebServer webserver(HTTP_PORT); // Webserver
|
||||
LEDMatrix led_matrix = LEDMatrix(&matrix, DEFAULT_BRIGHTNESS, &logger); // NeoMatrix wrapper
|
||||
struct tm timeinfo; // Structure tm holds time information
|
||||
time_t now; // Seconds since Epoch (1970) - UTC
|
||||
struct tm time_info; // Structure tm holds time information
|
||||
time_t time_now; // Seconds since Epoch (1970) - UTC
|
||||
|
||||
// ----------------------------------------------------------------------------------
|
||||
// STATIC VARIABLES
|
||||
@@ -70,19 +69,20 @@ static Pong pong = Pong(&led_matrix, &logger);
|
||||
static Snake snake = Snake(&led_matrix, &logger);
|
||||
static Tetris tetris = Tetris(&led_matrix, &logger);
|
||||
|
||||
static uint32 last_ntp_update_us = 0; // time of last NTP update
|
||||
static uint32 last_ntp_update_us = 0; // Time of last NTP update
|
||||
static char strftime_buf[64]; // Time string buffer
|
||||
|
||||
static bool flg_night_mode = false; // state of nightmode
|
||||
static bool flg_reset_wifi_creds = false; // used to reset stored wifi credentials
|
||||
static bool flg_night_mode = false; // State of nightmode
|
||||
static bool flg_reset_wifi_creds = false; // Used to reset stored wifi credentials
|
||||
static bool spiral_direction = false;
|
||||
static float filter_factor = DEFAULT_SMOOTHING_FACTOR; // stores smoothing factor for led transition
|
||||
static float filter_factor = DEFAULT_SMOOTHING_FACTOR; // Stores smoothing factor for led transition, value of 1 represents no smoothing.
|
||||
static int watchdog_counter = 30; // Watchdog counter to trigger restart if NTP update was not possible 30 times in a row (5min)
|
||||
static uint32 last_led_direct_us = 0; // time of last direct LED command (=> fall back to normal mode after timeout)
|
||||
static uint32_t heartbeat_counter = 0; // for heartbeat on-time in seconds
|
||||
static uint32_t main_color_clock = colors_24bit[2]; // color of the clock and digital clock
|
||||
static uint32_t main_color_snake = colors_24bit[1]; // color of the random snake animation
|
||||
static uint8_t current_brightness = DEFAULT_BRIGHTNESS; // current brightness of LEDs
|
||||
static uint8_t current_state = (uint8_t)ST_CLOCK; // stores current state
|
||||
static uint32 last_led_direct_us = 0; // Time of last direct LED command (=> fall back to normal mode after timeout)
|
||||
static uint32_t heartbeat_counter = 0; // Heartbeat on-time in seconds
|
||||
static uint32_t main_color_clock = colors_24bit[2]; // Color of the clock and digital clock
|
||||
static uint32_t main_color_snake = colors_24bit[1]; // Color of the random snake animation
|
||||
static uint8_t current_brightness = DEFAULT_BRIGHTNESS; // Current brightness of LEDs
|
||||
static uint8_t current_state = (uint8_t)ST_CLOCK; // Stores current state
|
||||
|
||||
static const String state_names[NUM_STATES] = {"Clock", "DiClock", "Spiral", "Tetris", "Snake", "PingPong", "Hearts"};
|
||||
static const uint32_t period_timings[NUM_STATES] = {PERIOD_CLOCK_UPDATE_US, PERIOD_CLOCK_UPDATE_US,
|
||||
@@ -170,16 +170,12 @@ void setup()
|
||||
// create UDP Logger to send logging messages via UDP multicast
|
||||
logger = UDPLogger(WiFi.localIP(), LOGGER_MULTICAST_IP, LOGGER_MULTICAST_PORT, "Wordclock 2.0");
|
||||
logger.log_string("Start program\n");
|
||||
delay(10);
|
||||
logger.log_string("Sketchname: " + String(__FILE__));
|
||||
delay(10);
|
||||
logger.log_string("Build: " + String(__TIMESTAMP__));
|
||||
delay(10);
|
||||
logger.log_string("IP: " + WiFi.localIP().toString());
|
||||
delay(10);
|
||||
logger.log_string("Reset Reason: " + ESP.getResetReason());
|
||||
|
||||
if (resetInfo->reason != REASON_SOFT_RESTART)
|
||||
if (resetInfo->reason != REASON_SOFT_RESTART) // only if there was a cold start/hard reset
|
||||
{
|
||||
// quickly test each LED
|
||||
for (int16_t row = 0; row < MATRIX_HEIGHT; row++)
|
||||
@@ -215,12 +211,12 @@ void setup()
|
||||
|
||||
// setup NTP
|
||||
configTime(MY_TZ, NTP_SERVER_URL);
|
||||
ntp_time_update(&last_ntp_update_us); // NTP time update
|
||||
ntp_time_update(NTP_MAX_UPDATE_TIME_US); // NTP time update
|
||||
|
||||
// show the current time for short time in words
|
||||
String timeMessage = time_to_string(timeinfo.tm_hour, timeinfo.tm_min);
|
||||
String timeMessage = time_to_string(time_info.tm_hour, time_info.tm_min);
|
||||
show_string_on_clock(timeMessage, main_color_clock);
|
||||
draw_minute_indicator(timeinfo.tm_min, main_color_clock);
|
||||
draw_minute_indicator(time_info.tm_min, main_color_clock);
|
||||
led_matrix.draw_on_matrix_smooth(filter_factor);
|
||||
|
||||
// init all animation modes
|
||||
@@ -289,7 +285,7 @@ void loop()
|
||||
check_wifi_status(); // check WiFi status before NTP update
|
||||
delay(10);
|
||||
|
||||
ntp_time_update(&last_ntp_update_us); // NTP time update
|
||||
ntp_time_update(NTP_MAX_UPDATE_TIME_US); // NTP time update
|
||||
delay(10);
|
||||
|
||||
current_brightness = update_brightness(); // update brightness every PERIOD_NTP_UPDATE_US
|
||||
@@ -315,29 +311,22 @@ void loop()
|
||||
*
|
||||
* @return boolean - true if NTP update was successful, false otherwise
|
||||
*/
|
||||
bool get_ntp_time(uint32 sec)
|
||||
bool get_ntp_time(uint32 usec)
|
||||
{
|
||||
uint32 start = system_get_time() / 1000; // ms
|
||||
uint32 start_time_us = system_get_time();
|
||||
do
|
||||
{
|
||||
time(&now);
|
||||
localtime_r(&now, &timeinfo);
|
||||
time(&time_now);
|
||||
localtime_r(&time_now, &time_info);
|
||||
delay(10);
|
||||
} while (((system_get_time() / 1000 - start) <= (1000 * sec)) && (timeinfo.tm_year < (2023 - 1900)));
|
||||
} while (((system_get_time() - start_time_us) <= usec) && (time_info.tm_year < (NTP_MININUM_RX_YEAR - NTP_MININUM_YEAR)));
|
||||
|
||||
if (timeinfo.tm_year <= (2023 - 1900))
|
||||
{
|
||||
return false; // the NTP call was not successful
|
||||
}
|
||||
else
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return ((time_info.tm_year <= (NTP_MININUM_RX_YEAR - NTP_MININUM_YEAR)) ? false : true);
|
||||
}
|
||||
|
||||
void log_time(tm local_time)
|
||||
{
|
||||
strftime(strftime_buf, sizeof(strftime_buf), "%c", &timeinfo);
|
||||
strftime(strftime_buf, sizeof(strftime_buf), "%c", &time_info);
|
||||
logger.log_string(String(strftime_buf));
|
||||
}
|
||||
|
||||
@@ -347,13 +336,13 @@ void handle_current_state()
|
||||
{
|
||||
case ST_CLOCK: // state clock
|
||||
{
|
||||
(void)show_string_on_clock(time_to_string((uint8_t)timeinfo.tm_hour, (uint8_t)timeinfo.tm_min), main_color_clock);
|
||||
draw_minute_indicator((uint8_t)timeinfo.tm_min, main_color_clock);
|
||||
(void)show_string_on_clock(time_to_string((uint8_t)time_info.tm_hour, (uint8_t)time_info.tm_min), main_color_clock);
|
||||
draw_minute_indicator((uint8_t)time_info.tm_min, main_color_clock);
|
||||
break;
|
||||
}
|
||||
case ST_DICLOCK: // state diclock
|
||||
{
|
||||
show_digital_clock((uint8_t)timeinfo.tm_hour, (uint8_t)timeinfo.tm_min, main_color_clock);
|
||||
show_digital_clock((uint8_t)time_info.tm_hour, (uint8_t)time_info.tm_min, main_color_clock);
|
||||
break;
|
||||
}
|
||||
case ST_SPIRAL: // state spiral
|
||||
@@ -447,8 +436,8 @@ void check_wifi_status()
|
||||
void check_night_mode()
|
||||
{
|
||||
// check if nightmode need to be activated
|
||||
int hours = timeinfo.tm_hour;
|
||||
int minutes = timeinfo.tm_min;
|
||||
int hours = time_info.tm_hour;
|
||||
int minutes = time_info.tm_min;
|
||||
|
||||
if ((hours == night_mode_times_ps->start_hour) && (minutes == night_mode_times_ps->start_min))
|
||||
{
|
||||
@@ -465,21 +454,21 @@ void check_night_mode()
|
||||
*
|
||||
* @param None
|
||||
*/
|
||||
void ntp_time_update(uint32 *last_ntp_update_us)
|
||||
void ntp_time_update(uint32 max_update_time)
|
||||
{
|
||||
// NTP time update
|
||||
bool ntp_retval = get_ntp_time(*last_ntp_update_us / 10000000);
|
||||
bool ntp_retval = get_ntp_time(max_update_time);
|
||||
|
||||
if (ntp_retval == true)
|
||||
{
|
||||
log_time(timeinfo);
|
||||
*last_ntp_update_us = system_get_time();
|
||||
watchdog_counter = 30;
|
||||
log_time(time_info);
|
||||
last_ntp_update_us = system_get_time();
|
||||
watchdog_counter = NTP_WATCHDOG_COUNTER_INIT;
|
||||
}
|
||||
else
|
||||
{
|
||||
logger.log_string("NTP-Update was not successful.");
|
||||
*last_ntp_update_us += 10000000;
|
||||
last_ntp_update_us += NTP_NEXT_UPDATE_DELAY_US;
|
||||
watchdog_counter--;
|
||||
}
|
||||
|
||||
@@ -499,7 +488,7 @@ void ntp_time_update(uint32 *last_ntp_update_us)
|
||||
*/
|
||||
void on_state_entry(uint8_t state)
|
||||
{
|
||||
filter_factor = 0.5f;
|
||||
filter_factor = DEFAULT_SMOOTHING_FACTOR;
|
||||
switch (state)
|
||||
{
|
||||
case ST_SPIRAL:
|
||||
@@ -1030,9 +1019,9 @@ uint8_t update_brightness()
|
||||
{
|
||||
new_brightness = calculate_dynamic_brightness(brightness_ps->dyn_brightness_min,
|
||||
brightness_ps->dyn_brightness_max,
|
||||
timeinfo.tm_hour,
|
||||
timeinfo.tm_min,
|
||||
timeinfo.tm_isdst);
|
||||
time_info.tm_hour,
|
||||
time_info.tm_min,
|
||||
time_info.tm_isdst);
|
||||
}
|
||||
else // use static brightness
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user