This commit is contained in:
2023-08-21 20:26:38 +02:00
commit 9a4a8c2a7d
33 changed files with 5782 additions and 0 deletions

View File

@@ -0,0 +1,20 @@
#ifndef ANIMATIONFUNCTIONS_H
#define ANIMATIONFUNCTIONS_H
#include <Arduino.h>
enum Direction
{
RIGHT,
LEFT,
UP,
DOWN
};
Direction next_direction(Direction dir, int d);
int random_snake(bool init, const uint8_t len, const uint32_t color, int numSteps);
int random_tetris(bool init);
int draw_spiral(bool init, bool empty, uint8_t size);
void show_digital_clock(uint8_t hours, uint8_t minutes, uint32_t color);
#endif /* ANIMATIONFUNCTIONS_H */

26
include/base64_wrapper.h Normal file
View File

@@ -0,0 +1,26 @@
/*
Copyright (C) 2016 Arturo Guadalupi. All right reserved.
This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
*/
#ifndef BASE64_WRAPPER_H
#define BASE64_WRAPPER_H
class Base64Class{
public:
int encode(char *output, char *input, int inputLength);
int decode(char * output, char * input, int inputLength);
int encodedLength(int plainLength);
int decodedLength(char * input, int inputLength);
private:
inline void fromA3ToA4(unsigned char * A4, unsigned char * A3);
inline void fromA4ToA3(unsigned char * A3, unsigned char * A4);
inline unsigned char lookupTable(char c);
};
extern Base64Class Base64;
#endif /* BASE64_WRAPPER_H */

56
include/ledmatrix.h Normal file
View File

@@ -0,0 +1,56 @@
#ifndef LEDMATRIX_H
#define LEDMATRIX_H
#include <Arduino.h>
#include <Adafruit_GFX.h>
#include <Adafruit_NeoMatrix.h>
#include "wordclock_constants.h"
#include "udp_logger.h"
#define DEFAULT_CURRENT_LIMIT 9999
extern const uint32_t colors_24bit[NUM_COLORS];
class LEDMatrix
{
public:
LEDMatrix(Adafruit_NeoMatrix * matrix, uint8_t brightness, UDPLogger * logger);
static uint16_t color_24_to_16bit(uint32_t color24bit);
static uint32_t color_24bit(uint8_t r, uint8_t g, uint8_t b);
static uint32_t interpolate_color_24bit(uint32_t color1, uint32_t color2, float factor);
static uint32_t wheel(uint8_t WheelPos);
void draw_on_matrix_instant();
void draw_on_matrix_smooth(float factor);
void flush(void);
void grid_add_pixel(uint8_t x, uint8_t y, uint32_t color);
void print_char(uint8_t xpos, uint8_t ypos, char character, uint32_t color);
void print_number(uint8_t xpos, uint8_t ypos, uint8_t number, uint32_t color);
void set_brightness(uint8_t mybrightness);
void set_current_limit(uint16_t new_current_limit);
void set_min_indicator(uint8_t pattern, uint32_t color);
void setup_matrix();
private:
Adafruit_NeoMatrix * _neomatrix;
UDPLogger * _logger;
uint8_t _brightness;
uint16_t _current_limit;
// target representation of matrix as 2D array
uint32_t _target_grid[MATRIX_HEIGHT][MATRIX_WIDTH] = {0};
// current representation of matrix as 2D array
uint32_t _current_grid[MATRIX_HEIGHT][MATRIX_WIDTH] = {0};
// target representation of minutes indicator leds
uint32_t _target_indicators[4] = {0, 0, 0, 0};
// current representation of minutes indicator leds
uint32_t _current_indicators[4] = {0, 0, 0, 0};
void _draw_on_matrix(float factor);
uint16_t _calc_estimated_led_current(uint32_t color);
};
#endif /* LEDMATRIX_H */

View File

@@ -0,0 +1,15 @@
#ifndef LITTLEFS_WRAPPER_H
#define LITTLEFS_WRAPPER_H
#include <Arduino.h>
bool handle_file(String &&path);
bool handle_list();
const String format_bytes(size_t const &bytes);
void delete_recursive(const String &path);
void format_filesystem();
void handle_upload();
void send_response();
void setup_filesystem();
#endif /* LITTLEFS_WRAPPER_H */

90
include/ntp_client_plus.h Normal file
View File

@@ -0,0 +1,90 @@
#ifndef NTPCLIENTPLUS_H
#define NTPCLIENTPLUS_H
#include <Arduino.h>
#include <WiFiUdp.h>
#define UNIX_TIMESTAMP_1900 2208988800UL // careful: positive value
#define NTP_PACKET_SIZE 48
#define NTP_DEFAULT_LOCAL_PORT 1337
#define MAX_NTP_CONN_TRIES 50 // 50 * NTP_RECEIVE_WAIT_TIME_MS => 500ms
#define NTP_RECEIVE_WAIT_TIME_MS 10 // 10ms
typedef enum
{
NTP_UPDATE_TIMEOUT = -1,
NTP_UPDATE_SUCCESS = 0,
NTP_UPDATE_DIFFTOOHIGH = 1,
NTP_UPDATE_TIME_INVALID = 2
} ntp_return_values;
/**
* @brief Own NTP Client library for Arduino with code from:
* - https://github.com/arduino-libraries/NTPClient
* - SPS&Technik - Projekt WordClock v1.02
*
*/
class NTPClientPlus
{
public:
NTPClientPlus(UDP &udp, const char *poolServerName, int utcx, bool _swChange);
void setupNTPClient();
int updateNTP();
void end();
void setTimeOffset(int timeOffset);
void setPoolServerName(const char *poolServerName);
unsigned long getSecsSince1900() const;
unsigned long getEpochTime() const;
int getHours24() const;
int getHours12() const;
int getMinutes() const;
int getSeconds() const;
String getFormattedTime() const;
String getFormattedDate();
void calcDate();
unsigned int getDayOfWeek();
unsigned int getYear();
bool isLeapYear(unsigned int year);
int getMonth(int dayOfYear);
long getTimeOffset();
bool updateSWChange();
private:
UDP *_udp;
bool _udpSetup = false;
bool _swChange = 1;
const char *_poolServerName = "pool.ntp.org"; // Default time server
int _utcx = 0;
IPAddress _poolServerIP;
long _timeOffset = 0;
unsigned int _port = NTP_DEFAULT_LOCAL_PORT;
unsigned long _updateInterval = 60000; // In ms
unsigned long _currentEpoc = 0; // In s
unsigned long _lastUpdate = 0; // In ms
unsigned long _secsSince1900 = 0; // seconds since 1. Januar 1900, 00:00:00
unsigned long _lastSecsSince1900 = 0;
unsigned int _dateYear = 0;
unsigned int _dateMonth = 0;
unsigned int _dateDay = 0;
unsigned int _dayOfWeek = 0;
unsigned char _packetBuffer[NTP_PACKET_SIZE] = {0};
void sendNTPPacket();
void setSummertime(bool summertime);
static const unsigned long secondperday = 86400;
static const unsigned long secondperhour = 3600;
static const unsigned long secondperminute = 60;
static const unsigned long minuteperhour = 60;
static const unsigned long millisecondpersecond = 1000;
// number of days in months
unsigned int daysInMonth[13] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
};
void wait(unsigned long time);
#endif /* NTPCLIENTPLUS_H */

9
include/otafunctions.h Normal file
View File

@@ -0,0 +1,9 @@
#ifndef OTAFUNCTIONS_H
#define OTAFUNCTIONS_H
#include <Arduino.h>
void handleOTA();
void setupOTA(String hostname);
#endif /* OTAFUNCTIONS_H */

66
include/own_font.h Normal file
View File

@@ -0,0 +1,66 @@
#ifndef OWNFONT_H
#define OWNFONT_H
uint8_t numbers_font[10][5] = { {0b00000111,
0b00000101,
0b00000101,
0b00000101,
0b00000111},
{0b00000001,
0b00000001,
0b00000001,
0b00000001,
0b00000001},
{0b00000111,
0b00000001,
0b00000111,
0b00000100,
0b00000111},
{0b00000111,
0b00000001,
0b00000111,
0b00000001,
0b00000111},
{0b00000101,
0b00000101,
0b00000111,
0b00000001,
0b00000001},
{0b00000111,
0b00000100,
0b00000111,
0b00000001,
0b00000111},
{0b00000111,
0b00000100,
0b00000111,
0b00000101,
0b00000111},
{0b00000111,
0b00000001,
0b00000001,
0b00000001,
0b00000001},
{0b00000111,
0b00000101,
0b00000111,
0b00000101,
0b00000111},
{0b00000111,
0b00000101,
0b00000111,
0b00000001,
0b00000111}};
uint8_t chars_font[2][5] = { {0b00000010,
0b00000010,
0b00000010,
0b00000010,
0b00000010},
{0b00000111,
0b00000101,
0b00000111,
0b00000100,
0b00000100}};
#endif /* OWNFONT_H */

100
include/pong.h Normal file
View File

@@ -0,0 +1,100 @@
/**
* @file pong.h
* @author techniccontroller (mail[at]techniccontroller.com)
* @brief Class declaration for pong game
* @version 0.1
* @date 2022-03-05
*
* @copyright Copyright (c) 2022
*
* main code from https://elektro.turanis.de/html/prj041/index.html
*
*/
#ifndef PONG_H
#define PONG_H
#include <Arduino.h>
#include "ledmatrix.h"
#include "udp_logger.h"
#ifdef DEBOUNCE_TIME
#undef DEBOUNCE_TIME
#endif
#define DEBOUNCE_TIME 10 // in ms
#define X_MAX 11
#define Y_MAX 11
#ifdef GAME_DELAY
#undef GAME_DELAY
#endif
#define GAME_DELAY 80 // in ms
#define BALL_DELAY_MAX 350 // in ms
#define BALL_DELAY_MIN 50 // in ms
#define BALL_DELAY_STEP 5 // in ms
#define PLAYER_AMOUNT 2
#define PLAYER_1 0
#define PLAYER_2 1
#define PADDLE_WIDTH 3
#define PADDLE_MOVE_NONE 0
#define PADDLE_MOVE_UP 1
#define PADDLE_MOVE_DOWN 2
#ifdef LED_TYPE_OFF
#undef LED_TYPE_OFF
#endif
#define LED_TYPE_OFF 1
#define LED_TYPE_PADDLE 2
#define LED_TYPE_BALL 3
#define LED_TYPE_BALL_RED 4
#define GAME_STATE_RUNNING 1
#define GAME_STATE_END 2
#define GAME_STATE_INIT 3
class Pong
{
struct Coords
{
uint8_t x;
uint8_t y;
};
public:
Pong();
Pong(LEDMatrix * matrix, UDPLogger * logger);
void loopCycle();
void initGame(uint8_t numBots);
void ctrlUp(uint8_t playerid);
void ctrlDown(uint8_t playerid);
void ctrlNone(uint8_t playerid);
private:
LEDMatrix *_ledmatrix;
UDPLogger *_logger;
uint8_t _gameState = 0;
uint8_t _numBots = 0;
uint8_t _playerMovement[PLAYER_AMOUNT] = {0};
Coords _paddles[PLAYER_AMOUNT][PADDLE_WIDTH] = {0};
Coords _ball = {0, 0};
Coords _ball_old = {0, 0};
int _ballMovement[2] = {0, 0};
unsigned int _ballDelay = 0;
unsigned long _lastDrawUpdate = 0;
unsigned long _lastBallUpdate = 0;
unsigned long _lastButtonClick = 0;
void updateBall();
void endGame();
void updateGame();
uint8_t getPlayerMovement(uint8_t playerId);
void resetLEDs();
void toggleLed(uint8_t x, uint8_t y, uint8_t type);
};
#endif /* PONG_H */

94
include/snake.h Normal file
View File

@@ -0,0 +1,94 @@
/**
* @file snake.h
* @author techniccontroller (mail[at]techniccontroller.com)
* @brief Class declaration of snake game
* @version 0.1
* @date 2022-03-05
*
* @copyright Copyright (c) 2022
*
* main code from https://elektro.turanis.de/html/prj099/index.html
*
*/
#ifndef snake_h
#define snake_h
#include <Arduino.h>
#include "ledmatrix.h"
#include "udp_logger.h"
#ifdef DEBOUNCE_TIME
#undef DEBOUNCE_TIME
#endif
#define DEBOUNCE_TIME 300 // in ms
#define X_MAX 11
#define Y_MAX 11
#ifdef GAME_DELAY
#undef GAME_DELAY
#endif
#define GAME_DELAY 400 // in ms
#define LED_TYPE_SNAKE 1
#ifdef LED_TYPE_OFF
#undef LED_TYPE_OFF
#endif
#define LED_TYPE_OFF 2
#define LED_TYPE_FOOD 3
#define LED_TYPE_BLOOD 4
#define DIRECTION_NONE 0
#define DIRECTION_UP 1
#define DIRECTION_DOWN 2
#define DIRECTION_LEFT 3
#define DIRECTION_RIGHT 4
#define GAME_STATE_RUNNING 1
#define GAME_STATE_END 2
#define GAME_STATE_INIT 3
#define MAX_TAIL_LENGTH (X_MAX * Y_MAX)
#define MIN_TAIL_LENGTH 3
class Snake
{
struct Coords
{
int x;
int y;
};
public:
Snake();
Snake(LEDMatrix * matrix, UDPLogger * logger);
void loopCycle();
void initGame();
void ctrlUp();
void ctrlDown();
void ctrlLeft();
void ctrlRight();
private:
LEDMatrix * _ledmatrix;
UDPLogger * _logger;
uint8_t _userDirection = 0;
uint8_t _gameState = 0;
Coords _head = {0, 0};
Coords _tail[MAX_TAIL_LENGTH] = {0};
Coords _food = {0, 0};
unsigned long _lastDrawUpdate = 0;
unsigned long _lastButtonClick = 0;
unsigned int _wormLength = 0;
void resetLEDs();
void updateGame();
void endGame();
void updateTail();
void updateFood();
bool isCollision();
void toggleLed(uint8_t x, uint8_t y, uint8_t type);
};
#endif

199
include/tetris.h Normal file
View File

@@ -0,0 +1,199 @@
/**
* @file tetris.h
* @author techniccontroller (mail[at]techniccontroller.com)
* @brief Class definition for tetris game
* @version 0.1
* @date 2022-03-05
*
* @copyright Copyright (c) 2022
*
* main tetris code originally written by Klaas De Craemer, Ing. David Hrbaty
*
*/
#ifndef TETRIS_H
#define TETRIS_H
#include <Arduino.h>
#include "ledmatrix.h"
#include "udp_logger.h"
#ifdef DEBOUNCE_TIME
#undef DEBOUNCE_TIME
#endif
#define DEBOUNCE_TIME 100
#define RED_END_TIME 1500
#define GAME_STATE_RUNNING 1
#define GAME_STATE_END 2
#define GAME_STATE_INIT 3
#define GAME_STATE_PAUSED 4
#define GAME_STATE_READY 5
// common
#define DIR_UP 1
#define DIR_DOWN 2
#define DIR_LEFT 3
#define DIR_RIGHT 4
// Maximum size of bricks. Individual bricks can still be smaller (eg 3x3)
#define GREEN 0x008000
#define RED 0xFF0000
#define BLUE 0x0000FF
#define YELLOW 0xFFFF00
#define CHOCOLATE 0xD2691E
#define PURPLE 0xFF00FF
#define WHITE 0XFFFFFF
#define AQUA 0x00FFFF
#define HOTPINK 0xFF1493
#define DARKORANGE 0xFF8C00
#define MAX_BRICK_SIZE 4
#define BRICKOFFSET -1 // Y offset for new bricks
#define INIT_SPEED 800 // Initial delay in ms between brick drops
#define SPEED_STEP 10 // Factor for speed increase between levels, default 10
#define LEVELUP 4 // Number of rows before levelup, default 5
#define WIDTH 11
#define HEIGHT 11
class Tetris
{
// Playing field
struct Field
{
uint8_t pix[MATRIX_WIDTH][MATRIX_HEIGHT + 1]; // Make field one larger so that collision detection with bottom of field can be done in a uniform way
uint32_t color[MATRIX_WIDTH][MATRIX_HEIGHT];
};
// Structure to represent active brick on screen
struct Brick
{
boolean enabled; // Brick is disabled when it has landed
int xpos, ypos;
int yOffset; // Y-offset to use when placing brick at top of field
uint8_t siz;
uint8_t pix[MAX_BRICK_SIZE][MAX_BRICK_SIZE];
uint32_t col;
};
// Struct to contain the different choices of blocks
struct AbstractBrick
{
int yOffset; // Y-offset to use when placing brick at top of field
uint8_t siz;
uint8_t pix[MAX_BRICK_SIZE][MAX_BRICK_SIZE];
uint32_t col;
};
public:
Tetris();
Tetris(LEDMatrix *myledmatrix, UDPLogger *mylogger);
void ctrlStart();
void ctrlPlayPause();
void ctrlRight();
void ctrlLeft();
void ctrlUp();
void ctrlDown();
void setSpeed(int32_t i);
void loopCycle();
private:
void resetLEDs();
void tetrisInit();
void printField();
/* *** Game functions *** */
void newActiveBrick();
boolean checkFieldCollision(struct Brick *brick);
boolean checkSidesCollision(struct Brick *brick);
void rotateActiveBrick();
void shiftActiveBrick(int dir);
void addActiveBrickToField();
void moveFieldDownOne(uint8_t startRow);
void checkFullLines();
void clearField();
void everythingRed();
void showscore();
LEDMatrix *_ledmatrix;
UDPLogger *_logger;
Brick _activeBrick = {0};
Field _field;
bool _allowdrop = false;
bool _tetrisGameOver = false;
int _gameStatet = GAME_STATE_INIT;
int _score = 0;
unsigned int _speedtetris = 80;
unsigned long _brickSpeed = 0;
unsigned long _droptime = 0;
unsigned long _lastButtonClick = 0;
unsigned long _lastButtonClickr = 0;
unsigned long _nbRowsThisLevel = 0;
unsigned long _nbRowsTotal = 0;
unsigned long _prevUpdateTime = 0;
unsigned long _tetrisshowscore = 0;
// color library
uint32_t _colorLib[10] = {RED, GREEN, BLUE, YELLOW, CHOCOLATE, PURPLE, WHITE, AQUA, HOTPINK, DARKORANGE};
// Brick "library"
AbstractBrick _brickLib[7] = {
{1, // yoffset when adding brick to field
4,
{{0, 0, 0, 0},
{0, 1, 1, 0},
{0, 1, 1, 0},
{0, 0, 0, 0}},
WHITE},
{0,
4,
{{0, 1, 0, 0},
{0, 1, 0, 0},
{0, 1, 0, 0},
{0, 1, 0, 0}},
GREEN},
{1,
3,
{{0, 0, 0, 0},
{1, 1, 1, 0},
{0, 0, 1, 0},
{0, 0, 0, 0}},
BLUE},
{1,
3,
{{0, 0, 1, 0},
{1, 1, 1, 0},
{0, 0, 0, 0},
{0, 0, 0, 0}},
YELLOW},
{1,
3,
{{0, 0, 0, 0},
{1, 1, 1, 0},
{0, 1, 0, 0},
{0, 0, 0, 0}},
AQUA},
{1,
3,
{{0, 1, 1, 0},
{1, 1, 0, 0},
{0, 0, 0, 0},
{0, 0, 0, 0}},
HOTPINK},
{1,
3,
{{1, 1, 0, 0},
{0, 1, 1, 0},
{0, 0, 0, 0},
{0, 0, 0, 0}},
RED}};
};
#endif /* TETRIS_H */

37
include/udp_logger.h Normal file
View File

@@ -0,0 +1,37 @@
/**
* @file udp_logger.h
* @author techniccontroller (mail[at]techniccontroller.com)
* @brief Class for sending logging Strings as multicast messages
* @version 0.1
* @date 2022-03-21
*
* @copyright Copyright (c) 2022
*
*/
#ifndef UDP_LOGGER_H
#define UDP_LOGGER_H
#include <Arduino.h>
#include <WiFiUdp.h>
class UDPLogger
{
public:
UDPLogger();
UDPLogger(IPAddress interface_addr, IPAddress multicast_addr, int port, String name);
void set_name(String name);
void log_string(String message);
void log_color_24bit(uint32_t color);
private:
char _packetBuffer[100] = {0};
int _port;
IPAddress _interfaceAddr;
IPAddress _multicastAddr;
String _name = "Logger";
unsigned long _lastSend = 0;
WiFiUDP _udp;
};
#endif /* UDP_LOGGER_H */

View File

@@ -0,0 +1,71 @@
#ifndef WORDCLOCK_CONSTANTS_H
#define WORDCLOCK_CONSTANTS_H
#include <Arduino.h>
// ----------------------------------------------------------------------------------
// CONSTANTS
// ----------------------------------------------------------------------------------
#define AP_SSID "WordclockAP" // SSID name of Access Point
#define NTP_SERVER_URL "de.pool.ntp.org" // NTP server address
#define HOSTNAME (String("wordclock")) // Local hostname
#define LOGGER_MULTICAST_IP (IPAddress(230, 120, 10, 2)) // IP for UDP server
#define LOGGER_MULTICAST_PORT 8123 // Port for UDP server
#define HTTP_PORT 80 // Standard HTTP port
// EEPROM layout
typedef enum
{
ADR_NM_START_H = 0,
ADR_NM_END_H = 4,
ADR_NM_START_M = 8,
ADR_NM_END_M = 12,
ADR_BRIGHTNESS = 16,
ADR_MC_RED = 20,
ADR_MC_GREEN = 22,
ADR_MC_BLUE = 24,
EEPROM_SIZE = 30
} EepromLayout_en;
#define NEOPIXEL_PIN 5 // pin to which the NeoPixels are attached
#define BUTTON_PIN 14 // pin to which the button is attached
// Night mode
#define NIGHTMODE_START_HR 23
#define NIGHTMODE_START_MIN 0
#define NIGHTMODE_END_HR 7
#define NIGHTMODE_END_MIN 0
// Timings
#define PERIOD_ANIMATION 200
#define PERIOD_HEARTBEAT 1000
#define PERIOD_MATRIX_UPDATE 100
#define PERIOD_NIGHTMODE_CHECK 20000
#define PERIOD_NTP_UPDATE 30000
#define PERIOD_PONG 10
#define PERIOD_SNAKE 50
#define PERIOD_STATE_CHANGE 10000
#define PERIOD_TETRIS 50
#define PERIOD_TIME_VISU_UPDATE 1000
#define TIMEOUT_LEDDIRECT 5000
#define SHORT_PRESS_MS 100
#define LONG_PRESS_MS 2000
// Current limit
#define CURRENT_LIMIT_LED 2500 // limit the total current consumed by LEDs (mA)
// LED smoothing
#define DEFAULT_SMOOTHING_FACTOR 0.5
// Number of colors in colors array
#define NUM_COLORS 7
// LED matrix size
#define MATRIX_WIDTH 11
#define MATRIX_HEIGHT 11
// State machine states count
#define NUM_STATES 6
#endif /* WORDCLOCK_CONSTANTS_H */

View File

@@ -0,0 +1,51 @@
#ifndef WORDCLOCK_ESP8266_H
#define WORDCLOCK_ESP8266_H
#include <Arduino.h>
#include <ESP8266WebServer.h>
#include "ledmatrix.h"
#include "udp_logger.h"
extern UDPLogger logger;
extern LEDMatrix led_matrix;
extern ESP8266WebServer webserver;
typedef struct
{
int nightmode_start_hour;
int nightmode_start_min;
int nightmode_end_hour;
int nightmode_end_min;
} NightModeTimes_st;
typedef enum
{
ST_CLOCK,
ST_DICLOCK,
ST_SPIRAL,
ST_TETRIS,
ST_SNAKE,
ST_PINGPONG
} clock_state_en;
int EEPROM_read_address(int address);
String leading_zero2digit(int value);
String split(String s, char parser, int index);
void check_night_mode(void);
void EEPROM_write_to_address(int address, int value);
void handle_button(void);
void handle_command(void);
void handle_current_state(void);
void handle_data_request(void);
void handle_led_direct(void);
void load_main_color(void);
void ntp_time_update(void);
void on_state_entry(uint8_t state);
void send_heartbeat(void);
void set_main_color(uint8_t red, uint8_t green, uint8_t blue);
void set_night_mode(bool on);
void state_change(uint8_t newState);
void update_matrix(void);
void update_state_machine(void);
#endif /* WORDCLOCK_ESP8266_H */

View File

@@ -0,0 +1,10 @@
#ifndef WORDCLOCK_FUNCTIONS_H
#define WORDCLOCK_FUNCTIONS_H
#include <Arduino.h>
int show_string_on_clock(String message, uint32_t color);
String time_to_string(uint8_t hours, uint8_t minutes);
void draw_minute_indicator(uint8_t minutes, uint32_t color);
#endif /* WORDCLOCK_FUNCTIONS_H */