Compare commits
3 Commits
04529ffab2
...
fda0ef95e0
Author | SHA1 | Date |
---|---|---|
Neale Pickett | fda0ef95e0 | |
Neale Pickett | 8e45c59aa1 | |
Neale Pickett | afa3c39fc3 |
31
README.md
31
README.md
|
@ -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
|
||||||
|
|
||||||
|
|
29
network.cpp
29
network.cpp
|
@ -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());
|
||||||
|
|
|
@ -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();
|
||||||
|
|
48
wallart.ino
48
wallart.ino
|
@ -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)) {
|
||||||
|
|
Loading…
Reference in New Issue