Skip to content

Instantly share code, notes, and snippets.

@connornishijima
Last active May 9, 2022 03:24
Show Gist options
  • Save connornishijima/f6eefa02d0f50cfb23027b2aeb747a6b to your computer and use it in GitHub Desktop.
Save connornishijima/f6eefa02d0f50cfb23027b2aeb747a6b to your computer and use it in GitHub Desktop.
Mother's Day Clock Firmware
#include <TimeLib.h>
#include <WiFiUdp.h>
#include <WiFiManager.h> // https://github.com/tzapu/WiFiManager
#include "Pixie_Chroma.h" // ... Include library
PixieChroma pix; // ............ Get class object
WiFiUDP Udp;
#define DATA_PIN 5 // GPIO to use for Pixie Chroma data line
#define PIXIES_X 3 // Total amount and arrangement
#define PIXIES_Y 2 // of Pixie PCBs
uint8_t format_hour[24] = { 12, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 };
uint8_t cal_day = 0;
uint8_t cal_month = 0;
uint8_t cal_minute = 0;
uint8_t cal_hour = 0;
char* meridian = "[:#7028700000:]";
char* delimiter = ":";
bool tick = false ;
bool message_flag = true;
float hue = 200;
static const char ntp_server_name[] = "us.pool.ntp.org";
int time_zone = -7;
uint8_t dst_offset = 1;
unsigned int local_port = 8888; // local port to listen for UDP packets
time_t prev_display = 0;
uint32_t dst_rules[6][2] = {
{1000000000,1},
{1667725200,0},
{1678611600,1},
{1699174800,0},
{1710061200,1},
{1730624400,0},
};
void setup() {
Serial.begin(230400);
pix.begin( DATA_PIN, PIXIES_X, PIXIES_Y );
pix.clear(); // ................... Clears the display buffer
pix.set_max_power( 3.3, 5000 );
pix.set_brightness(12); // ... Set the output brightness
pix.set_scroll_type(SMOOTH);
pix.set_line_wrap(false);
pix.print(" .... ");
pix.show();
init_wifi();
Serial.print("IP number assigned by DHCP is ");
Serial.println(WiFi.localIP());
Serial.println("Starting UDP");
Udp.begin(local_port);
Serial.print("Local port: ");
Serial.println(Udp.localPort());
Serial.println("waiting for sync");
setSyncProvider(getNtpTime);
setSyncInterval(1500);
}
void loop() {
run_time();
pix.clear();
pix.print_color( CHSV(hue, 255, 255) );
pix.print(format_number(cal_month));
spin();
pix.print(format_number(cal_day));
pix.println(" ");
pix.print_color( CHSV(hue + 90, 255, 255) );
pix.print(format_number(cal_hour));
pix.print(delimiter);
pix.print(format_number(cal_minute));
pix.print(meridian);
pix.show();
delay(1);
if (message_flag) {
message_flag = false;
scroll_random_message();
}
yield();
}
void spin() {
static uint8_t del = 0;
static uint8_t spinner = 1;
if ( spinner == 1 ) {
pix.print("[:SPINNER_1:]");
}
else if (spinner == 2 ) {
pix.print("[:SPINNER_2:]");
}
else if (spinner == 3 ) {
pix.print("[:SPINNER_3:]");
}
else if (spinner == 4 ) {
pix.print("[:SPINNER_4:]");
}
else if (spinner == 5 ) {
pix.print("[:SPINNER_5:]");
}
else if (spinner == 6 ) {
pix.print("[:SPINNER_6:]");
}
else if (spinner == 7 ) {
pix.print("[:SPINNER_7:]");
}
else if (spinner == 8 ) {
pix.print("[:SPINNER_8:]");
}
else if (spinner == 9 ) {
pix.print("[:SPINNER_9:]");
}
else if (spinner == 10) {
pix.print("[:SPINNER_10:]");
}
if (del == 0) {
spinner++;
if (spinner > 10) {
spinner = 1;
}
}
del++;
if (del >= 8) {
del = 0;
}
}
void scroll_random_message() {
static uint8_t random_index = 0;
delay(1000);
if(random_index == 0){
pix.scroll_message("[:HEART:] CUSTOM MESSAGE HERE");
}
else if(random_index == 1){
pix.scroll_message("[:HEART:] CUSTOM MESSAGE HERE");
}
else if(random_index == 2){
pix.scroll_message("[:HEART:] CUSTOM MESSAGE HERE");
}
else if(random_index == 3){
pix.scroll_message("[:HEART:] CUSTOM MESSAGE HERE");
}
else if(random_index == 4){
pix.scroll_message("[:HEART:] CUSTOM MESSAGE HERE");
}
else if(random_index == 5){
pix.scroll_message("[:HEART:] CUSTOM MESSAGE HERE");
}
random_index++;
if(random_index >= 6){
random_index = 0;
}
}
void init_wifi() {
Serial.println("CONNECTING TO WIFI...");
WiFi.mode(WIFI_STA);
WiFiManager wm;
if (!wm.autoConnect("Pixie_Chroma_AP")) {
Serial.println("Failed to connect!");
delay(1000);
ESP.restart();
}
else { // Connected
Serial.println("WIFI CONNECTED");
}
}
void run_time() {
if (timeStatus() != timeNotSet) {
uint32_t t_now = now();
if (t_now != prev_display) { //update the display only if time has changed
prev_display = t_now;
for(uint8_t i = 0; i < 6; i++){
if(t_now >= dst_rules[i][0]){
dst_offset = dst_rules[i][1];
}
}
show_time();
}
}
}
void show_time() {
tick = !tick;
hue += 0.05;
if (tick) {
delimiter = ":";
}
else {
delimiter = " ";
}
cal_day = day();
cal_month = month();
cal_minute = minute();
cal_hour = hour();
if (cal_minute % 15 == 0 && second() == 0) {
message_flag = true;
}
meridian = "[:#7028700000:]";
if (cal_hour >= 12) {
meridian = "[:#7828100000:]";
}
cal_hour = format_hour[cal_hour];
}
char* format_number(uint8_t num) {
char* str = "00";
sprintf(str, "%02d", num);
return str;
}
/*-------- NTP code ----------*/
const int NTP_PACKET_SIZE = 48; // NTP time is in the first 48 bytes of message
byte packetBuffer[NTP_PACKET_SIZE]; //buffer to hold incoming & outgoing packets
time_t getNtpTime()
{
IPAddress ntpServerIP; // NTP server's ip address
while (Udp.parsePacket() > 0) ; // discard any previously received packets
Serial.println("Transmit NTP Request");
// get a random server from the pool
WiFi.hostByName(ntp_server_name, ntpServerIP);
Serial.print(ntp_server_name);
Serial.print(": ");
Serial.println(ntpServerIP);
sendNTPpacket(ntpServerIP);
uint32_t beginWait = millis();
while (millis() - beginWait < 1500) {
int size = Udp.parsePacket();
if (size >= NTP_PACKET_SIZE) {
Serial.println("Receive NTP Response");
Udp.read(packetBuffer, NTP_PACKET_SIZE); // read packet into the buffer
unsigned long secsSince1900;
// convert four bytes starting at location 40 to a long integer
secsSince1900 = (unsigned long)packetBuffer[40] << 24;
secsSince1900 |= (unsigned long)packetBuffer[41] << 16;
secsSince1900 |= (unsigned long)packetBuffer[42] << 8;
secsSince1900 |= (unsigned long)packetBuffer[43];
return secsSince1900 - 2208988800UL + (time_zone+dst_offset) * SECS_PER_HOUR;
}
}
Serial.println("No NTP Response :-(");
ESP.restart();
return 0; // return 0 if unable to get the time
}
// send an NTP request to the time server at the given address
void sendNTPpacket(IPAddress &address)
{
// set all bytes in the buffer to 0
memset(packetBuffer, 0, NTP_PACKET_SIZE);
// Initialize values needed to form NTP request
// (see URL above for details on the packets)
packetBuffer[0] = 0b11100011; // LI, Version, Mode
packetBuffer[1] = 0; // Stratum, or type of clock
packetBuffer[2] = 6; // Polling Interval
packetBuffer[3] = 0xEC; // Peer Clock Precision
// 8 bytes of zero for Root Delay & Root Dispersion
packetBuffer[12] = 49;
packetBuffer[13] = 0x4E;
packetBuffer[14] = 49;
packetBuffer[15] = 52;
// all NTP fields have been given values, now
// you can send a packet requesting a timestamp:
Udp.beginPacket(address, 123); //NTP requests are to port 123
Udp.write(packetBuffer, NTP_PACKET_SIZE);
Udp.endPacket();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment