Pojďme si vytvořit naprosto minimalistický ovladač pro LED pásek WS2812, který bude připojen k naší domácí wifi síti a u kterého budeme moci ovládat barvu, jas i základní efekty, bez jakékoliv nutné aplikace, z jakéhokoliv zařízení připojeného k naší síti. Ovládačů na led pásky najdeme již hotových spousty. Jejich nevýhoda je však, že k jejich ovládání je nutné používat další aplikace nebo například přiložené ovladače. Co tahle to ale zjednodušit a ovládat barvu, jas nebo i zapnutí efektu prostě tím, že s páskem v síti zahájíme komunikaci, například otevřením adresy v mobilním telefonu?
Pokud totiž obejdeme ovládací aplikace, otevírá se nám totiž najednou obrovská možnost, jak pásek využít. Například, jakmile si zapnete počítač, může na pozadí zavolat do get a pásek zapnout. Můžete ovládat pásek pomocí jednoduchého internetového prohlížeče, kdekoliv v domácnosti nebo například pomocí serveru. Doma se může ověřovat, jestli je na Minecraft serveru ve vaší domácnosti více uživatelů a podle toho barvu pásku měnit. Já pasek propojil s aletry na streamovací platformě Twitch, kde vysílám každý pracovní den. Sledující mohou barvu měnit podle libosti nebo se může zapnout nějaké blikání v závislosti na tom, co se na streamu děje.
Jak je vidět, možnosti využití jsou velké a zaleží jen na vás, k čemu takto upravený pásek dovedete využít. Zapojení je také velice jednoduché. Použijeme vývojovou destičku NodeMcu osazenou ESP8266. Poté led pásek WS1812 se 100 diodami. A v poslední řadě stabilizovaný zdroj na 5V 3A, který dává našemu pásku i kontrolérů dostatek energie. Zdroj je zapojen na konec pásku, protože pásek je na celé délce průchozí. Na začátku pásku je tak připojen kontrolér, který se z něj napájí.
Princip kódu je velice jednoduchý. Pomocí otevření webové stránky s parametry předáme informace pásku a ten je podle toho zpracuje. Vždy budeme volat podstránky. Ty mají název stejný jako s funkcí, kterou budeme používat. Například jas tedy budeme ovládat pomocí http://ip_v_siti/jas?…, kde se hodnota volá od 0 do 255 nebo barvičky pásku budeme volat http://ip_v_siti/nastav?… nebo si budeme moct přehrát nějaký krátký efekt, kdy řadič při otevření stránky na pár vteřin led pásek například rozbliká http://ip_v_siti/kometa. Zároveň všechny změněné udaje jako je nastavená barva nebo jas budeme ukládat do paměti kontroléru tak, aby při ipětovném zapnutí napájení si kontrolér načetl poslední nastavení a nedocházelo tak k restartování barev nebo hodnoty jasu.
Zde je zdrojový kód základních funkcí.
int start = 1;
#include <ESP8266WiFi.h>
#include <WiFiClient.h>
#include <ESP8266WebServer.h>
#include <ESP_EEPROM.h>
#include <Adafruit_NeoPixel.h>
#define pinDI 4
// nastavení počtu LED modulů
#define pocetLED 100
// inicializace LED modulu z knihovny
// Parameter 1 = number of pixels in strip
// Parameter 2 = pin number (most are valid)
// Parameter 3 = pixel type flags, add together as needed:
// NEO_KHZ800 800 KHz bitstream (most NeoPixel products w/WS2812 LEDs)
// NEO_KHZ400 400 KHz (classic 'v1' (not v2) FLORA pixels, WS2811 drivers)
// NEO_GRB Pixels are wired for GRB bitstream (most NeoPixel products)
// NEO_RGB Pixels are wired for RGB bitstream (v1 FLORA pixels, not v2)
//Adafruit_NeoPixel strip = Adafruit_NeoPixel(NUM_LEDS, PIN, NEO_GRB + NEO_KHZ800);
Adafruit_NeoPixel rgbWS = Adafruit_NeoPixel(pocetLED, pinDI, NEO_GRB + NEO_KHZ800);
#define RED_AD 0
#define GREEN_AD 4
#define BLUE_AD 8
#define JAS_AD 12
int poc = 0;
int poc2 = 0;
const char* ssid = "TajnaWifi";
const char* password = "SuperTajneHeslo";
ESP8266WebServer server(80);
String webString = ""; // String to display
// Generally, you should use "unsigned long" for variables that hold time
unsigned long previousMillis = 0; // will store last temp was read
const long interval = 2000; // interval at which to read sensor
void handle_root() {
int analog = 0;
Serial.println("HTTP cteni ");
webString = "|WEBSERVER|"; // Arduino has a hard time with float to string
server.send(200, "text/plain", webString); // send to someones browser when asked
delay(100);
}
void setup(void)
{
// You can open the Arduino IDE Serial Monitor window to see what the code is doing
Serial.begin(115200); // Serial connection from ESP-01 via 3.3v console cable
EEPROM.begin(16);
// načteni jasu z paměti
int read_jas;
EEPROM.get(JAS_AD, read_jas);
Serial.print("nacitam jas - ");
Serial.println(read_jas);
// zahájení komunikace s LED modulem
rgbWS.begin();
rgbWS.setBrightness(read_jas);
// nasstaveni wifi modu jen na clienta
// WiFi.mode(m): set mode to WIFI_AP, WIFI_STA, or WIFI_AP_STA.
// WiFi.mode(WIFI_STA);
WiFi.softAPdisconnect(true);
// Connect to WiFi network
WiFi.begin(ssid, password);
Serial.print("\n\r \n\rWorking to connect");
// Wait for connection
while (WiFi.status() != WL_CONNECTED) {
delay(1000);
Serial.print(".");
}
Serial.println("");
Serial.print("Connected to ");
Serial.println(ssid);
Serial.print("IP address: ");
Serial.println(WiFi.localIP());
server.on("/", handle_root);
server.on("/nastav", []() { // if you add this subdirectory to your webserver call, you get text below :)
int chyba_dat = 0;
String r=server.arg("r");
int red = r.toInt();
Serial.println("Volam zmenu barev");
Serial.print(" RED - ");
Serial.println(red);
if ((red > -1 ) and (red < 256)) {
webString = "Red je "+ String(red) +" ";
EEPROM.put(RED_AD,red);
}else{
webString= "R neplatne zadani cekam 0/255 ";
chyba_dat = 1;
}
String g=server.arg("g");
int green = g.toInt();
Serial.print(" Green - ");
Serial.println(green);
if ((green > -1 ) and (green < 256)) {
webString = webString + "Green je "+ String(green) +" ";
EEPROM.put(GREEN_AD,green);
}else{
webString= "G neplatne zadani cekam 0/255 ";
chyba_dat = 1;
}
String b=server.arg("b");
int blue = b.toInt();
Serial.print(" Blue - ");
Serial.println(blue);
if ((blue > -1 ) and (blue < 256)) {
webString = webString + "Blue je "+ String(blue) +" ";
EEPROM.put(BLUE_AD,blue);
}else{
webString= "B neplatne zadani cekam 0/255 ";
chyba_dat = 1;
}
if ( chyba_dat < 1 ) {
// write the data to EEPROM
boolean ok1 = EEPROM.commit();
zmen_vse_RGB (red , green , blue );
Serial.println((ok1) ? "Ukladani probehlo ok" : "Chyba ulozeni do pameti");
}else{
Serial.println("Chyba dat ukladani preruseno.");
}
server.send(200, "text/plain", webString); // send to someones browser when asked
});
server.on("/jas", []() { // if you add this subdirectory to your webserver call, you get text below :)
int chyba_dat = 0;
String r=server.arg("r");
int jas = r.toInt();
Serial.println("Volam zmenu jasu");
Serial.print(" Jas - ");
Serial.println(jas);
if ((jas > -1 ) and (jas < 256)) {
webString = "Jas je "+ String(jas) +" ";
EEPROM.put(JAS_AD,jas);
}else{
webString= "Jas ma neplatne zadani cekam 0/255 ";
chyba_dat = 1;
}
if ( chyba_dat < 1 ) {
// write the data to EEPROM
boolean ok1 = EEPROM.commit();
rgbWS.setBrightness(jas);
rgbWS.show();
// rgbWS.begin();
Serial.println((ok1) ? "Ukladani probehlo ok" : "Chyba ulozeni do pameti");
}else{
Serial.println("Chyba dat ukladani preruseno.");
}
server.send(200, "text/plain", webString); // send to someones browser when asked
});
// kometa
server.on("/kometa", []() { // if you add this subdirectory to your webserver call, you get text below :)
webString= "Kometa ";
server.send(200, "text/plain", webString); // send to someones browser when asked
zmen_vse_RGB (0,0,0);
int krok = 0;
// int velikost= 10;
// int krok2 = 0;
for(krok=0;krok<pocetLED+25;krok++){
//for(krok2=0;krok2<velikost;krok2++){
// nastavRGB (255-(krok2*10), 255-(krok2*10), 255-(krok2*10), krok-krok2);
// }
//nastavRGB (0, 0, 0, krok-krok2-1);
nastavRGB (255, 255, 255, krok);
nastavRGB (75, 75, 75, krok-2);
nastavRGB (50, 50, 50, krok-6);
nastavRGB (30, 30, 30, krok-10);
nastavRGB (15, 15, 15, krok-20);
nastavRGB (0, 0, 0, krok-22);
Serial.println(krok);
delay(5);
}
/* */
// konec efektu
delay(1000);
load_rgb( );
});
// kometa
// htmlcolor
server.on("/html_barva", []() { // if you add this subdirectory to your webserver call, you get text below :)
int chyba_dat = 0;
String r=server.arg("r");
String html = r;
Serial.println("Volam zmenu barvy z html zadani");
int pocet = 0;
pocet = html.length();
//#F96AA3 F96AA3
//# nelze pouzit ignoruje v promenich tento znak !
if ((pocet > 5 ) and (pocet < 7)) {
// poslalo se 6 znaku správne zadani
Serial.println(" Spravne zadani ");
// string hexstring = "#FF3Fa0";
html = "#"+html;
// Get rid of '#' and convert it to integer
int number = (int) strtol( &html[1], NULL, 16);
// Split them up into r, g, b values
int r = number >> 16;
int g = number >> 8 & 0xFF;
int b = number & 0xFF;
Serial.print("cervena je ");
Serial.println(r);
EEPROM.put(RED_AD,r);
Serial.print("zelena je ");
Serial.println(g);
EEPROM.put(GREEN_AD,g);
Serial.print("modra je ");
Serial.println(b);
EEPROM.put(BLUE_AD,b);
// write the data to EEPROM
boolean ok1 = EEPROM.commit();
zmen_vse_RGB (r , g , b );
webString = "Barva byla nastavena na "+ String(html) +".";
Serial.println((ok1) ? "Ukladani probehlo ok" : "Chyba ulozeni do pameti");
}else{
// špatné zadaní
Serial.print(" Chyba poctu znaku poslanych pro barvy odeslano ");
Serial.print(pocet);
Serial.println(" znaku. ");
webString = "Chyba poctu znaku poslanych pro barvy odeslano "+ String(pocet) +" znaku.";
}
server.send(200, "text/plain", webString); // send to someones browser when asked
});
server.begin();
Serial.println("HTTP server started");
Serial.println("Nacitani barev z eprom");
Serial.print("Red ");
int read_red;
EEPROM.get(RED_AD, read_red);
Serial.print(read_red);
Serial.print(" Green ");
int read_green;
EEPROM.get(GREEN_AD, read_green);
Serial.print(read_green);
Serial.print(" Blue ");
int read_blue;
EEPROM.get(BLUE_AD, read_blue);
Serial.println(read_blue);
// nastavRGB(read_red , read_green , read_blue , 1);
zmen_vse_RGB (read_red , read_green , read_blue );
EEPROM.get(JAS_AD, read_jas);
Serial.print("nacitam jas - ");
Serial.println(read_jas);
rgbWS.setBrightness(read_jas);
rgbWS.show();
}
void load_rgb( ) {
int read_red;
int read_green;
int read_blue;
EEPROM.get(RED_AD, read_red);
EEPROM.get(GREEN_AD, read_green);
EEPROM.get(BLUE_AD, read_blue);
zmen_vse_RGB (read_red , read_green , read_blue );
}
void loop(void)
{
server.handleClient();
}
void nastavRGB (byte r, byte g, byte b, int cislo) {
// vytvoření proměnné pro ukládání barev
uint32_t barva;
// načtení barvy do proměnné
barva = rgbWS.Color(r, g, b);
// nastavení barvy pro danou LED diodu,
// číslo má pořadí od nuly
rgbWS.setPixelColor(cislo, barva);
// aktualizace barev na všech modulech
rgbWS.show();
}
void zmen_vse_RGB (byte r, byte g, byte b) {
for(poc=0;poc<pocetLED;poc++){
// vytvoření proměnné pro ukládání barev
uint32_t barva;
// načtení barvy do proměnné
barva = rgbWS.Color(r, g, b);
// nastavení barvy pro danou LED diodu,
// číslo má pořadí od nuly
rgbWS.setPixelColor(poc, barva);
// aktualizace barev na všech modulech
rgbWS.show();
}
}
Jen malý poznatek. S funkci LED WS2812 díky použité funkci, kde destička využívá webový server, na kterém čeká na poslání parametru, je celý systém značně zpomalený a nepřekreslují se tedy diody tak rychle, jak by bylo potřeba. Všechny efekty jsou tak zpomaleny. A hlavně pokud chcete využívat nějaké barevné vlny, tak jde na pásku vidět pomalé překreslování. Nelze tedy využít efekty, které se rychleji překreslují. Tento problém lze vyřešit obvodem SN74HTC245 nebo SN74HTC125. Tyto obvody nicméně nemám, takže toto zapojení nemám vyzkoušeno.
Moblo by Vás zajímat
Jednoduchá vánoční dekorace pomocí ws2812
Vložit komentář
* - vyžadované údaje. RSS kanál s komentáři