Jellyfish 1
Av Hans Mehlin, 2021-01-10.
Jellyfish1 är en Arduino-driven lampa som ändrar färg och animationer baserat på rörelserna på aktiemarknaden.
Färgen på animationen indikerar om marknaden rör sig uppåt eller nedåt, medan hastigheten på animationerna indikerar hastigheten på rörelserna på marknaden. Färgerna är animerade som en cykel mellan två färger. Tentaklerna har en extra löpande vit pixel mellan varje färgcykel.
Exempel på animation som indikerar en positiv marknad med en hastighet på cirka 0,5% under 8 timmar:
Exempel på animation som indikerar en negativ marknad med en hastighet på cirka 0,5% under 8 timmar:
Hur den byggdes
Elektronik
Jellyfish 1 är baserad på ett NodeMCU V2 Arduino-kort med inbyggd WIFI, en NeoPixel Ring med 24 RGB-LED och 1 meter NeoPixel Digital RGBW LED-remsa som är uppdelad i 3 delar med 20 LED i varje. Kretsen drivs av extern 5V. En kondensator skyddar kretsen mot strömspikar och resistanser läggs till mellan den digitala utgången från Arduino och LED remsorna.
Kretsen testades först på ett experimentbräde, som också användes under utvecklingen av koden.
Kretsen löddes senare på ett universellt kort för att göra den mer robust och minska storleken. 5V-strömmen till Arduino kan enkelt kopplas bort när det behövs för att ansluta den till USB och uppdatera koden.
Kod
Arduino anropar en API-URL med regelbundna intervall för att hämta en json-fil med parametrar som styr färgerna och hastigheten på animationen.
// jellyfish 1 by Hans Mehlin
#include <Adafruit_NeoPixel.h>
#include <ESP8266WiFi.h>
#include <ESP8266HTTPClient.h>
#include <Arduino_JSON.h>
#ifdef __AVR__
#include <avr/power.h> // Required for 16 MHz Adafruit Trinket
#endif
const char* ssid = "your ssid here";
const char* password = "your password here";
// Pin for controlling ledstrip
#define LED_PIN D7
#define LED_PINR D5
// Number of NeoPixels attached to the Arduino
#define LED_COUNT 20
#define LED_COUNTR 24
// Declare our NeoPixel strip objects:
Adafruit_NeoPixel strip(LED_COUNT, LED_PIN, NEO_RGBW + NEO_KHZ800);
Adafruit_NeoPixel ring(LED_COUNTR, LED_PINR, NEO_GRB + NEO_KHZ800);
void setup() {
Serial.begin(115200); // Start the Serial communication to send messages to the computer
delay(10);
Serial.println('\n');
WiFi.begin(ssid, password); // Connect to the network
Serial.print("Connecting to ");
Serial.print(ssid); Serial.println(" ...");
int i = 0;
while (WiFi.status() != WL_CONNECTED) { // Wait for the Wi-Fi to connect
delay(1000);
Serial.print(++i); Serial.print(' ');
}
Serial.println('\n');
Serial.println("Connection established!");
Serial.print("IP address:\t");
Serial.println(WiFi.localIP()); // Send the IP address of the ESP8266 to the computer
strip.begin(); // INITIALIZE NeoPixel strip object (REQUIRED)
strip.show(); // Turn OFF all pixels ASAP
strip.setBrightness(20); // Set BRIGHTNESS to 50 is about 1/5 (max = 255)
ring.begin(); // INITIALIZE NeoPixel strip object (REQUIRED)
ring.show(); // Turn OFF all pixels ASAP
ring.setBrightness(20); // Set BRIGHTNESS to 50 is about 1/5 (max = 255)
}
void loop() {
int white = 0;
int whitepixel = 80;
int r1 = 0;
int g1 = 0;
int b1 = 255;
int r2 = 0;
int g2 = 255;
int b2 = 0;
int width = 20;
int sleep = 50;
float part;
float rad;
float s;
int numtimes;
int offsetr;
//Periodically refresh the variables from the web definition
if (WiFi.status() == WL_CONNECTED) { //Check WiFi connection status
HTTPClient http; //Declare an object of class HTTPClient
http.begin("http://your-url-here/data.json"); //Specify request destination
int httpCode = http.GET(); //Send the request
if (httpCode > 0) { //Check the returning code
String payload = http.getString(); //Get the request response payload
Serial.println(payload); //Print the response payload
//deserializeJson(vars, payload);
JSONVar myObject = JSON.parse(payload);
const char* name = myObject["name"];
if (myObject.hasOwnProperty("color1")) {
r1 = myObject["color1"][0];
g1 = myObject["color1"][1];
b1 = myObject["color1"][2];
}
if (myObject.hasOwnProperty("color2")) {
r2 = myObject["color2"][0];
g2 = myObject["color2"][1];
b2 = myObject["color2"][2];
}
if (myObject.hasOwnProperty("width")) {
width = myObject["width"];
}
if (myObject.hasOwnProperty("sleep")) {
sleep = myObject["sleep"];
}
http.end(); //Close connection
}
}
// Number of times to loop before we read the paramaters again
// 1000000 = about 1 minute
numtimes = 1000000/(LED_COUNT * width * sleep);
if (numtimes <= 0) { numtimes = 1; }
for(int bigloop=0; bigloop<numtimes; bigloop++) {
for(int offset=0; offset<width; offset++) {
offsetr = offsetr + 1;
if (offsetr > LED_COUNTR) {offsetr = offsetr - LED_COUNTR - 1; }
for(int i=0; i<LED_COUNT; i++) { // For each pixel in strip...
part = float(i - offset) / float(width);
rad = part * 6,283;
s = sin(rad);
s = s + 1,0;
s = s / 2,0;
if (bigloop==0 && offset==0 && i==0) {
Serial.println("i");
Serial.println(i);
Serial.println("s");
Serial.println(s);
}
int r = int( float(r2-r1) * s + float(r1));
int g = int( float(g2-g1) * s + float(g1));
int b = int( float(b2-b1) * s + float(b1));
int whitelevel = white;
// if (i==offset || i==offset-LED_COUNT) { whitelevel = whitepixel; }
if (i==offset) { whitelevel = whitepixel; }
strip.setPixelColor(i, g, r, b, whitelevel); // Set pixel's color (in RAM)
for(int j=0; j<LED_COUNTR; j++) { // For each pixel in ring...
part = float(j - offsetr) / float(LED_COUNTR);
rad = part * 6,283;
s = sin(rad);
s = s + 1,0;
s = s / 2,0;
if (bigloop==0 && offset==0 && i==0) {
Serial.println("i");
Serial.println(i);
Serial.println("s");
Serial.println(s);
}
int r = int( float(r2-r1) * s + float(r1));
int g = int( float(g2-g1) * s + float(g1));
int b = int( float(b2-b1) * s + float(b1));
ring.setPixelColor(j, r, g, b); // Set pixel's color (in RAM)
}
ring.show(); // Update ring to match
}
strip.show(); // Update strip to match
delay(sleep);
}
}
}
Nedan finns ett exempel på en json-fil. I mitt fall är det inte en statisk json-fil utan en php-backend som returnerar json. Backend hämtar regelbundet mina index från aktiemarknaden och beräknar lämpliga färger och hastighet. Eftersom backend kod är ganska personlig är den inte inkluderad här. Genom att separera visualiseringen i Arduino och backend som returnerar json kan Yellyfish1 användas för att visualisera andra saker som väder eller sociala medier-analyser.
{
"name": "Jellyfish1",
"sleep": 150,
"width": 60,
"color1": [
0,
0,
255
],
"color2": [
0,
255,
0
]
}
Montering
Kretsen monterades inuti en upp-och-nedvänd rund glasljusstake. Strömkabeln går genom ett borrat hål högst upp. LED-ringen monterades med ljuset uppåt tätt mot glaset för att sprida ljuset inuti glaset. Remsorna monterades som tentakler under glaset. En knut på strömkabeln håller den uppe och trådar håller ihop saker och tar bort stress från kablar.
Glaset täcktes med ett vitt oregelbundet och fluffigt tyg. För tentaklerna monterades en metalltråd i några band för att göra det möjligt att justera deras positioner och få dem att reflektera ljuset. Tyget kan enkelt tas bort, och kortet dras ut från glaset, om en programuppdatering behövs.
Webbsajten senast uppdaterad 2024-11
Copyright 2024 Vårboda Studio