Compare commits

...

3 Commits

Author SHA1 Message Date
Neale Pickett fda0ef95e0 Merge README 2023-12-06 10:52:39 -07:00
Neale Pickett 8e45c59aa1 Merge branch 'master' of https://git.woozle.org/neale/wallart 2023-12-06 10:50:35 -07:00
Neale Pickett afa3c39fc3 TZ setup in UI 2023-12-06 10:50:31 -07:00
4 changed files with 51 additions and 60 deletions

View File

@ -20,32 +20,36 @@ Most people, after watching it for a bit,
form different ideas about what it's displaying. form different ideas about what it's displaying.
That's cool. That's cool.
Reset
------
Plug the device in, Setup
connect GND to pin A0,
and briefly press the reboot button.
It will flash orange and blue a few times
to let you know it has reset.
WiFi
----- -----
If the red light on the board is lit, If the red light on the board is lit,
that means it doesn't know how to connect to the WiFi. that means it doesn't know how to connect to the WiFi.
Get your phone or computer to connect to an access point Get your phone or computer to connect to an access point
called "Wall Art xxxxxxxxx". called "WallArt".
The password is "artsy fartsy", unless you changed it in the source code. The password is "artsy fartsy", unless you changed it in the source code.
Once connected, Once connected,
you should get a browser window that lets you connect. you should get a browser window that lets you connect.
If not, try going to http://neverssl.com/. If not, try going to http://neverssl.com/.
Please configure the clock before the WiFi.
This will set up your time zone,
so it doesn't blind you in the middle of the night.
You can clear the wifi information with a reset. You can clear the wifi information with a reset.
Reset
------
Plug the device in,
and connect GND to pin A0 (right next to GND).
The red LED on the Feather board should come on immediately,
indicating it needs the network set up again.
Network Server Network Server
-------------- --------------
@ -80,9 +84,6 @@ Clock
At night, At night,
and sometimes during the day, and sometimes during the day,
it displays something like a clock. 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 top row is 1 hour (3600 seconds)
* Each pixel in the middle row is 5 minutes (300 seconds) * Each pixel in the middle row is 5 minutes (300 seconds)
@ -98,7 +99,7 @@ Reset the device,
and select the "Update" button instead of configuring WiFi. and select the "Update" button instead of configuring WiFi.
Then you can upload the new .bin firmware file. Then you can upload the new .bin firmware file.
You will have to reconfigure networking after this. You may have to reconfigure networking after this.
### Uploading from CLI ### Uploading from CLI

View File

@ -1,5 +1,6 @@
#include <FastLED.h> #include <FastLED.h>
#include <WiFiManager.h> #include <WiFiManager.h>
#include <WiFiManagerTz.h>
#include <esp_wifi.h> #include <esp_wifi.h>
#include <HTTPClient.h> #include <HTTPClient.h>
#include <WiFiClientSecure.h> #include <WiFiClientSecure.h>
@ -8,13 +9,25 @@
WiFiManager wfm; WiFiManager wfm;
void network_reset() { void network_reset() {
Serial.println("Resetting network");
wfm.resetSettings(); wfm.resetSettings();
} }
void network_setup(char *password) { void on_time_available(struct timeval *t)
String hostid = String(ESP.getEfuseMac(), HEX); {
String hostname = "Wall Art " + hostid; struct tm timeInfo;
getLocalTime(&timeInfo, 1000);
Serial.println(&timeInfo, "%A, %B %d %Y %H:%M:%S %Z %z ");
}
void network_setup(char *password) {
String hostname = "WallArt";
WiFiManagerNS::NTP::onTimeAvailable(&on_time_available);
WiFiManagerNS::init(&wfm);
std::vector<const char *> menu = {"wifi", "info", "custom", "param", "sep", "restart", "exit"};
wfm.setMenu(menu);
wfm.setConfigPortalBlocking(false); wfm.setConfigPortalBlocking(false);
wfm.setHostname(hostname); wfm.setHostname(hostname);
wfm.autoConnect(hostname.c_str(), password); wfm.autoConnect(hostname.c_str(), password);
@ -24,7 +37,17 @@ bool connected() {
return WiFi.status() == WL_CONNECTED; return WiFi.status() == WL_CONNECTED;
} }
bool timeConfigured = false;
void pause(uint32_t dwMs) { void pause(uint32_t dwMs) {
if (connected() && !timeConfigured) {
WiFiManagerNS::configTime();
timeConfigured = true;
}
if (!digitalRead(RESET_PIN)) {
network_reset();
}
for (uint32_t t = 0; t < dwMs; t += 10) { for (uint32_t t = 0; t < dwMs; t += 10) {
wfm.process(); wfm.process();
digitalWrite(LED_BUILTIN, !connected()); digitalWrite(LED_BUILTIN, !connected());

View File

@ -1,5 +1,8 @@
#pragma once #pragma once
// Short this to ground to reset the network
#define RESET_PIN 26
void network_reset(); void network_reset();
void network_setup(char *password); void network_setup(char *password);
bool connected(); bool connected();

View File

@ -1,18 +1,16 @@
#include <FastLED.h> #include <FastLED.h>
#include <ArduinoHttpClient.h> #include <ArduinoHttpClient.h>
#include <WiFiClientSecure.h> #include <WiFiClientSecure.h>
#include <WiFiUdp.h> #include <WiFiUdp.h>
#include <NTPClient.h>
#include <TimeLib.h> #include <TimeLib.h>
#include "durations.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 TIMEZONE TZ_US_Mountain #define TIMEZONE TZ_US_Eastern
/* /*
* The hours when the day begins and ends. * The hours when the day begins and ends.
@ -34,47 +32,19 @@
#define HTTPS_TIMEOUT (2 * SECOND) #define HTTPS_TIMEOUT (2 * SECOND)
#define RESET_PIN 26
CRGB grid[GRIDLEN]; CRGB grid[GRIDLEN];
WiFiUDP ntpUDP;
NTPClient timeClient(ntpUDP);
void do_reset() {
for (int i = 0; i < 8; i++) {
for (int j = 0; j < 8; j += 1) {
grid[j] = ((i+j)%2) ? (CRGB::Orange) : (CRGB::Blue);
}
FastLED.show();
digitalWrite(LED_BUILTIN, i%2);
delay(300 * MILLISECOND);
}
network_reset();
}
void setup() { void setup() {
pinMode(RESET_PIN, INPUT_PULLUP); pinMode(RESET_PIN, INPUT_PULLUP);
pinMode(LED_BUILTIN, OUTPUT); pinMode(LED_BUILTIN, OUTPUT);
Serial.begin(19200);
FastLED.addLeds<WS2812, NEOPIXEL_PIN, GRB>(grid, GRIDLEN); FastLED.addLeds<WS2812, NEOPIXEL_PIN, GRB>(grid, GRIDLEN);
// Maybe it's the plexiglass, but for my build, I need to dial back the red // Maybe it's the plexiglass, but for my build, I need to dial back the red
FastLED.setCorrection(0xd0ffff); FastLED.setCorrection(0xd0ffff);
if (!digitalRead(RESET_PIN)) {
do_reset();
}
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);
@ -291,7 +261,6 @@ void displayTime(unsigned long duration = 20 * SECOND) {
FastLED.clear(); FastLED.clear();
while (millis() < end) { while (millis() < end) {
updateTime();
int hh = hour(); int hh = hour();
int mmss = now() % 3600; int mmss = now() % 3600;
uint8_t hue = HUE_YELLOW; uint8_t hue = HUE_YELLOW;
@ -337,14 +306,9 @@ void loop() {
uint8_t getprob = 4; uint8_t getprob = 4;
bool conn = connected(); bool conn = connected();
bool day = true; bool day = true;
timeStatus_t ts = timeStatus();
switch (timeStatus()) { if (ts == timeSet) {
case timeNotSet:
case timeNeedsSync:
updateTime();
break;
}
if (timeStatus() == timeSet) {
int hh = hour(); int hh = hour();
day = ((hh >= DAY_BEGIN) && (hh < DAY_END)); day = ((hh >= DAY_BEGIN) && (hh < DAY_END));
} }
@ -355,7 +319,7 @@ void loop() {
getprob = 16; getprob = 16;
} }
if (!day || p.Pick(4)) { if ((ts == timeSet) && (!day || p.Pick(4))) {
// At night, only ever show the clock // At night, only ever show the clock
displayTime(2 * MINUTE); displayTime(2 * MINUTE);
} else if (p.Pick(getprob)) { } else if (p.Pick(getprob)) {