Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Get the ESP8266 version to work #13

Open
wants to merge 26 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
c703567
remove unused code
Wene Aug 30, 2021
715deef
use static variable for value only used internally
Wene Aug 30, 2021
1d1b502
patch to get prevent esp8266 from crashing
Wene Aug 30, 2021
2c6ab64
move settings into separate file
Wene Sep 4, 2021
bdabed9
add some debugging output while wifi is connecting
Wene Sep 4, 2021
fc636e0
move strings to flash
Wene Sep 4, 2021
5ff6f6f
remove connecting output - isn't visible anyway since virtually no ti…
Wene Sep 4, 2021
82b8fd2
remove timers - I suspect them to cause the crash on ESP8266
Wene Sep 4, 2021
165ae93
simplify timing
Wene Sep 4, 2021
6202176
use static for variables used only in one function
Wene Sep 4, 2021
2efa250
move animation timing handling into an own function
Wene Sep 4, 2021
5e677b6
remove unused function
Wene Sep 4, 2021
35230ae
use function pointer to differentiate between active animation type
Wene Sep 4, 2021
8b85509
try to prevent overflow within calculation
Wene Sep 5, 2021
2a09780
integrate animation functions
Wene Sep 5, 2021
72c9f0f
some cleanup
Wene Sep 5, 2021
467b77a
remove more global variables and (hopefully) continue blinking colon
Wene Sep 5, 2021
ab9ea84
restore original timing
Wene Sep 5, 2021
7ac1a10
move time setting function call since the timing is equal now
Wene Sep 5, 2021
f69fd5c
add debugging output
Wene Sep 5, 2021
1143de8
wait 20 seconds instead of the end of the animation
Wene Sep 5, 2021
76ecc63
slower colon blinking
Wene Sep 5, 2021
f7f1056
move animate functionality into loop and animation transition into th…
Wene Sep 5, 2021
5e21b4f
reduce flicker when nothing changes
Wene Sep 19, 2021
6e67d9b
fix messed up intro
Wene Sep 19, 2021
6b589bc
Merge branch 'develop'
Wene Sep 19, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
304 changes: 143 additions & 161 deletions ESP8266/EzTimeTetrisClockESP8266/EzTimeTetrisClockESP8266.ino
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
/*******************************************************************
Tetris clock that fetches its time Using the EzTimeLibrary

NOTE: THIS IS CURRENTLY CRASHING!

For use with an ESP8266
* *

Written by Brian Lough
YouTube: https://www.youtube.com/brianlough
Tindie: https://www.tindie.com/stores/brianlough/
Expand All @@ -15,7 +13,6 @@
// Standard Libraries - Already Installed if you have ESP32 set up
// ----------------------------

#include <Ticker.h>
#include <ESP8266WiFi.h>

// ----------------------------
Expand Down Expand Up @@ -43,23 +40,9 @@

// ---- Stuff to configure ----

// Initialize Wifi connection to the router
char ssid[] = "SSID"; // your network SSID (name)
char password[] = "password"; // your network key

// Set a timezone using the following list
// https://en.wikipedia.org/wiki/List_of_tz_database_time_zones
#define MYTIMEZONE "Europe/Dublin"

// Sets whether the clock should be 12 hour format or not.
bool twelveHourFormat = true;
// moved into settings.h for version control reasons
#include "settings.h"

// If this is set to false, the number will only change if the value behind it changes
// e.g. the digit representing the least significant minute will be replaced every minute,
// but the most significant number will only be replaced every 10 minutes.
// When true, all digits will be replaced every minute.
bool forceRefresh = true;
// -----------------------------

// ----- Wiring -------
#define P_LAT 16
Expand All @@ -71,9 +54,6 @@ bool forceRefresh = true;
#define P_E 0
// ---------------------

Ticker display_ticker;
Ticker timer_ticker;

// PxMATRIX display(32,16,P_LAT, P_OE,P_A,P_B,P_C);
// PxMATRIX display(64,32,P_LAT, P_OE,P_A,P_B,P_C,P_D);
PxMATRIX display(64, 32, P_LAT, P_OE, P_A, P_B, P_C, P_D, P_E);
Expand All @@ -83,58 +63,104 @@ TetrisMatrixDraw tetris2(display); // The "M" of AM/PM
TetrisMatrixDraw tetris3(display); // The "P" or "A" of AM/PM

Timezone myTZ;
unsigned long oneSecondLoopDue = 0;

bool showColon = true;
bool finishedAnimating = false;
bool displayIntro = true;
bool animateFlag = false;
bool setMatrixTime() {
static String lastDisplayedTime;
static String lastDisplayedAmPm;

String lastDisplayedTime = "";
String lastDisplayedAmPm = "";
bool timeChanged = false;

// This method is needed for driving the display
void display_updater() {
display.display(70);
String timeString;
String AmPmString;
if (twelveHourFormat) {
// Get the time in format "1:15" or 11:15 (12 hour, no leading 0)
// Check the EZTime Github page for info on
// time formatting
timeString = myTZ.dateTime("g:i");

//If the length is only 4, pad it with
// a space at the beginning
if (timeString.length() == 4) {
timeString = " " + timeString;
}

//Get if its "AM" or "PM"
AmPmString = myTZ.dateTime("A");
if (lastDisplayedAmPm != AmPmString) {
Serial.println(AmPmString);
lastDisplayedAmPm = AmPmString;
// Second character is always "M"
// so need to parse it out
tetris2.setText("M", forceRefresh);

// Parse out first letter of String
tetris3.setText(AmPmString.substring(0, 1), forceRefresh);
}
} else {
// Get time in format "01:15" or "22:15"(24 hour with leading 0)
timeString = myTZ.dateTime("H:i");
}

// Only update Time if its different
if (lastDisplayedTime != timeString) {
Serial.println(timeString);
lastDisplayedTime = timeString;
tetris.setTime(timeString, forceRefresh);
timeChanged = true;
}

return timeChanged;
}

void setAnimateFlag() {
animateFlag = true;
// declare all available animations
bool animateIntro(bool showColon);
bool animateTwelveHour(bool showColon);
bool animateTwentyFourHour(bool showColon);

// set function pointer to the active animation
auto activeAnimation = animateIntro;

bool animateIntro(bool showColon)
{
static unsigned long first_call = millis(); // remember the time of the first call

tetris.drawText(1, 21);

if(millis() > first_call + 20000) // switch to clock animation 20 seconds after first call
{
activeAnimation = twelveHourFormat ? animateTwelveHour : animateTwentyFourHour;
tetris.scale = 2;
}

return false;
}

// This method is for controlling the tetris library draw calls
void animationHandler()
bool animateTwelveHour(bool showColon)
{
// Not clearing the display and redrawing it when you
// dont need to improves how the refresh rate appears
if (!finishedAnimating) {
display.clearDisplay();
if (displayIntro) {
finishedAnimating = tetris.drawText(1, 21);
} else {
if (twelveHourFormat) {
// Place holders for checking are any of the tetris objects
// currently still animating.
bool tetris1Done = false;
bool tetris2Done = false;
bool tetris3Done = false;

tetris1Done = tetris.drawNumbers(-6, 26, showColon);
tetris2Done = tetris2.drawText(56, 25);

// Only draw the top letter once the bottom letter is finished.
if (tetris2Done) {
tetris3Done = tetris3.drawText(56, 15);
}

finishedAnimating = tetris1Done && tetris2Done && tetris3Done;

} else {
finishedAnimating = tetris.drawNumbers(2, 26, showColon);
}
}
setMatrixTime();

// Place holders for checking are any of the tetris objects
// currently still animating.
bool tetris1Done = false;
bool tetris2Done = false;
bool tetris3Done = false;

tetris1Done = tetris.drawNumbers(-6, 26, showColon);
tetris2Done = tetris2.drawText(56, 25);

// Only draw the top letter once the bottom letter is finished.
if (tetris2Done) {
tetris3Done = tetris3.drawText(56, 15);
}

return tetris1Done && tetris2Done && tetris3Done;
}

bool animateTwentyFourHour(bool showColon)
{
setMatrixTime();

return tetris.drawNumbers(2, 26, showColon);
}

void drawIntro(int x = 0, int y = 0)
Expand All @@ -151,40 +177,34 @@ void drawIntro(int x = 0, int y = 0)
tetris.drawChar("y", x + 47, y, tetris.tetrisGREEN);
}

void drawConnecting(int x = 0, int y = 0)
{
tetris.drawChar("C", x, y, tetris.tetrisCYAN);
tetris.drawChar("o", x + 5, y, tetris.tetrisMAGENTA);
tetris.drawChar("n", x + 11, y, tetris.tetrisYELLOW);
tetris.drawChar("n", x + 17, y, tetris.tetrisGREEN);
tetris.drawChar("e", x + 22, y, tetris.tetrisBLUE);
tetris.drawChar("c", x + 27, y, tetris.tetrisRED);
tetris.drawChar("t", x + 32, y, tetris.tetrisWHITE);
tetris.drawChar("i", x + 37, y, tetris.tetrisMAGENTA);
tetris.drawChar("n", x + 42, y, tetris.tetrisYELLOW);
tetris.drawChar("g", x + 47, y, tetris.tetrisGREEN);
}

void setup() {
Serial.begin(115200);

// Attempt to connect to Wifi network:
Serial.print("Connecting Wifi: ");
Serial.println(ssid);

// Set WiFi to station mode and disconnect from an AP if it was Previously
// connected
WiFi.mode(WIFI_STA);
WiFi.begin(ssid, password);

int attempts = 0;
while (WiFi.status() != WL_CONNECTED) {
Serial.print(".");
if(0 == attempts % 10) {
Serial.println();
Serial.print(F("Connecting to Wifi '"));
Serial.print(ssid);
Serial.print(F("' using password '"));
Serial.print(password);
Serial.print("' ");
}
delay(500);
Serial.print(".");
attempts++;
}

Serial.println("");
Serial.println("WiFi connected");
Serial.print("IP address: ");
Serial.println();
Serial.println(F("WiFi connected"));
Serial.print(F("IP address: "));
Serial.println(WiFi.localIP());

// Do not set up display before WiFi connection
Expand All @@ -193,14 +213,7 @@ void setup() {
// Intialise display library
display.begin(16);
display.clearDisplay();

// Setup ticker for driving display
display_ticker.attach(0.002, display_updater);
yield();
display.clearDisplay();

// "connecting"
drawConnecting(5, 10);
display.display(70);

// Setup EZ Time
setDebug(INFO);
Expand All @@ -213,85 +226,54 @@ void setup() {
Serial.print(F("Time in your set timezone: "));
Serial.println(myTZ.dateTime());

display.clearDisplay();
//"Powered By"
// "Powered By"
drawIntro(6, 12);
delay(2000);
unsigned long now = millis();
unsigned long start_time = now;
while(now < start_time + 2000) {
now = millis();
if(0 == now % (unsigned long)2)
{
display.display(70);
}
}

// Start the Animation Timer
tetris.setText("B. LOUGH");
timer_ticker.attach(0.1, animationHandler);

// Wait for the animation to finish
while (!finishedAnimating)
{
delay(10); //waiting for intro to finish
}
delay(2000);
//timer_ticker.attach(0.1, setAnimateFlag);
finishedAnimating = false;
displayIntro = false;
tetris.scale = 2;
}

void setMatrixTime() {
String timeString = "";
String AmPmString = "";
if (twelveHourFormat) {
// Get the time in format "1:15" or 11:15 (12 hour, no leading 0)
// Check the EZTime Github page for info on
// time formatting
timeString = myTZ.dateTime("g:i");
static bool showColon()
{
static unsigned int colonCounter = 0;
colonCounter++;
unsigned int colonFraction = colonCounter / 5;
return !!(colonFraction % 2);
}

//If the length is only 4, pad it with
// a space at the beginning
if (timeString.length() == 4) {
timeString = " " + timeString;
}
void loop()
{
static bool animationDone = false;
static bool colonVisible = true;

//Get if its "AM" or "PM"
AmPmString = myTZ.dateTime("A");
if (lastDisplayedAmPm != AmPmString) {
Serial.println(AmPmString);
lastDisplayedAmPm = AmPmString;
// Second character is always "M"
// so need to parse it out
tetris2.setText("M", forceRefresh);
unsigned long now = millis();

// Parse out first letter of String
tetris3.setText(AmPmString.substring(0, 1), forceRefresh);
if(0 == now % (unsigned long)100)
{
bool colonChanged = false;
if(colonVisible != showColon())
{
colonVisible = !colonVisible;
colonChanged = true;
}
} else {
// Get time in format "01:15" or "22:15"(24 hour with leading 0)
timeString = myTZ.dateTime("H:i");
}

// Only update Time if its different
if (lastDisplayedTime != timeString) {
Serial.println(timeString);
lastDisplayedTime = timeString;
tetris.setTime(timeString, forceRefresh);

// Must set this to false so animation knows
// to start again
finishedAnimating = false;
if(!animationDone || colonChanged)
{
display.clearDisplay();
animationDone = activeAnimation(colonVisible);
}
}
}


void loop() {
unsigned long now = millis();
// if(false && animateFlag){
// animateFlag = false;
// animationHandler();
// }

// animationHandler();
if (now > oneSecondLoopDue) {
// We can call this often, but it will only
// update when it needs to
setMatrixTime();
showColon = !showColon;
oneSecondLoopDue = now + 10000;
if(0 == now % (unsigned long)2)
{
display.display(70);
}
}
Loading