Refactoring for stability, etc. Add new animation.
This commit is contained in:
@@ -80,8 +80,8 @@ int NTPClientPlus::updateNTP()
|
||||
// check if time off last ntp update is roughly in the same range: 100sec apart (validation check)
|
||||
if (this->_lastSecsSince1900 == 0 || tempSecsSince1900 - this->_lastSecsSince1900 < 100000)
|
||||
{
|
||||
// Only update time then
|
||||
this->_lastUpdate = millis() - (NTP_RECEIVE_WAIT_TIME_MS * (conn_tries + 1)); // Account for delay in reading the time
|
||||
// Only update time then account for delay in reading the time
|
||||
this->_lastUpdate = (system_get_time() / 1000) - (NTP_RECEIVE_WAIT_TIME_MS * (conn_tries + 1));
|
||||
this->_secsSince1900 = tempSecsSince1900;
|
||||
this->_currentEpoc = this->_secsSince1900 - UNIX_TIMESTAMP_1900;
|
||||
|
||||
@@ -141,7 +141,7 @@ unsigned long NTPClientPlus::getSecsSince1900() const
|
||||
{
|
||||
return this->_timeOffset + // User offset
|
||||
this->_secsSince1900 + // seconds returned by the NTP server
|
||||
((millis() - this->_lastUpdate) / 1000); // Time since last update
|
||||
(((system_get_time() / 1000) - this->_lastUpdate) / 1000); // Time since last update
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -685,8 +685,8 @@ bool NTPClientPlus::updateSWChange()
|
||||
|
||||
void wait(unsigned long time)
|
||||
{
|
||||
unsigned long start = millis();
|
||||
while (millis() - start < time)
|
||||
unsigned long start = (system_get_time() / 1000);
|
||||
while (((system_get_time() / 1000) - start) < time)
|
||||
{
|
||||
yield();
|
||||
};
|
||||
|
||||
@@ -21,7 +21,7 @@ void UDPLogger::set_name(String name)
|
||||
void UDPLogger::log_string(String message)
|
||||
{
|
||||
// wait 5 milliseconds if last send was less than 5 milliseconds before
|
||||
if (millis() < (_lastSend + 5))
|
||||
if ((system_get_time() / 1000) < (_lastSend + 5))
|
||||
{
|
||||
delay(5);
|
||||
}
|
||||
@@ -31,13 +31,13 @@ void UDPLogger::log_string(String message)
|
||||
message.toCharArray(_packetBuffer, 100);
|
||||
_udp.print(_packetBuffer);
|
||||
_udp.endPacket();
|
||||
_lastSend = millis();
|
||||
_lastSend = (system_get_time() / 1000);
|
||||
}
|
||||
|
||||
void UDPLogger::log_color_24bit(uint32_t color)
|
||||
{
|
||||
uint8_t result_red = color >> 16 & 0xff;
|
||||
uint8_t result_green = color >> 8 & 0xff;
|
||||
uint8_t result_blue = color & 0xff;
|
||||
uint8_t result_red = color >> 16 & UINT8_MAX;
|
||||
uint8_t result_green = color >> 8 & UINT8_MAX;
|
||||
uint8_t result_blue = color & UINT8_MAX;
|
||||
log_string(String(result_red) + ", " + String(result_green) + ", " + String(result_blue));
|
||||
}
|
||||
@@ -60,10 +60,10 @@ void Pong::loopCycle()
|
||||
*/
|
||||
void Pong::ctrlUp(uint8_t playerid)
|
||||
{
|
||||
if (millis() > _lastButtonClick + DEBOUNCE_TIME)
|
||||
if ((system_get_time() / 1000) > (_lastButtonClick + DEBOUNCE_TIME))
|
||||
{
|
||||
_playerMovement[playerid] = PADDLE_MOVE_DOWN; // need to swap direction as field is rotated 180deg
|
||||
_lastButtonClick = millis();
|
||||
_lastButtonClick = (system_get_time() / 1000);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -74,10 +74,10 @@ void Pong::ctrlUp(uint8_t playerid)
|
||||
*/
|
||||
void Pong::ctrlDown(uint8_t playerid)
|
||||
{
|
||||
if (millis() > _lastButtonClick + DEBOUNCE_TIME)
|
||||
if ((system_get_time() / 1000) > (_lastButtonClick + DEBOUNCE_TIME))
|
||||
{
|
||||
_playerMovement[playerid] = PADDLE_MOVE_UP; // need to swap direction as field is rotated 180deg
|
||||
_lastButtonClick = millis();
|
||||
_lastButtonClick = (system_get_time() / 1000);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -88,10 +88,10 @@ void Pong::ctrlDown(uint8_t playerid)
|
||||
*/
|
||||
void Pong::ctrlNone(uint8_t playerid)
|
||||
{
|
||||
if (millis() > _lastButtonClick + DEBOUNCE_TIME)
|
||||
if ((system_get_time() / 1000) > (_lastButtonClick + DEBOUNCE_TIME))
|
||||
{
|
||||
_playerMovement[playerid] = PADDLE_MOVE_NONE;
|
||||
_lastButtonClick = millis();
|
||||
_lastButtonClick = (system_get_time() / 1000);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -102,9 +102,9 @@ void Pong::ctrlNone(uint8_t playerid)
|
||||
*/
|
||||
void Pong::initGame(uint8_t numBots)
|
||||
{
|
||||
(*_logger).log_string("Pong: init with " + String(numBots) + " Bots");
|
||||
_logger->log_string("Pong: init with " + String(numBots) + " Bots");
|
||||
resetLEDs();
|
||||
_lastButtonClick = millis();
|
||||
_lastButtonClick = (system_get_time() / 1000);
|
||||
|
||||
_numBots = numBots;
|
||||
|
||||
@@ -134,11 +134,11 @@ void Pong::initGame(uint8_t numBots)
|
||||
void Pong::updateBall()
|
||||
{
|
||||
bool hitBall = false;
|
||||
if ((millis() - _lastBallUpdate) < _ballDelay)
|
||||
if (((system_get_time() / 1000) - _lastBallUpdate) < _ballDelay)
|
||||
{
|
||||
return;
|
||||
}
|
||||
_lastBallUpdate = millis();
|
||||
_lastBallUpdate = (system_get_time() / 1000);
|
||||
toggleLed(_ball.x, _ball.y, LED_TYPE_OFF);
|
||||
|
||||
// collision detection for player 1
|
||||
@@ -199,7 +199,7 @@ void Pong::updateBall()
|
||||
*/
|
||||
void Pong::endGame()
|
||||
{
|
||||
(*_logger).log_string("Pong: Game ended");
|
||||
_logger->log_string("Pong: Game ended");
|
||||
_gameState = GAME_STATE_END;
|
||||
toggleLed(_ball.x, _ball.y, LED_TYPE_BALL_RED);
|
||||
}
|
||||
@@ -210,11 +210,11 @@ void Pong::endGame()
|
||||
*/
|
||||
void Pong::updateGame()
|
||||
{
|
||||
if ((millis() - _lastDrawUpdate) < GAME_DELAY)
|
||||
if (((system_get_time() / 1000) - _lastDrawUpdate) < GAME_DELAY)
|
||||
{
|
||||
return;
|
||||
}
|
||||
_lastDrawUpdate = millis();
|
||||
_lastDrawUpdate = (system_get_time() / 1000);
|
||||
|
||||
// turn off paddle LEDs
|
||||
for (uint8_t p = 0; p < PLAYER_AMOUNT; p++)
|
||||
@@ -297,7 +297,7 @@ uint8_t Pong::getPlayerMovement(uint8_t playerId)
|
||||
*/
|
||||
void Pong::resetLEDs()
|
||||
{
|
||||
(*_ledmatrix).flush();
|
||||
_ledmatrix->flush();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -328,5 +328,5 @@ void Pong::toggleLed(uint8_t x, uint8_t y, uint8_t type)
|
||||
break;
|
||||
}
|
||||
|
||||
(*_ledmatrix).grid_add_pixel(x, y, color);
|
||||
_ledmatrix->grid_add_pixel(x, y, color);
|
||||
}
|
||||
@@ -58,11 +58,11 @@ void Snake::loopCycle()
|
||||
*/
|
||||
void Snake::ctrlUp()
|
||||
{
|
||||
if (millis() > _lastButtonClick + DEBOUNCE_TIME && _gameState == GAME_STATE_RUNNING)
|
||||
if ((system_get_time() / 1000) > _lastButtonClick + DEBOUNCE_TIME && _gameState == GAME_STATE_RUNNING)
|
||||
{
|
||||
(*_logger).log_string("Snake: UP");
|
||||
_logger->log_string("Snake: UP");
|
||||
_userDirection = DIRECTION_DOWN; // need to swap direction as field is rotated 180deg
|
||||
_lastButtonClick = millis();
|
||||
_lastButtonClick = (system_get_time() / 1000);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -72,11 +72,11 @@ void Snake::ctrlUp()
|
||||
*/
|
||||
void Snake::ctrlDown()
|
||||
{
|
||||
if (millis() > _lastButtonClick + DEBOUNCE_TIME && _gameState == GAME_STATE_RUNNING)
|
||||
if ((system_get_time() / 1000) > _lastButtonClick + DEBOUNCE_TIME && _gameState == GAME_STATE_RUNNING)
|
||||
{
|
||||
_logger->log_string("Snake: DOWN");
|
||||
_userDirection = DIRECTION_UP; // need to swap direction as field is rotated 180deg
|
||||
_lastButtonClick = millis();
|
||||
_lastButtonClick = (system_get_time() / 1000);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -86,11 +86,11 @@ void Snake::ctrlDown()
|
||||
*/
|
||||
void Snake::ctrlRight()
|
||||
{
|
||||
if (millis() > _lastButtonClick + DEBOUNCE_TIME && _gameState == GAME_STATE_RUNNING)
|
||||
if ((system_get_time() / 1000) > _lastButtonClick + DEBOUNCE_TIME && _gameState == GAME_STATE_RUNNING)
|
||||
{
|
||||
_logger->log_string("Snake: RIGHT");
|
||||
_userDirection = DIRECTION_LEFT; // need to swap direction as field is rotated 180deg
|
||||
_lastButtonClick = millis();
|
||||
_lastButtonClick = (system_get_time() / 1000);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -100,11 +100,11 @@ void Snake::ctrlRight()
|
||||
*/
|
||||
void Snake::ctrlLeft()
|
||||
{
|
||||
if (millis() > _lastButtonClick + DEBOUNCE_TIME && _gameState == GAME_STATE_RUNNING)
|
||||
if ((system_get_time() / 1000) > _lastButtonClick + DEBOUNCE_TIME && _gameState == GAME_STATE_RUNNING)
|
||||
{
|
||||
_logger->log_string("Snake: LEFT");
|
||||
_userDirection = DIRECTION_RIGHT; // need to swap direction as field is rotated 180deg
|
||||
_lastButtonClick = millis();
|
||||
_lastButtonClick = (system_get_time() / 1000);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -131,7 +131,7 @@ void Snake::initGame()
|
||||
_food.y = -1;
|
||||
_wormLength = MIN_TAIL_LENGTH;
|
||||
_userDirection = DIRECTION_LEFT;
|
||||
_lastButtonClick = millis();
|
||||
_lastButtonClick = (system_get_time() / 1000);
|
||||
|
||||
for (int i = 0; i < MAX_TAIL_LENGTH; i++)
|
||||
{
|
||||
@@ -148,7 +148,7 @@ void Snake::initGame()
|
||||
*/
|
||||
void Snake::updateGame()
|
||||
{
|
||||
if ((millis() - _lastDrawUpdate) > GAME_DELAY)
|
||||
if (((system_get_time() / 1000) - _lastDrawUpdate) > GAME_DELAY)
|
||||
{
|
||||
_logger->log_string("Snake: update game");
|
||||
toggleLed(_tail[_wormLength - 1].x, _tail[_wormLength - 1].y, LED_TYPE_OFF);
|
||||
@@ -197,7 +197,7 @@ void Snake::updateGame()
|
||||
updateFood();
|
||||
}
|
||||
|
||||
_lastDrawUpdate = millis();
|
||||
_lastDrawUpdate = (system_get_time() / 1000);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -26,7 +26,7 @@ Tetris::Tetris(LEDMatrix *myledmatrix, UDPLogger *mylogger)
|
||||
{
|
||||
_logger = mylogger;
|
||||
_ledmatrix = myledmatrix;
|
||||
_gameStatet = GAME_STATE_READY;
|
||||
_gameState = GAME_STATE_READY;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -35,7 +35,7 @@ Tetris::Tetris(LEDMatrix *myledmatrix, UDPLogger *mylogger)
|
||||
*/
|
||||
void Tetris::loopCycle()
|
||||
{
|
||||
switch (_gameStatet)
|
||||
switch (_gameState)
|
||||
{
|
||||
case GAME_STATE_READY:
|
||||
|
||||
@@ -51,18 +51,18 @@ void Tetris::loopCycle()
|
||||
// move faster down when allow drop
|
||||
if (_allowdrop)
|
||||
{
|
||||
if (millis() > _droptime + 50)
|
||||
if ((system_get_time() / 1000) > (_droptime + 50))
|
||||
{
|
||||
_droptime = millis();
|
||||
_droptime = (system_get_time() / 1000);
|
||||
shiftActiveBrick(DIR_DOWN);
|
||||
printField();
|
||||
}
|
||||
}
|
||||
|
||||
// move down with regular speed
|
||||
if ((millis() - _prevUpdateTime) > (_brickSpeed * _speedtetris / 100))
|
||||
if (((system_get_time() / 1000) - _prevUpdateTime) > (_brickSpeed * _speedtetris / 100))
|
||||
{
|
||||
_prevUpdateTime = millis();
|
||||
_prevUpdateTime = (system_get_time() / 1000);
|
||||
shiftActiveBrick(DIR_DOWN);
|
||||
printField();
|
||||
}
|
||||
@@ -74,7 +74,7 @@ void Tetris::loopCycle()
|
||||
// and create new brick at top of field
|
||||
checkFullLines();
|
||||
newActiveBrick();
|
||||
_prevUpdateTime = millis(); // Reset update time to avoid brick dropping two spaces
|
||||
_prevUpdateTime = (system_get_time() / 1000); // Reset update time to avoid brick dropping two spaces
|
||||
}
|
||||
break;
|
||||
case GAME_STATE_PAUSED:
|
||||
@@ -85,17 +85,17 @@ void Tetris::loopCycle()
|
||||
if (_tetrisGameOver == true)
|
||||
{
|
||||
_tetrisGameOver = false;
|
||||
(*_logger).log_string("Tetris: end");
|
||||
_logger->log_string("Tetris: end");
|
||||
everythingRed();
|
||||
_tetrisshowscore = millis();
|
||||
_tetrisshowscore = (system_get_time() / 1000);
|
||||
}
|
||||
|
||||
if (millis() > (_tetrisshowscore + RED_END_TIME))
|
||||
if ((system_get_time() / 1000) > (_tetrisshowscore + RED_END_TIME))
|
||||
{
|
||||
resetLEDs();
|
||||
_score = _nbRowsTotal;
|
||||
showscore();
|
||||
_gameStatet = GAME_STATE_READY;
|
||||
_gameState = GAME_STATE_READY;
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -107,10 +107,10 @@ void Tetris::loopCycle()
|
||||
*/
|
||||
void Tetris::ctrlStart()
|
||||
{
|
||||
if (millis() > _lastButtonClick + DEBOUNCE_TIME)
|
||||
if ((system_get_time() / 1000) > _lastButtonClick + DEBOUNCE_TIME)
|
||||
{
|
||||
_lastButtonClick = millis();
|
||||
_gameStatet = GAME_STATE_INIT;
|
||||
_lastButtonClick = (system_get_time() / 1000);
|
||||
_gameState = GAME_STATE_INIT;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -120,20 +120,20 @@ void Tetris::ctrlStart()
|
||||
*/
|
||||
void Tetris::ctrlPlayPause()
|
||||
{
|
||||
if (millis() > _lastButtonClick + DEBOUNCE_TIME)
|
||||
if ((system_get_time() / 1000) > _lastButtonClick + DEBOUNCE_TIME)
|
||||
{
|
||||
_lastButtonClick = millis();
|
||||
if (_gameStatet == GAME_STATE_PAUSED)
|
||||
_lastButtonClick = (system_get_time() / 1000);
|
||||
if (_gameState == GAME_STATE_PAUSED)
|
||||
{
|
||||
(*_logger).log_string("Tetris: continue");
|
||||
_logger->log_string("Tetris: continue");
|
||||
|
||||
_gameStatet = GAME_STATE_RUNNING;
|
||||
_gameState = GAME_STATE_RUNNING;
|
||||
}
|
||||
else if (_gameStatet == GAME_STATE_RUNNING)
|
||||
else if (_gameState == GAME_STATE_RUNNING)
|
||||
{
|
||||
(*_logger).log_string("Tetris: pause");
|
||||
_logger->log_string("Tetris: pause");
|
||||
|
||||
_gameStatet = GAME_STATE_PAUSED;
|
||||
_gameState = GAME_STATE_PAUSED;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -144,9 +144,9 @@ void Tetris::ctrlPlayPause()
|
||||
*/
|
||||
void Tetris::ctrlRight()
|
||||
{
|
||||
if (millis() > _lastButtonClick + DEBOUNCE_TIME && _gameStatet == GAME_STATE_RUNNING)
|
||||
if ((system_get_time() / 1000) > _lastButtonClick + DEBOUNCE_TIME && _gameState == GAME_STATE_RUNNING)
|
||||
{
|
||||
_lastButtonClick = millis();
|
||||
_lastButtonClick = (system_get_time() / 1000);
|
||||
shiftActiveBrick(DIR_RIGHT);
|
||||
printField();
|
||||
}
|
||||
@@ -158,9 +158,9 @@ void Tetris::ctrlRight()
|
||||
*/
|
||||
void Tetris::ctrlLeft()
|
||||
{
|
||||
if (millis() > _lastButtonClick + DEBOUNCE_TIME && _gameStatet == GAME_STATE_RUNNING)
|
||||
if ((system_get_time() / 1000) > _lastButtonClick + DEBOUNCE_TIME && _gameState == GAME_STATE_RUNNING)
|
||||
{
|
||||
_lastButtonClick = millis();
|
||||
_lastButtonClick = (system_get_time() / 1000);
|
||||
shiftActiveBrick(DIR_LEFT);
|
||||
printField();
|
||||
}
|
||||
@@ -172,9 +172,9 @@ void Tetris::ctrlLeft()
|
||||
*/
|
||||
void Tetris::ctrlUp()
|
||||
{
|
||||
if (millis() > _lastButtonClick + DEBOUNCE_TIME && _gameStatet == GAME_STATE_RUNNING)
|
||||
if ((system_get_time() / 1000) > _lastButtonClick + DEBOUNCE_TIME && _gameState == GAME_STATE_RUNNING)
|
||||
{
|
||||
_lastButtonClick = millis();
|
||||
_lastButtonClick = (system_get_time() / 1000);
|
||||
rotateActiveBrick();
|
||||
printField();
|
||||
}
|
||||
@@ -187,10 +187,10 @@ void Tetris::ctrlUp()
|
||||
void Tetris::ctrlDown()
|
||||
{
|
||||
// longer debounce time, to prevent immediate drop
|
||||
if (millis() > _lastButtonClickr + DEBOUNCE_TIME * 5 && _gameStatet == GAME_STATE_RUNNING)
|
||||
if ((system_get_time() / 1000) > _lastButtonClickr + DEBOUNCE_TIME * 5 && _gameState == GAME_STATE_RUNNING)
|
||||
{
|
||||
_allowdrop = true;
|
||||
_lastButtonClickr = millis();
|
||||
_lastButtonClickr = (system_get_time() / 1000);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -221,7 +221,7 @@ void Tetris::resetLEDs()
|
||||
*/
|
||||
void Tetris::tetrisInit()
|
||||
{
|
||||
(*_logger).log_string("Tetris: init");
|
||||
_logger->log_string("Tetris: init");
|
||||
|
||||
clearField();
|
||||
_brickSpeed = INIT_SPEED;
|
||||
@@ -230,9 +230,9 @@ void Tetris::tetrisInit()
|
||||
_tetrisGameOver = false;
|
||||
|
||||
newActiveBrick();
|
||||
_prevUpdateTime = millis();
|
||||
_prevUpdateTime = (system_get_time() / 1000);
|
||||
|
||||
_gameStatet = GAME_STATE_RUNNING;
|
||||
_gameState = GAME_STATE_RUNNING;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -318,7 +318,7 @@ void Tetris::newActiveBrick()
|
||||
if (checkFieldCollision(&_activeBrick))
|
||||
{
|
||||
_tetrisGameOver = true;
|
||||
_gameStatet = GAME_STATE_END;
|
||||
_gameState = GAME_STATE_END;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -437,3 +437,20 @@ int random_tetris(bool init)
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int draw_heart_animation(void)
|
||||
{
|
||||
static uint8_t frame_idx = 0;
|
||||
|
||||
for (int col = 0; col < MATRIX_WIDTH; col++)
|
||||
{
|
||||
for (int row = 0; row < MATRIX_HEIGHT; row++)
|
||||
{
|
||||
led_matrix.grid_add_pixel(col, row, heart_frames_colormap_11x11[frame_idx][col][row]);
|
||||
}
|
||||
}
|
||||
|
||||
// Increase frame index per call until HEART_ANIMATION_FRAMES - 1 for array index.
|
||||
frame_idx = (frame_idx >= (HEART_ANIMATION_FRAMES - 1)) ? 0 : frame_idx + 1;
|
||||
return 0;
|
||||
}
|
||||
@@ -50,9 +50,9 @@ uint32_t LEDMatrix::color_24bit(uint8_t r, uint8_t g, uint8_t b)
|
||||
*/
|
||||
uint16_t LEDMatrix::color_24_to_16bit(uint32_t color_24bit)
|
||||
{
|
||||
uint8_t r = color_24bit >> 16 & 0xff;
|
||||
uint8_t g = color_24bit >> 8 & 0xff;
|
||||
uint8_t b = color_24bit & 0xff;
|
||||
uint8_t r = color_24bit >> 16 & UINT8_MAX;
|
||||
uint8_t g = color_24bit >> 8 & UINT8_MAX;
|
||||
uint8_t b = color_24bit & UINT8_MAX;
|
||||
return ((uint16_t)(r & 0xF8) << 8) |
|
||||
((uint16_t)(g & 0xFC) << 3) |
|
||||
(b >> 3);
|
||||
@@ -90,13 +90,13 @@ uint32_t LEDMatrix::wheel(uint8_t WheelPos)
|
||||
*/
|
||||
uint32_t LEDMatrix::interpolate_color_24bit(uint32_t color1, uint32_t color2, float factor)
|
||||
{
|
||||
uint8_t resultRed = color1 >> 16 & 0xff;
|
||||
uint8_t resultGreen = color1 >> 8 & 0xff;
|
||||
uint8_t resultBlue = color1 & 0xff;
|
||||
resultRed = (uint8_t)(resultRed + (int16_t)(factor * ((int16_t)(color2 >> 16 & 0xff) - (int16_t)resultRed)));
|
||||
resultGreen = (uint8_t)(resultGreen + (int16_t)(factor * ((int16_t)(color2 >> 8 & 0xff) - (int16_t)resultGreen)));
|
||||
resultBlue = (uint8_t)(resultBlue + (int16_t)(factor * ((int16_t)(color2 & 0xff) - (int16_t)resultBlue)));
|
||||
return color_24bit(resultRed, resultGreen, resultBlue);
|
||||
uint8_t result_R = color1 >> 16 & UINT8_MAX;
|
||||
uint8_t result_G = color1 >> 8 & UINT8_MAX;
|
||||
uint8_t result_B = color1 & UINT8_MAX;
|
||||
result_R = (uint8_t)(result_R + (int16_t)(factor * ((int16_t)(color2 >> 16 & UINT8_MAX) - (int16_t)result_R)));
|
||||
result_G = (uint8_t)(result_G + (int16_t)(factor * ((int16_t)(color2 >> 8 & UINT8_MAX) - (int16_t)result_G)));
|
||||
result_B = (uint8_t)(result_B + (int16_t)(factor * ((int16_t)(color2 & UINT8_MAX) - (int16_t)result_B)));
|
||||
return color_24bit(result_R, result_G, result_B);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -128,19 +128,19 @@ void LEDMatrix::set_min_indicator(uint8_t pattern, uint32_t color)
|
||||
// 0 -> 0000
|
||||
if (pattern & 1)
|
||||
{
|
||||
_target_indicators[0] = color;
|
||||
_target_minute_indicators[0] = color;
|
||||
}
|
||||
if (pattern >> 1 & 1)
|
||||
{
|
||||
_target_indicators[1] = color;
|
||||
_target_minute_indicators[1] = color;
|
||||
}
|
||||
if (pattern >> 2 & 1)
|
||||
{
|
||||
_target_indicators[2] = color;
|
||||
_target_minute_indicators[2] = color;
|
||||
}
|
||||
if (pattern >> 3 & 1)
|
||||
{
|
||||
_target_indicators[3] = color;
|
||||
_target_minute_indicators[3] = color;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -158,10 +158,6 @@ void LEDMatrix::grid_add_pixel(uint8_t x, uint8_t y, uint32_t color)
|
||||
{
|
||||
_target_grid[y][x] = color;
|
||||
}
|
||||
else
|
||||
{
|
||||
// logger->log_string("Index out of Range: " + String(x) + ", " + String(y));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -179,10 +175,10 @@ void LEDMatrix::flush(void)
|
||||
}
|
||||
}
|
||||
// set every minutes indicator led to 0
|
||||
_target_indicators[0] = 0;
|
||||
_target_indicators[1] = 0;
|
||||
_target_indicators[2] = 0;
|
||||
_target_indicators[3] = 0;
|
||||
_target_minute_indicators[0] = 0;
|
||||
_target_minute_indicators[1] = 0;
|
||||
_target_minute_indicators[2] = 0;
|
||||
_target_minute_indicators[3] = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -215,31 +211,31 @@ void LEDMatrix::_draw_on_matrix(float factor)
|
||||
uint32_t filtered_color = 0;
|
||||
|
||||
// loop over all leds in matrix
|
||||
for (int s = 0; s < MATRIX_WIDTH; s++)
|
||||
for (uint8_t col = 0; col < MATRIX_WIDTH; col++)
|
||||
{
|
||||
for (int z = 0; z < MATRIX_HEIGHT; z++)
|
||||
for (uint8_t row = 0; row < MATRIX_HEIGHT; row++)
|
||||
{
|
||||
// inplement momentum as smooth transistion function
|
||||
uint32_t filtered_color = interpolate_color_24bit(_current_grid[z][s], _target_grid[z][s], factor);
|
||||
_neomatrix->drawPixel(s, z, color_24_to_16bit(filtered_color));
|
||||
_current_grid[z][s] = filtered_color;
|
||||
// implement momentum as smooth transistion function
|
||||
filtered_color = interpolate_color_24bit(_current_grid[row][col], _target_grid[row][col], factor);
|
||||
_neomatrix->drawPixel(col, row, color_24_to_16bit(filtered_color));
|
||||
_current_grid[row][col] = filtered_color;
|
||||
total_current += _calc_estimated_led_current(filtered_color);
|
||||
}
|
||||
}
|
||||
|
||||
// loop over all minute indicator leds
|
||||
for (int i = 0; i < 4; i++)
|
||||
for (uint8_t i = 0; i < 4; i++)
|
||||
{
|
||||
filtered_color = interpolate_color_24bit(_current_indicators[i], _target_indicators[i], factor);
|
||||
filtered_color = interpolate_color_24bit(_current_minute_indicators[i], _target_minute_indicators[i], factor);
|
||||
_neomatrix->drawPixel(MATRIX_WIDTH - (1 + i), MATRIX_HEIGHT, color_24_to_16bit(filtered_color));
|
||||
_current_indicators[i] = filtered_color;
|
||||
_current_minute_indicators[i] = filtered_color;
|
||||
total_current += _calc_estimated_led_current(filtered_color);
|
||||
}
|
||||
|
||||
// Check if totalCurrent reaches CURRENTLIMIT -> if yes reduce brightness
|
||||
// Check if totalCurrent reaches _current_limit -> if yes reduce brightness
|
||||
if (total_current > _current_limit)
|
||||
{
|
||||
uint8_t new_brightness = _brightness * float(_current_limit) / float(total_current);
|
||||
uint8_t new_brightness = (uint8)(_brightness * (float(_current_limit) / float(total_current)));
|
||||
_neomatrix->setBrightness(new_brightness);
|
||||
}
|
||||
_neomatrix->show();
|
||||
@@ -319,9 +315,9 @@ void LEDMatrix::set_brightness(uint8_t brightness)
|
||||
uint16_t LEDMatrix::_calc_estimated_led_current(uint32_t color)
|
||||
{
|
||||
// extract rgb values
|
||||
uint8_t red = color >> 16 & 0xff;
|
||||
uint8_t green = color >> 8 & 0xff;
|
||||
uint8_t blue = color & 0xff;
|
||||
uint8_t red = color >> 16 & UINT8_MAX;
|
||||
uint8_t green = color >> 8 & UINT8_MAX;
|
||||
uint8_t blue = color & UINT8_MAX;
|
||||
|
||||
// Linear estimation: 20mA for full brightness per LED
|
||||
// (calculation avoids float numbers)
|
||||
|
||||
@@ -16,38 +16,36 @@ const String clock_chars_as_string = "ESRISTNFUNFVIERTELZEHNZWANZIGHVORPIKACHUNA
|
||||
void draw_minute_indicator(uint8_t minutes, uint32_t color)
|
||||
{
|
||||
// separate LEDs for minutes in an additional row
|
||||
switch (minutes % 5)
|
||||
{
|
||||
switch (minutes % 5)
|
||||
{
|
||||
case 1:
|
||||
{
|
||||
led_matrix.set_min_indicator(0b1000, color);
|
||||
break;
|
||||
}
|
||||
case 1:
|
||||
{
|
||||
led_matrix.set_min_indicator(0b1000, color);
|
||||
break;
|
||||
}
|
||||
|
||||
case 2:
|
||||
{
|
||||
led_matrix.set_min_indicator(0b1100, color);
|
||||
break;
|
||||
}
|
||||
case 2:
|
||||
{
|
||||
led_matrix.set_min_indicator(0b1100, color);
|
||||
break;
|
||||
}
|
||||
|
||||
case 3:
|
||||
{
|
||||
led_matrix.set_min_indicator(0b1110, color);
|
||||
break;
|
||||
}
|
||||
case 3:
|
||||
{
|
||||
led_matrix.set_min_indicator(0b1110, color);
|
||||
break;
|
||||
}
|
||||
|
||||
case 4:
|
||||
{
|
||||
led_matrix.set_min_indicator(0b1111, color);
|
||||
break;
|
||||
}
|
||||
case 0:
|
||||
default:
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
case 4:
|
||||
{
|
||||
led_matrix.set_min_indicator(0b1111, color);
|
||||
break;
|
||||
}
|
||||
case 0:
|
||||
default:
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -49,20 +49,22 @@
|
||||
// DEBUG
|
||||
uint32_t dbg_counter = 0; // TODO RM
|
||||
|
||||
const String state_names[] = {"Clock", "DiClock", "Spiral", "Tetris", "Snake", "PingPong"};
|
||||
const String state_names[] = {"Clock", "DiClock", "Spiral", "Tetris", "Snake", "PingPong", "Hearts"};
|
||||
// PERIODS for each state (different for stateAutoChange or Manual mode)
|
||||
const uint16_t PERIODS[2][NUM_STATES] = {{PERIOD_TIME_VISU_UPDATE, // stateAutoChange = 0
|
||||
PERIOD_TIME_VISU_UPDATE,
|
||||
PERIOD_ANIMATION,
|
||||
PERIOD_TETRIS,
|
||||
PERIOD_SNAKE,
|
||||
PERIOD_PONG},
|
||||
PERIOD_PONG,
|
||||
PERIOD_ANIMATION},
|
||||
{PERIOD_TIME_VISU_UPDATE, // stateAutoChange = 1
|
||||
PERIOD_TIME_VISU_UPDATE,
|
||||
PERIOD_ANIMATION,
|
||||
PERIOD_ANIMATION,
|
||||
PERIOD_ANIMATION,
|
||||
PERIOD_PONG}};
|
||||
PERIOD_PONG,
|
||||
PERIOD_ANIMATION}};
|
||||
|
||||
// ----------------------------------------------------------------------------------
|
||||
// GLOBAL VARIABLES
|
||||
@@ -85,6 +87,7 @@ UDPLogger logger;
|
||||
|
||||
// Statics
|
||||
static bool spiral_direction = false;
|
||||
static unsigned long last_led_direct = 0; // time of last direct LED command (=> fall back to normal mode after timeout)
|
||||
|
||||
static WiFiUDP wifi_udp;
|
||||
static NTPClientPlus ntp_client = NTPClientPlus(wifi_udp, NTP_SERVER_URL, 1, true);
|
||||
@@ -92,16 +95,6 @@ static Pong pong = Pong(&led_matrix, &logger);
|
||||
static Snake snake = Snake(&led_matrix, &logger);
|
||||
static Tetris tetris = Tetris(&led_matrix, &logger);
|
||||
|
||||
// Timestamp variables
|
||||
static unsigned long button_press_start = 0; // time of push button press start
|
||||
static unsigned long last_led_direct = 0; // time of last direct LED command (=> fall back to normal mode after timeout)
|
||||
static unsigned long last_animation_step = millis(); // time of last Matrix update
|
||||
static unsigned long last_heartbeat = millis(); // time of last heartbeat sending
|
||||
static unsigned long last_nightmode_check = millis(); // time of last nightmode check
|
||||
static unsigned long last_ntp_update = millis() - PERIOD_NTP_UPDATE - 5000; // time of last NTP update
|
||||
static unsigned long last_state_change = millis(); // time of last state change
|
||||
static unsigned long last_step = millis(); // time of last animation step
|
||||
|
||||
static bool night_mode = false; // stores state of nightmode
|
||||
static bool state_auto_change = false; // stores state of automatic state change
|
||||
static float filter_factor = DEFAULT_SMOOTHING_FACTOR; // stores smoothing factor for led transition
|
||||
@@ -120,7 +113,6 @@ NightModeTimes_st night_mode_times = {
|
||||
// ----------------------------------------------------------------------------------
|
||||
// SETUP
|
||||
// ----------------------------------------------------------------------------------
|
||||
|
||||
void setup()
|
||||
{
|
||||
// put your setup code here, to run once:
|
||||
@@ -196,12 +188,12 @@ void setup()
|
||||
if (resetInfo->reason != REASON_SOFT_RESTART)
|
||||
{
|
||||
// test quickly each LED
|
||||
for (int r = 0; r < MATRIX_HEIGHT; r++)
|
||||
for (int16_t row = 0; row < MATRIX_HEIGHT; row++)
|
||||
{
|
||||
for (int c = 0; c < MATRIX_WIDTH; c++)
|
||||
for (int16_t col = 0; col < MATRIX_WIDTH; col++)
|
||||
{
|
||||
matrix.fillScreen(0);
|
||||
matrix.drawPixel(c, r, LEDMatrix::color_24_to_16bit(colors_24bit[2]));
|
||||
matrix.drawPixel(col, row, LEDMatrix::color_24_to_16bit(colors_24bit[2]));
|
||||
matrix.show();
|
||||
delay(10);
|
||||
}
|
||||
@@ -270,6 +262,7 @@ void setup()
|
||||
{
|
||||
night_mode_times.nightmode_end_min = NIGHTMODE_END_MIN;
|
||||
}
|
||||
|
||||
logger.log_string("Nightmode starts at: " + String(night_mode_times.nightmode_start_hour) + ":" + String(night_mode_times.nightmode_start_min));
|
||||
logger.log_string("Nightmode ends at: " + String(night_mode_times.nightmode_end_hour) + ":" + String(night_mode_times.nightmode_end_min));
|
||||
|
||||
@@ -286,35 +279,79 @@ void setup()
|
||||
// ----------------------------------------------------------------------------------
|
||||
// LOOP
|
||||
// ----------------------------------------------------------------------------------
|
||||
|
||||
void loop()
|
||||
{
|
||||
unsigned long current_time_ms = CURRENT_TIME_MS;
|
||||
|
||||
// Timestamp variables
|
||||
static unsigned long last_animation_step = 0; // time of last animation step
|
||||
static unsigned long last_matrix_update = 0; // time of last Matrix update
|
||||
static unsigned long last_heartbeat = 0; // time of last heartbeat sending
|
||||
static unsigned long last_nightmode_check = 0; // time of last nightmode check
|
||||
static unsigned long last_ntp_update = 0; // time of last NTP update
|
||||
static unsigned long last_state_change = 0; // time of last state change
|
||||
|
||||
handleOTA(); // handle OTA
|
||||
logger.log_string("After handleOTA");
|
||||
yield();
|
||||
|
||||
webserver.handleClient(); // handle webserver
|
||||
logger.log_string("After handleClient");
|
||||
yield();
|
||||
|
||||
send_heartbeat(); // send heartbeat update
|
||||
logger.log_string("After send_heartbeat");
|
||||
// send regularly heartbeat messages via UDP multicast
|
||||
if ((current_time_ms - last_heartbeat) > PERIOD_HEARTBEAT)
|
||||
{
|
||||
Serial.printf("a");
|
||||
Serial.println();
|
||||
send_heartbeat(); // send heartbeat update
|
||||
last_heartbeat = CURRENT_TIME_MS;
|
||||
yield();
|
||||
Serial.printf("A");
|
||||
}
|
||||
|
||||
handle_current_state(); // handle current state - main process
|
||||
logger.log_string("After handle_current_state");
|
||||
if (!night_mode && ((current_time_ms - last_animation_step) > PERIODS[state_auto_change][current_state]) && ((current_time_ms - last_led_direct) > TIMEOUT_LEDDIRECT))
|
||||
{
|
||||
Serial.printf("b");
|
||||
handle_current_state(); // handle current state
|
||||
last_animation_step = CURRENT_TIME_MS;
|
||||
yield();
|
||||
Serial.printf("B");
|
||||
}
|
||||
|
||||
update_matrix(); // update matrix
|
||||
logger.log_string("After update_matrix");
|
||||
if ((current_time_ms - last_matrix_update) > PERIOD_MATRIX_UPDATE)
|
||||
{
|
||||
Serial.printf("c");
|
||||
update_matrix(); // update matrix
|
||||
last_matrix_update = CURRENT_TIME_MS;
|
||||
yield();
|
||||
Serial.printf("C");
|
||||
}
|
||||
|
||||
handle_button(); // handle button press
|
||||
logger.log_string("After handle_button");
|
||||
|
||||
update_state_machine(); // handle state changes
|
||||
logger.log_string("After update_state_machine");
|
||||
if (!night_mode && state_auto_change && (current_time_ms - last_state_change > PERIOD_STATE_CHANGE))
|
||||
{
|
||||
Serial.printf("d");
|
||||
update_state_machine(); // handle state changes
|
||||
last_state_change = CURRENT_TIME_MS;
|
||||
yield();
|
||||
Serial.printf("D");
|
||||
}
|
||||
|
||||
ntp_time_update(); // ntp time update
|
||||
logger.log_string("After ntp_time_update");
|
||||
if ((current_time_ms - last_ntp_update) > PERIOD_NTP_UPDATE)
|
||||
{
|
||||
Serial.printf("e");
|
||||
ntp_time_update(&last_ntp_update); // ntp time update
|
||||
yield();
|
||||
Serial.printf("E");
|
||||
}
|
||||
|
||||
check_night_mode(); // check night mode
|
||||
logger.log_string("After check_night_mode");
|
||||
if ((current_time_ms - last_nightmode_check) > PERIOD_NIGHTMODE_CHECK)
|
||||
{
|
||||
Serial.printf("f");
|
||||
check_night_mode(); // check night mode
|
||||
last_nightmode_check = CURRENT_TIME_MS;
|
||||
Serial.printf("F");
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------
|
||||
@@ -323,101 +360,92 @@ void loop()
|
||||
|
||||
void update_state_machine()
|
||||
{
|
||||
unsigned long current_time_ms = millis();
|
||||
|
||||
if (state_auto_change && (current_time_ms - last_state_change > PERIOD_STATE_CHANGE) && !night_mode)
|
||||
{
|
||||
// increment state variable and trigger state change
|
||||
state_change((current_state + 1) % NUM_STATES);
|
||||
// save last automatic state change
|
||||
last_state_change = current_time_ms;
|
||||
}
|
||||
// increment state variable and trigger state change
|
||||
state_change((current_state + 1) % (uint8_t)NUM_STATES);
|
||||
}
|
||||
|
||||
void handle_current_state()
|
||||
{
|
||||
unsigned long current_time_ms = millis();
|
||||
|
||||
// handle mode behaviours (trigger loopCycles of different modes depending on current mode)
|
||||
if (!night_mode && ((current_time_ms - last_step) > PERIODS[state_auto_change][current_state]) && ((current_time_ms - last_led_direct) > TIMEOUT_LEDDIRECT))
|
||||
switch (current_state)
|
||||
{
|
||||
switch (current_state)
|
||||
{
|
||||
case ST_CLOCK: // state clock
|
||||
{
|
||||
int hours = ntp_client.getHours24();
|
||||
int minutes = ntp_client.getMinutes();
|
||||
case ST_CLOCK: // state clock
|
||||
{
|
||||
int hours = ntp_client.getHours24();
|
||||
int minutes = ntp_client.getMinutes();
|
||||
|
||||
(void)show_string_on_clock(time_to_string((uint8_t)hours, (uint8_t)minutes), main_color_clock);
|
||||
draw_minute_indicator((uint8_t)minutes, main_color_clock);
|
||||
break;
|
||||
}
|
||||
case ST_DICLOCK: // state diclock
|
||||
(void)show_string_on_clock(time_to_string((uint8_t)hours, (uint8_t)minutes), main_color_clock);
|
||||
draw_minute_indicator((uint8_t)minutes, main_color_clock);
|
||||
break;
|
||||
}
|
||||
case ST_DICLOCK: // state diclock
|
||||
{
|
||||
int hours = ntp_client.getHours24();
|
||||
int minutes = ntp_client.getMinutes();
|
||||
show_digital_clock((uint8_t)hours, (uint8_t)minutes, main_color_clock);
|
||||
break;
|
||||
}
|
||||
case ST_SPIRAL: // state spiral
|
||||
{
|
||||
int res = draw_spiral(false, spiral_direction, MATRIX_WIDTH - 6);
|
||||
if (res && spiral_direction == 0)
|
||||
{
|
||||
int hours = ntp_client.getHours24();
|
||||
int minutes = ntp_client.getMinutes();
|
||||
show_digital_clock((uint8_t)hours, (uint8_t)minutes, main_color_clock);
|
||||
break;
|
||||
// change spiral direction to closing (draw empty leds)
|
||||
spiral_direction = 1;
|
||||
// init spiral with new spiral direction
|
||||
draw_spiral(true, spiral_direction, MATRIX_WIDTH - 6);
|
||||
}
|
||||
case ST_SPIRAL: // state spiral
|
||||
else if (res && spiral_direction == 1)
|
||||
{
|
||||
int res = draw_spiral(false, spiral_direction, MATRIX_WIDTH - 6);
|
||||
if (res && spiral_direction == 0)
|
||||
{
|
||||
// change spiral direction to closing (draw empty leds)
|
||||
spiral_direction = 1;
|
||||
// init spiral with new spiral direction
|
||||
draw_spiral(true, spiral_direction, MATRIX_WIDTH - 6);
|
||||
}
|
||||
else if (res && spiral_direction == 1)
|
||||
{
|
||||
// reset spiral direction to normal drawing leds
|
||||
spiral_direction = 0;
|
||||
// init spiral with new spiral direction
|
||||
draw_spiral(true, spiral_direction, MATRIX_WIDTH - 6);
|
||||
}
|
||||
break;
|
||||
// reset spiral direction to normal drawing leds
|
||||
spiral_direction = 0;
|
||||
// init spiral with new spiral direction
|
||||
draw_spiral(true, spiral_direction, MATRIX_WIDTH - 6);
|
||||
}
|
||||
case ST_TETRIS: // state tetris
|
||||
break;
|
||||
}
|
||||
case ST_TETRIS: // state tetris
|
||||
{
|
||||
if (state_auto_change)
|
||||
{
|
||||
if (state_auto_change)
|
||||
{
|
||||
random_tetris(false);
|
||||
}
|
||||
else
|
||||
{
|
||||
tetris.loopCycle();
|
||||
}
|
||||
break;
|
||||
random_tetris(false);
|
||||
}
|
||||
case ST_SNAKE: // state snake
|
||||
else
|
||||
{
|
||||
if (state_auto_change)
|
||||
{
|
||||
led_matrix.flush();
|
||||
if (random_snake(false, 8, main_color_snake, -1))
|
||||
{
|
||||
// init snake for next run
|
||||
random_snake(true, 8, main_color_snake, -1);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
snake.loopCycle();
|
||||
}
|
||||
break;
|
||||
tetris.loopCycle();
|
||||
}
|
||||
case ST_PINGPONG: // state ping pong
|
||||
break;
|
||||
}
|
||||
case ST_SNAKE: // state snake
|
||||
{
|
||||
if (state_auto_change)
|
||||
{
|
||||
pong.loopCycle();
|
||||
break;
|
||||
led_matrix.flush();
|
||||
if (random_snake(false, 8, main_color_snake, -1))
|
||||
{
|
||||
// init snake for next run
|
||||
random_snake(true, 8, main_color_snake, -1);
|
||||
}
|
||||
}
|
||||
default:
|
||||
else
|
||||
{
|
||||
break;
|
||||
snake.loopCycle();
|
||||
}
|
||||
}
|
||||
last_step = millis();
|
||||
break;
|
||||
}
|
||||
case ST_PINGPONG: // state ping pong
|
||||
{
|
||||
pong.loopCycle();
|
||||
break;
|
||||
}
|
||||
case ST_HEARTS:
|
||||
{
|
||||
draw_heart_animation();
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -428,14 +456,8 @@ void handle_current_state()
|
||||
*/
|
||||
void update_matrix()
|
||||
{
|
||||
unsigned long current_time_ms = millis();
|
||||
|
||||
// periodically write colors to matrix
|
||||
if ((current_time_ms - last_animation_step) > PERIOD_MATRIX_UPDATE)
|
||||
{
|
||||
led_matrix.draw_on_matrix_smooth(filter_factor);
|
||||
last_animation_step = current_time_ms;
|
||||
}
|
||||
led_matrix.draw_on_matrix_smooth(filter_factor);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -445,25 +467,17 @@ void update_matrix()
|
||||
*/
|
||||
void send_heartbeat()
|
||||
{
|
||||
unsigned long current_time_ms = millis();
|
||||
|
||||
// send regularly heartbeat messages via UDP multicast
|
||||
if ((current_time_ms - last_heartbeat) > PERIOD_HEARTBEAT)
|
||||
logger.log_string("Heartbeat, state: " + state_names[current_state] + ", FreeHeap: " + ESP.getFreeHeap() +
|
||||
", HeapFrag: " + ESP.getHeapFragmentation() + ", MaxFreeBlock: " + ESP.getMaxFreeBlockSize() + "\nCounter: " +
|
||||
dbg_counter + " , Hours: " + (float)(dbg_counter) / 3600.0 + "\n"); // TODO CHANGE
|
||||
// Check wifi status
|
||||
if (WiFi.status() != WL_CONNECTED)
|
||||
{
|
||||
logger.log_string("Heartbeat, state: " + state_names[current_state] + ", FreeHeap: " + ESP.getFreeHeap() + \
|
||||
", HeapFrag: " + ESP.getHeapFragmentation() + ", MaxFreeBlock: " + ESP.getMaxFreeBlockSize() + "\nCounter: " + \
|
||||
dbg_counter + " , Hours: " + (float)(dbg_counter) / 3600.0 + "\n"); // TODO CHANGE
|
||||
last_heartbeat = current_time_ms;
|
||||
|
||||
// Check wifi status (only if no apmode)
|
||||
if (WiFi.status() != WL_CONNECTED)
|
||||
{
|
||||
Serial.println("WiFi connection lost!");
|
||||
led_matrix.grid_add_pixel(0, 5, colors_24bit[1]);
|
||||
led_matrix.draw_on_matrix_instant();
|
||||
}
|
||||
dbg_counter++; // TODO RM
|
||||
Serial.println("WiFi connection lost!");
|
||||
led_matrix.grid_add_pixel(0, 5, colors_24bit[1]);
|
||||
led_matrix.draw_on_matrix_instant();
|
||||
}
|
||||
dbg_counter++; // TODO RM
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -473,23 +487,17 @@ void send_heartbeat()
|
||||
*/
|
||||
void check_night_mode()
|
||||
{
|
||||
unsigned long current_time_ms = millis();
|
||||
|
||||
// check if nightmode need to be activated
|
||||
if ((current_time_ms - last_nightmode_check) > PERIOD_NIGHTMODE_CHECK)
|
||||
{
|
||||
int hours = ntp_client.getHours24();
|
||||
int minutes = ntp_client.getMinutes();
|
||||
int hours = ntp_client.getHours24();
|
||||
int minutes = ntp_client.getMinutes();
|
||||
|
||||
if (hours == night_mode_times.nightmode_start_hour && minutes == night_mode_times.nightmode_start_min)
|
||||
{
|
||||
set_night_mode(true);
|
||||
}
|
||||
else if (hours == night_mode_times.nightmode_end_hour && minutes == night_mode_times.nightmode_end_min)
|
||||
{
|
||||
set_night_mode(false);
|
||||
}
|
||||
last_nightmode_check = current_time_ms;
|
||||
if (hours == night_mode_times.nightmode_start_hour && minutes == night_mode_times.nightmode_start_min)
|
||||
{
|
||||
set_night_mode(true);
|
||||
}
|
||||
else if (hours == night_mode_times.nightmode_end_hour && minutes == night_mode_times.nightmode_end_min)
|
||||
{
|
||||
set_night_mode(false);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -498,63 +506,59 @@ void check_night_mode()
|
||||
*
|
||||
* @param None
|
||||
*/
|
||||
void ntp_time_update()
|
||||
void ntp_time_update(unsigned long *last_ntp_update)
|
||||
{
|
||||
unsigned long current_time_ms = millis();
|
||||
|
||||
// NTP time update
|
||||
if ((current_time_ms - last_ntp_update) > PERIOD_NTP_UPDATE)
|
||||
{
|
||||
int ntp_retval = ntp_client.updateNTP();
|
||||
switch (ntp_retval)
|
||||
{
|
||||
case NTP_UPDATE_SUCCESS:
|
||||
{
|
||||
ntp_client.calcDate();
|
||||
logger.log_string("NTP-Update successful");
|
||||
logger.log_string("Time: " + ntp_client.getFormattedTime());
|
||||
logger.log_string("Date: " + ntp_client.getFormattedDate());
|
||||
logger.log_string("TimeOffset (seconds): " + String(ntp_client.getTimeOffset()));
|
||||
logger.log_string("Summertime: " + String(ntp_client.updateSWChange()));
|
||||
last_ntp_update = millis();
|
||||
watchdog_counter = 30;
|
||||
break;
|
||||
}
|
||||
case NTP_UPDATE_TIMEOUT:
|
||||
{
|
||||
logger.log_string("NTP-Update not successful. Reason: Timeout");
|
||||
last_ntp_update += 10000;
|
||||
watchdog_counter--;
|
||||
break;
|
||||
}
|
||||
case NTP_UPDATE_DIFFTOOHIGH:
|
||||
{
|
||||
logger.log_string("NTP-Update not successful. Reason: Too large time difference");
|
||||
logger.log_string("Time: " + ntp_client.getFormattedTime());
|
||||
logger.log_string("Date: " + ntp_client.getFormattedDate());
|
||||
logger.log_string("TimeOffset (seconds): " + String(ntp_client.getTimeOffset()));
|
||||
logger.log_string("Summertime: " + String(ntp_client.updateSWChange()));
|
||||
last_ntp_update += 10000;
|
||||
watchdog_counter--;
|
||||
break;
|
||||
}
|
||||
case NTP_UPDATE_TIME_INVALID:
|
||||
default:
|
||||
{
|
||||
logger.log_string("NTP-Update not successful. Reason: NTP time not valid (<1970)");
|
||||
last_ntp_update += 10000;
|
||||
watchdog_counter--;
|
||||
break;
|
||||
}
|
||||
}
|
||||
int ntp_retval = ntp_client.updateNTP();
|
||||
|
||||
logger.log_string("Watchdog Counter: " + String(watchdog_counter));
|
||||
if (watchdog_counter <= 0)
|
||||
{
|
||||
logger.log_string("Trigger restart due to watchdog...");
|
||||
delay(100);
|
||||
ESP.restart();
|
||||
}
|
||||
switch (ntp_retval)
|
||||
{
|
||||
case NTP_UPDATE_SUCCESS:
|
||||
{
|
||||
ntp_client.calcDate();
|
||||
logger.log_string("NTP-Update successful");
|
||||
logger.log_string("Time: " + ntp_client.getFormattedTime());
|
||||
logger.log_string("Date: " + ntp_client.getFormattedDate());
|
||||
logger.log_string("TimeOffset (seconds): " + String(ntp_client.getTimeOffset()));
|
||||
logger.log_string("Summertime: " + String(ntp_client.updateSWChange()));
|
||||
*last_ntp_update = CURRENT_TIME_MS;
|
||||
watchdog_counter = 30;
|
||||
break;
|
||||
}
|
||||
case NTP_UPDATE_TIMEOUT:
|
||||
{
|
||||
logger.log_string("NTP-Update not successful. Reason: Timeout");
|
||||
*last_ntp_update += 10000;
|
||||
watchdog_counter--;
|
||||
break;
|
||||
}
|
||||
case NTP_UPDATE_DIFFTOOHIGH:
|
||||
{
|
||||
logger.log_string("NTP-Update not successful. Reason: Too large time difference");
|
||||
logger.log_string("Time: " + ntp_client.getFormattedTime());
|
||||
logger.log_string("Date: " + ntp_client.getFormattedDate());
|
||||
logger.log_string("TimeOffset (seconds): " + String(ntp_client.getTimeOffset()));
|
||||
logger.log_string("Summertime: " + String(ntp_client.updateSWChange()));
|
||||
*last_ntp_update += 10000;
|
||||
watchdog_counter--;
|
||||
break;
|
||||
}
|
||||
case NTP_UPDATE_TIME_INVALID:
|
||||
default:
|
||||
{
|
||||
logger.log_string("NTP-Update not successful. Reason: NTP time not valid (<1970)");
|
||||
*last_ntp_update += 10000;
|
||||
watchdog_counter--;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
logger.log_string("Watchdog Counter: " + String(watchdog_counter));
|
||||
if (watchdog_counter <= 0)
|
||||
{
|
||||
logger.log_string("Trigger restart due to watchdog...");
|
||||
delay(100);
|
||||
ESP.restart();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -631,10 +635,9 @@ void state_change(uint8_t newState)
|
||||
{
|
||||
set_night_mode(false); // deactivate Nightmode
|
||||
}
|
||||
// first clear matrix
|
||||
led_matrix.flush();
|
||||
// set new state
|
||||
current_state = newState;
|
||||
|
||||
led_matrix.flush(); // first clear matrix
|
||||
current_state = newState; // set new state
|
||||
on_state_entry(current_state);
|
||||
logger.log_string("State change to: " + state_names[current_state]);
|
||||
delay(5);
|
||||
@@ -680,7 +683,7 @@ void handle_led_direct()
|
||||
}
|
||||
led_matrix.draw_on_matrix_instant();
|
||||
|
||||
last_led_direct = millis();
|
||||
last_led_direct = CURRENT_TIME_MS;
|
||||
}
|
||||
webserver.send(200, "text/plain", message);
|
||||
}
|
||||
@@ -692,28 +695,28 @@ void handle_led_direct()
|
||||
*/
|
||||
void handle_button()
|
||||
{
|
||||
static bool lastButtonState = false;
|
||||
bool buttonPressed = !digitalRead(BUTTON_PIN);
|
||||
bool button_pressed = !digitalRead(BUTTON_PIN);
|
||||
static bool last_button_state = false;
|
||||
static unsigned long button_press_start = 0; // time of push button press start
|
||||
|
||||
// check rising edge
|
||||
if (buttonPressed == true && lastButtonState == false)
|
||||
if (button_pressed == true && last_button_state == false)
|
||||
{
|
||||
// button press start
|
||||
logger.log_string("Button press started");
|
||||
button_press_start = millis();
|
||||
button_press_start = CURRENT_TIME_MS;
|
||||
}
|
||||
// check falling edge
|
||||
if (buttonPressed == false && lastButtonState == true)
|
||||
if (button_pressed == false && last_button_state == true)
|
||||
{
|
||||
// button press ended
|
||||
if ((millis() - button_press_start) > LONG_PRESS_MS)
|
||||
if ((CURRENT_TIME_MS - button_press_start) > LONG_PRESS_MS)
|
||||
{
|
||||
// longpress -> nightmode
|
||||
logger.log_string("Button press ended - long press");
|
||||
|
||||
set_night_mode(true);
|
||||
}
|
||||
else if ((millis() - button_press_start) > SHORT_PRESS_MS)
|
||||
else if ((CURRENT_TIME_MS - button_press_start) > SHORT_PRESS_MS)
|
||||
{
|
||||
// shortpress -> state change
|
||||
logger.log_string("Button press ended - short press");
|
||||
@@ -724,11 +727,11 @@ void handle_button()
|
||||
}
|
||||
else
|
||||
{
|
||||
state_change((current_state + 1) % NUM_STATES);
|
||||
state_change((current_state + 1) % (uint8_t)NUM_STATES);
|
||||
}
|
||||
}
|
||||
}
|
||||
lastButtonState = buttonPressed;
|
||||
last_button_state = button_pressed;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -755,7 +758,8 @@ void load_main_color()
|
||||
uint8_t red = EEPROM.read(ADR_MC_RED);
|
||||
uint8_t green = EEPROM.read(ADR_MC_GREEN);
|
||||
uint8_t blue = EEPROM.read(ADR_MC_BLUE);
|
||||
if (int(red) + int(green) + int(blue) < 50)
|
||||
|
||||
if ((int(red) + int(green) + int(blue)) < 50)
|
||||
{
|
||||
main_color_clock = colors_24bit[2];
|
||||
}
|
||||
@@ -821,6 +825,10 @@ void handle_command()
|
||||
{
|
||||
state_change(ST_PINGPONG);
|
||||
}
|
||||
else if (mode_str.equals("hearts"))
|
||||
{
|
||||
state_change(ST_HEARTS);
|
||||
}
|
||||
}
|
||||
else if (webserver.argName(0).equals("nightmode"))
|
||||
{
|
||||
@@ -946,6 +954,7 @@ void handle_command()
|
||||
pong.initGame(1);
|
||||
}
|
||||
}
|
||||
|
||||
webserver.send(204, "text/plain", "No Content"); // this page doesn't send back content --> 204
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user