Skip to content

Instantly share code, notes, and snippets.

@terryspitz
Last active July 19, 2019 07:54
Show Gist options
  • Save terryspitz/071d01c8aa18b21ca6e702b238476f01 to your computer and use it in GitHub Desktop.
Save terryspitz/071d01c8aa18b21ca6e702b238476f01 to your computer and use it in GitHub Desktop.
added seconds toggle by closing pins D0/RX briefly
//Terry Spitz, 2019
// Hardware:
// DS3231 Real Time Clock board
// 4x MAX7219 8x8 LED Matrix with controller
#include "LedControl.h"
#include <Wire.h>
#include <RtcDS3231.h>
TwoWire wire;
RtcDS3231<TwoWire> rtc(wire);
const int RTC_GND_PIN = D8;
const int RTC_VCC_PIN = D7;
const int RTC_SDA_PIN = D6;
const int RTC_SCL_PIN = D5;
//To switch between hh:mm and hh:mm:ss, briefly connect these pins
const int SEC_GND_PIN = D1;
const int SEC_TEST_PIN = RX;
const int DEVICE_COUNT = 4;
LedControl led = LedControl(D4, D2, D3, DEVICE_COUNT);
void setup() {
Serial.begin(115200);
Serial.println("\nStarted\n");
//Serial.swap(); //Free RX,TX pins
pinMode(SEC_GND_PIN, OUTPUT); digitalWrite(SEC_GND_PIN, LOW);
pinMode(SEC_TEST_PIN, INPUT_PULLUP);
pinMode(RTC_GND_PIN, OUTPUT); digitalWrite(RTC_GND_PIN, LOW);
pinMode(RTC_VCC_PIN, OUTPUT); digitalWrite(RTC_VCC_PIN, HIGH);
wire.begin(RTC_SDA_PIN, RTC_SCL_PIN);
rtc.Begin();
RtcDateTime now = rtc.GetDateTime();
if (rtc.LastError() != 0)
{
// we have a communications error
// see https://www.arduino.cc/en/Reference/WireEndTransmission for
// what the number means
Serial.print("RTC communications error = ");
Serial.println(rtc.LastError());
Serial.println("Restarting in 5s");
delay(5000);
ESP.reset();
}
if (!rtc.IsDateTimeValid())
{
// Common Causes:
// 1) the battery on the device is low or even missing and the power line was disconnected
Serial.println("Warning: RTC lost confidence in the DateTime!");
}
char datestring[9];
snprintf_P(datestring, 9, PSTR("%02u:%02u:%02u"),
now.Hour(), now.Minute(), now.Second() );
Serial.println(datestring);
for (char device = 0; device < DEVICE_COUNT; ++device) {
led.shutdown(device, false); //wake up led device
led.setIntensity(device, 3);
led.clearDisplay(device);
}
}
// My little 5x3 set of digits, from https://docs.google.com/spreadsheets/d/18fk7YnEaq9ArqHn4P15a8HQxXN0mI4ds9AppET3lukI/edit?usp=sharing
const char N_DIGITS = 15;
const char ROWS_PER_DIGIT = 6;
const int COLON = 11;
const byte DIGITS[N_DIGITS][ROWS_PER_DIGIT] = {
{0x2, 0x5, 0x5, 0x5, 0x2, 0}, // 0
{0x2, 0x6, 0x2, 0x2, 0x7, 0}, // 1
{0x6, 0x1, 0x2, 0x4, 0x7, 0}, // 2
{0x6, 0x1, 0x7, 0x1, 0x6, 0}, // 3
{0x1, 0x3, 0x5, 0x7, 0x1, 0}, // 4
{0x7, 0x4, 0x7, 0x1, 0x6, 0}, // 5
{0x3, 0x4, 0x7, 0x5, 0x7, 0}, // 6
{0x7, 0x1, 0x1, 0x1, 0x1, 0}, // 7
{0x7, 0x5, 0x7, 0x5, 0x7, 0}, // 8
{0x7, 0x5, 0x7, 0x1, 0x1, 0}, // 9
{0x2, 0x5, 0x5, 0x5, 0x2, 0}, // 0 repeated
{0x0, 0x1, 0x0, 0x1, 0x0, 0}, // :
{0x0, 0x0, 0x0, 0x0, 0x0, 0}, // blank
{0x1, 0x3, 0x1, 0x1, 0x3, 0}, // 1, 2-pixel wide
{0x0, 0x0, 0x0, 0x0, 0x0, 0}, // blank
};
unsigned long delaytime_scroll = 100;
const int PARTS_HHMMSS = 8; //6 digits + 2 colons
const int PARTS_HHMM = 5; //4 digits + 1 colon
int SHIFTS_HHMMSS[PARTS_HHMMSS] = {26, 22, 20, 16, 12, 10, 6, 2};
int SHIFTS_HHMM[PARTS_HHMM] = {22, 18, 16, 12, 8};
int prev_digits[PARTS_HHMMSS];
bool showSeconds = false;
void loop()
{
//Serial.println("loop");
RtcDateTime now = rtc.GetDateTime();
if(now.Second()%10==prev_digits[7])
return;
int digits[PARTS_HHMMSS] = {now.Hour() / 10, now.Hour() % 10, COLON,
now.Minute() / 10, now.Minute() % 10, COLON,
now.Second() / 10, now.Second() % 10
};
int parts = showSeconds ? PARTS_HHMMSS : PARTS_HHMM;
int* shifts = showSeconds ? SHIFTS_HHMMSS : SHIFTS_HHMM;
bool scrolls[PARTS_HHMMSS];
for (char part = 0; part < parts; ++part) {
scrolls[part] = digits[part] != prev_digits[part];
prev_digits[part] = digits[part];
}
for (char scroll = 0; scroll <= ROWS_PER_DIGIT; ++scroll)
{
uint32_t rows[8];
for (char row = 0; row < 8; ++row)
rows[row] = 0;
for (char part = 0; part < parts; ++part)
{
if (digits[part] != COLON)
rows[0] |= uint32_t(digits[part]) << shifts[part];
for (char row = 0; row < 5; ++row)
{
char rowdigit = digits[part];
if (scrolls[part] && (scroll + row) < ROWS_PER_DIGIT) {
if (digits[part] == 0) {
if (part == 0 || part == 3 || part == 5)
rowdigit = 5;
else
rowdigit = 9;
}
else
rowdigit--;
}
char rowindex = (row + (scrolls[part] ? scroll : 0)) % ROWS_PER_DIGIT;
rows[row + 2] |= uint32_t(DIGITS[rowdigit][rowindex]) << shifts[part];
}
}
int brightness = (now.Hour()<10 || now.Hour()>18) ? 0 : 5;
for (char row = 0; row < 8; ++row) {
//Serial.println(String(int(row)) + "," + String(rows[row]));
for (char device = 0; device < DEVICE_COUNT; ++device) {
led.setIntensity(device, brightness);
led.setRow((DEVICE_COUNT - 1 - device), row, (rows[row] >> (8 * device)) & 0xff);
}
}
delay(delaytime_scroll);
}
if(digitalRead(SEC_TEST_PIN)==LOW)
showSeconds = !showSeconds;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment