Compare commits

...

3 Commits

5 changed files with 88 additions and 35 deletions

6
.gitignore vendored
View File

@ -1 +1,5 @@
.vscode debug.cfg
debug_custom.json
esp32.svd
.vscode/
build/

View File

@ -49,6 +49,22 @@ A happy setup will cycle through each color once,
and then display orange for a while. and then display orange for a while.
Clock
-----
At night,
and sometimes during the day,
it displays something like a clock.
You will need to tell it your time zone.
It doesn't do daylight saving time, sorry.
I suggest you set it to standard time and pretend it's in sync with the sun.
* Each pixel in the top row is 1 hour (3600 seconds)
* Each pixel in the middle row is 5 minutes (300 seconds)
* Each pixel in the bottom row is 25 seconds
* There are four pixels around the bottom that move every 5 seconds
Philosophy Philosophy
---------- ----------
@ -68,4 +84,3 @@ but if you want to make NeoPixel art,
think hard about what the end result should look like. think hard about what the end result should look like.
It's not enough to make a cool light show; It's not enough to make a cool light show;
it has to make people wonder "what is that for?" it has to make people wonder "what is that for?"

17
timezones.h Normal file
View File

@ -0,0 +1,17 @@
#include <Timezone.h>
TimeChangeRule usEDT = {"EDT", Second, Sun, Mar, 2, -240};
TimeChangeRule usEST = {"EST", First, Sun, Nov, 2, -300};
Timezone TZ_US_Eastern(usEDT, usEST);
TimeChangeRule usCDT = {"CDT", Second, Sun, Mar, 2, -300};
TimeChangeRule usCST = {"CST", First, Sun, Nov, 2, -360};
Timezone TZ_US_Central(usCDT, usCST);
TimeChangeRule usMDT = {"MDT", Second, Sun, Mar, 2, -360};
TimeChangeRule usMST = {"MST", First, Sun, Nov, 2, -420};
Timezone TZ_US_Mountain(usMDT, usMST);
TimeChangeRule usPDT = {"EDT", Second, Sun, Mar, 2, -420};
TimeChangeRule usPST = {"EST", First, Sun, Nov, 2, -480};
Timezone TZ_US_Pacific(usPDT, usPST);

View File

@ -3,21 +3,23 @@
#include <WiFiClientSecure.h> #include <WiFiClientSecure.h>
#include <WiFiUdp.h> #include <WiFiUdp.h>
#include <NTPClient.h> #include <NTPClient.h>
#include "times.h" #include <Time.h>
#include "durations.h"
#include "timezones.h"
#include "picker.h" #include "picker.h"
#include "network.h" #include "network.h"
#define NEOPIXEL_PIN 32 #define NEOPIXEL_PIN 32
#define GRIDLEN 64 #define GRIDLEN 64
#define WFM_PASSWORD "artsy fartsy" #define WFM_PASSWORD "artsy fartsy"
#define TIME_OFFSET (-7 * HOUR / SECOND) #define TIMEZONE TZ_US_Mountain
/* /*
* The hours when the day begins and ends. * The hours when the day begins and ends.
* During the day, everything is brighter. * At night, all you get is a dim clock.
*/ */
#define DAY_BEGIN 7 #define DAY_BEGIN 6
#define DAY_END 21 #define DAY_END 20
#define DAY_BRIGHTNESS 0x80 #define DAY_BRIGHTNESS 0x80
#define NIGHT_BRIGHTNESS 0x10 #define NIGHT_BRIGHTNESS 0x10
@ -35,7 +37,7 @@
CRGB grid[GRIDLEN]; CRGB grid[GRIDLEN];
WiFiUDP ntpUDP; WiFiUDP ntpUDP;
NTPClient timeClient(ntpUDP, TIME_OFFSET); NTPClient timeClient(ntpUDP);
void setup() { void setup() {
FastLED.addLeds<WS2812, NEOPIXEL_PIN, GRB>(grid, GRIDLEN); FastLED.addLeds<WS2812, NEOPIXEL_PIN, GRB>(grid, GRIDLEN);
@ -43,7 +45,17 @@ void setup() {
FastLED.setCorrection(0xc0ffff); FastLED.setCorrection(0xc0ffff);
network_setup(WFM_PASSWORD); network_setup(WFM_PASSWORD);
} }
bool updateTime() {
if (timeClient.update()) {
time_t now = timeClient.getEpochTime();
time_t local = TIMEZONE.toLocal(now);
setTime(local);
return true;
}
return false;
}
void fade(int cycles = 2) { void fade(int cycles = 2) {
int reps = (cycles*GRIDLEN) + random(GRIDLEN); int reps = (cycles*GRIDLEN) + random(GRIDLEN);
int hue = random(256); int hue = random(256);
@ -243,22 +255,35 @@ void spinner(int count=32) {
} }
void displayTime(unsigned long duration = 20 * SECOND) { void displayTime(unsigned long duration = 20 * SECOND) {
if (!connected()) return; if (timeStatus() != timeSet) return;
unsigned long end = millis() + duration; unsigned long end = millis() + duration;
FastLED.clear(); FastLED.clear();
while (millis() < end) { while (millis() < end) {
timeClient.update(); updateTime();
int hh = timeClient.getHours(); int hh = hour();
int mm = timeClient.getMinutes(); int mmss = now() % 3600;
int ss = timeClient.getSeconds();
uint8_t hue = HUE_YELLOW; uint8_t hue = HUE_YELLOW;
if (hh >= 12) { // Top: Hours
if (isPM()) {
hue = HUE_ORANGE; hue = HUE_ORANGE;
hh -= 12; hh -= 12;
} }
// Middle: 5m (300s)
uint8_t mm = (mmss/300) % 12;
// Bottom: 25s
uint8_t ss = (mmss/25) % 12;
// Outer: 5s
uint8_t s = (mmss/5) % 5;
grid[64 - 7 - 1] = CHSV(HUE_PURPLE, 128, (s==1)?96:0);
grid[64 - 15 - 1] = CHSV(HUE_PURPLE, 128, (s==2)?96:0);
grid[64 - 8 - 1] = CHSV(HUE_PURPLE, 128, (s==3)?96:0);
grid[64 - 0 - 1] = CHSV(HUE_PURPLE, 128, (s==4)?96:0);
for (int i = 0; i < 12; i++) { for (int i = 0; i < 12; i++) {
// Omit first and last position on a row // Omit first and last position on a row
int pos = i + 1; int pos = i + 1;
@ -267,8 +292,8 @@ void displayTime(unsigned long duration = 20 * SECOND) {
} }
grid[pos + 0] = CHSV(hue, 255, (i<hh)?128:48); grid[pos + 0] = CHSV(hue, 255, (i<hh)?128:48);
grid[pos + 24] = CHSV(HUE_RED, 255, (i<mm/5)?128:48); grid[pos + 24] = CHSV(HUE_RED, 255, (i<mm)?128:48);
grid[pos + 48] = CHSV(HUE_PINK, 128, (i<ss/5)?96:48); grid[pos + 48] = CHSV(HUE_PINK, 128, (i<ss)?96:48);
} }
FastLED.show(); FastLED.show();
@ -276,33 +301,27 @@ void displayTime(unsigned long duration = 20 * SECOND) {
} }
} }
void adjustBrightness() {
int hh = timeClient.getHours();
if ((hh >= DAY_BEGIN) && (hh < DAY_END)) {
FastLED.setBrightness(DAY_BRIGHTNESS);
} else {
FastLED.setBrightness(NIGHT_BRIGHTNESS);
}
}
void loop() { void loop() {
Picker p; Picker p;
uint8_t getprob = 4; uint8_t getprob = 4;
bool conn = connected(); bool conn = connected();
bool day = true; bool day = true;
timeClient.update(); if (updateTime()) {
if (timeClient.isTimeSet()) { int hh = hour();
int hh = timeClient.getHours(); day = ((hh >= DAY_BEGIN) && (hh < DAY_END));
day = ((hh > DAY_BEGIN) && (hh < DAY_END));
} }
FastLED.setBrightness(day?DAY_BRIGHTNESS:NIGHT_BRIGHTNESS); FastLED.setBrightness(day?DAY_BRIGHTNESS:NIGHT_BRIGHTNESS);
// If we don't yet have net art, try a little harder to get it.
if ((NetArtFrames == 0) || !conn) { if ((NetArtFrames == 0) || !conn) {
getprob = 16; getprob = 16;
} }
if (p.Pick(getprob)) { if (!day || p.Pick(4)) {
// At night, only ever show the clock
displayTime(2 * MINUTE);
} else if (p.Pick(getprob)) {
netget(); netget();
} else if (day && p.Pick(4)) { } else if (day && p.Pick(4)) {
// These can be hella bright // These can be hella bright
@ -324,7 +343,5 @@ void loop() {
cm5(8); cm5(8);
} else if (p.Pick(2)) { } else if (p.Pick(2)) {
cm5(16); cm5(16);
} else if (p.Pick(4)) { }
displayTime(1 * MINUTE);
}
} }