Now it's network-aware

This commit is contained in:
Neale Pickett 2022-07-17 22:22:16 -06:00
parent 0f65cd1f92
commit de0505cf79
6 changed files with 172 additions and 143 deletions

View File

@ -12,10 +12,10 @@ furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
The software is provided "as is", without warranty of any kind, express or
implied, including but not limited to the warranties of merchantability,
fitness for a particular purpose and noninfringement. In no event shall the
authors or copyright holders be liable for any claim, damages or other
liability, whether in an action of contract, tort or otherwise, arising from,
out of or in connection with the software or the use or other dealings in the
software.

View File

@ -1,13 +1,10 @@
Wall Art
========
This is a CircuitPython port of an art piece I have
hanging in the wall of my office, with
This an art piece I have
hanging in the wall of my house, with
pixels crammed into a cardboard box.
This port is running on a 1x1 stick of wood,
with tissue paper around it.
It doesn't display anything significant.
The idea is to have something to look at if you're idle,
without it being a distraction from more pressing issues.

31
network.cpp Normal file
View File

@ -0,0 +1,31 @@
#include <FastLED.h>
#include <WiFiManager.h>
#include <esp_wifi.h>
#include <HTTPClient.h>
#include <WiFiClientSecure.h>
#include "network.h"
WiFiManager wfm;
void network_setup(char *password) {
String hostid = String(ESP.getEfuseMac(), HEX);
String hostname = "Wall Art " + hostid;
wfm.setConfigPortalBlocking(false);
wfm.setHostname(hostname);
wfm.autoConnect(hostname.c_str(), password);
pinMode(LED_BUILTIN, OUTPUT);
}
bool connected() {
return WiFi.status() == WL_CONNECTED;
}
void pause(uint32_t dwMs) {
for (uint32_t t = 0; t < dwMs; t += 10) {
wfm.process();
digitalWrite(LED_BUILTIN, connected());
delay(10);
}
}

10
network.h Normal file
View File

@ -0,0 +1,10 @@
#pragma once
#include <HTTPClient.h>
#include <WiFiClientSecure.h>
void network_setup(char *password);
bool connected();
void pause(uint32_t dwMs);
void netget(int count);

View File

@ -1,14 +1,23 @@
#include <FastLED.h>
#include "picker.h"
#include "network.h"
#define NEOPIXEL_PIN 2
#define GRIDLEN 50
#define NEOPIXEL_PIN 32
#define GRIDLEN 64
#define WFM_PASSWORD "artsy fartsy"
#define ART_URL "https://sweetums.woozle.org/public/wallart.bin"
#define MILLISECOND 1
#define SECOND (1000 * MILLISECOND)
CRGB grid[GRIDLEN];
void setup() {
FastLED.addLeds<WS2812, NEOPIXEL_PIN, GRB>(grid, GRIDLEN);
FastLED.setBrightness(32);
network_setup(WFM_PASSWORD);
}
void fade(int cycles = 2) {
int reps = (cycles*GRIDLEN) + random(GRIDLEN);
int hue = random(256);
@ -17,15 +26,15 @@ void fade(int cycles = 2) {
grid[(i+pos) % GRIDLEN] = CHSV(hue, 255, pos * 32);
}
FastLED.show();
delay(80);
pause(80);
}
}
void singleCursor(int count = 80) {
for (int i = 0; i < 80; i++) {
for (int i = 0; i < count; i++) {
grid[20] = CHSV(0, 210, 127 * (i%2));
FastLED.show();
delay(120);
pause(120);
}
}
@ -41,7 +50,7 @@ void sparkle(int cycles=50) {
for (int j = 0; j < NUM_SPARKS; j++) {
grid[pos[j]] = CRGB::Black;
}
delay(40);
pause(40);
}
}
@ -76,11 +85,11 @@ void glitchPulse(int cycles=1000) {
steps[i]--;
}
FastLED.show();
delay(100);
pause(100);
}
}
void conwayish(int cycles=1000) {
void conwayish(int cycles=5000) {
uint8_t total[GRIDLEN];
uint8_t left[GRIDLEN] = {0};
uint8_t hue = random(0, 64);
@ -104,29 +113,115 @@ void conwayish(int cycles=1000) {
}
}
FastLED.show();
delay(20);
pause(20);
}
}
void setup() {
FastLED.addLeds<WS2812, NEOPIXEL_PIN, RGB>(grid, GRIDLEN);
FastLED.setBrightness(52);
pinMode(LED_BUILTIN, OUTPUT);
void cm5(int cycles=200) {
for (int frame = 0; frame < cycles; frame++) {
int val = 127 * random(2);
for (int pos = 0; pos < GRIDLEN; pos++) {
if (pos < GRIDLEN-1) {
grid[pos] = grid[pos + 1];
} else {
grid[pos] = CHSV(0, 255, val);
}
}
FastLED.show();
pause(500);
}
}
// Art from the network
bool NetArtExists = false;
CRGB NetArt[GRIDLEN];
void netart() {
if (NetArtExists) {
memcpy(grid, NetArt, GRIDLEN*3);
FastLED.show();
pause(10 * SECOND);
}
}
int netgetStatus(int hue) {
static int positions[4] = {0};
for (int j = 0; j < 4; j++) {
grid[positions[j]] = CHSV(0, 0, 0);
positions[j] = random(GRIDLEN);
grid[positions[j]] = CHSV(hue, 255, 180);
}
FastLED.show();
pause(500);
return hue;
}
void netget(int count=30) {
int hue = netgetStatus(HUE_BLUE);
if (connected()) {
WiFiClientSecure scli;
hue = netgetStatus(hue - 32);
scli.setInsecure();
{
HTTPClient https;
if (https.begin(scli, ART_URL)) {
hue = netgetStatus(hue - 32);
int code = https.GET();
if (code == HTTP_CODE_OK) {
hue = netgetStatus(hue - 32);
String resp = https.getString();
for (int i = 0; i < resp.length(); i += 3) {
if (resp.length() < i+3) {
break;
}
CRGB pixel = CRGB(resp[i], resp[i+1], resp[i+2]);
NetArt[i/3] = rgb2hsv_approximate(pixel);
}
NetArtExists = true;
hue = hue - 32;
}
https.end();
FastLED.show();
for (int i = 0; i < 4*4; i++) {
pause(250);
}
}
scli.stop();
}
}
for (int i = 0; i < count; i++) {
netgetStatus(hue);
}
}
void loop() {
Picker p;
Picker p;
if (p.Pick(1)) {
fade();
singleCursor(20);
} else if (p.Pick(1)) {
sparkle();
} else if (p.Pick(4)) {
singleCursor();
} else if (p.Pick(8)) {
conwayish();
} else if (p.Pick(8)) {
glitchPulse();
}
}
if (p.Pick(1)) {
fade();
singleCursor(20);
} else if (p.Pick(1)) {
sparkle();
} else if (p.Pick(4)) {
singleCursor();
} else if (p.Pick(8)) {
conwayish();
} else if (p.Pick(8)) {
glitchPulse();
} else if (p.Pick(8)) {
cm5();
} else if (p.Pick(4) || !connected()) {
netget();
}
// trying to debug why we get freezing
grid[0] = CHSV(HUE_YELLOW, 255, 255);
FastLED.show();
}

View File

@ -1,104 +0,0 @@
import board
from digitalio import DigitalInOut, Direction, Pull
import adafruit_dotstar as dotstar
import adafruit_fancyled.adafruit_fancyled as fancy
import time
import neopixel
import random
import microcontroller
# One pixel connected internally!
dot = dotstar.DotStar(board.APA102_SCK, board.APA102_MOSI, 1, brightness=0.2)
dot[0] = 0
# Built in red LED
led = DigitalInOut(board.D13)
led.direction = Direction.OUTPUT
# NeoPixel strip (of 16 LEDs) connected on D4
GRIDLEN = 64
grid = neopixel.NeoPixel(board.D4, GRIDLEN, brightness=0.2, auto_write=False, pixel_order=neopixel.GRB)
class GlitchPixel:
def __init__(self):
self.init()
self.nsteps = 64
self.step = random.randrange(self.nsteps)
def init(self):
self.step = 0
self.pos = random.randrange(GRIDLEN)
self.color = fancy.CHSV(random.random()).pack()
def frame(self):
bmask = (0xff * self.step // 32) & 0xff
if self.step > self.nsteps/2:
bmask = 0xff - bmask
mask = (bmask << 16) | (bmask << 8) | (bmask << 0)
color = self.color & mask
grid[self.pos] = color
self.step += 1
if self.step > self.nsteps:
self.init()
def fade():
reps = 300 + random.randrange(GRIDLEN)
hue = random.randrange(256)
colors = [fancy.CHSV(hue, 255, v).pack() for v in range(0, 256, 32)]
rcolors = colors[:]
rcolors.reverse()
colors = colors + rcolors
for count in range(reps):
pos = count % GRIDLEN
for color in colors:
grid[pos] = color
pos -= 1
grid.show()
def singleCursor():
red = fancy.CHSV(0, 210, 127).pack()
pos = 20
for i in range(80):
grid[pos] = red * (i % 2)
led.value = not (i % 2)
grid.show()
time.sleep(0.08)
def sparkle():
white = fancy.CHSV(0, 0, 127).pack()
pos = [0,0,0]
for i in range(50):
for j in range(len(pos)):
pos[j] = random.randrange(GRIDLEN)
grid[pos[j]] = white
grid.show()
for p in pos:
grid[p] = 0
grid.show()
def glitchPulse():
grid.fill(0)
pixels = []
for i in range(4):
p = GlitchPixel()
pixels.append(p)
for f in range(1000):
for p in pixels:
p.frame()
grid.show()
time.sleep(0.1)
def loop():
fade()
singleCursor()
sparkle()
glitchPulse()
# For some reason, this program freezes occasionally.
# I don't want to debug CircuitPython.
microcontroller.reset()
while True:
loop()