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.
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
----------
@ -68,4 +84,3 @@ but if you want to make NeoPixel art,
think hard about what the end result should look like.
It's not enough to make a cool light show;
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 <WiFiUdp.h>
#include <NTPClient.h>
#include "times.h"
#include <Time.h>
#include "durations.h"
#include "timezones.h"
#include "picker.h"
#include "network.h"
#define NEOPIXEL_PIN 32
#define GRIDLEN 64
#define WFM_PASSWORD "artsy fartsy"
#define TIME_OFFSET (-7 * HOUR / SECOND)
#define TIMEZONE TZ_US_Mountain
/*
* 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_END 21
#define DAY_BEGIN 6
#define DAY_END 20
#define DAY_BRIGHTNESS 0x80
#define NIGHT_BRIGHTNESS 0x10
@ -35,7 +37,7 @@
CRGB grid[GRIDLEN];
WiFiUDP ntpUDP;
NTPClient timeClient(ntpUDP, TIME_OFFSET);
NTPClient timeClient(ntpUDP);
void setup() {
FastLED.addLeds<WS2812, NEOPIXEL_PIN, GRB>(grid, GRIDLEN);
@ -43,7 +45,17 @@ void setup() {
FastLED.setCorrection(0xc0ffff);
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) {
int reps = (cycles*GRIDLEN) + random(GRIDLEN);
int hue = random(256);
@ -243,22 +255,35 @@ void spinner(int count=32) {
}
void displayTime(unsigned long duration = 20 * SECOND) {
if (!connected()) return;
if (timeStatus() != timeSet) return;
unsigned long end = millis() + duration;
FastLED.clear();
while (millis() < end) {
timeClient.update();
int hh = timeClient.getHours();
int mm = timeClient.getMinutes();
int ss = timeClient.getSeconds();
updateTime();
int hh = hour();
int mmss = now() % 3600;
uint8_t hue = HUE_YELLOW;
if (hh >= 12) {
// Top: Hours
if (isPM()) {
hue = HUE_ORANGE;
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++) {
// Omit first and last position on a row
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 + 24] = CHSV(HUE_RED, 255, (i<mm/5)?128:48);
grid[pos + 48] = CHSV(HUE_PINK, 128, (i<ss/5)?96:48);
grid[pos + 24] = CHSV(HUE_RED, 255, (i<mm)?128:48);
grid[pos + 48] = CHSV(HUE_PINK, 128, (i<ss)?96:48);
}
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() {
Picker p;
uint8_t getprob = 4;
bool conn = connected();
bool day = true;
timeClient.update();
if (timeClient.isTimeSet()) {
int hh = timeClient.getHours();
day = ((hh > DAY_BEGIN) && (hh < DAY_END));
if (updateTime()) {
int hh = hour();
day = ((hh >= DAY_BEGIN) && (hh < DAY_END));
}
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) {
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();
} else if (day && p.Pick(4)) {
// These can be hella bright
@ -324,7 +343,5 @@ void loop() {
cm5(8);
} else if (p.Pick(2)) {
cm5(16);
} else if (p.Pick(4)) {
displayTime(1 * MINUTE);
}
}
}