Hrátky s NeoPixel RGB LED páskem
Arduino s NeoPixel jedou v barvách!
Ukažte se, co ve vás je, a vybarvěte svůj Arduino projekt použitím barevného LED pásku! V dnešním článku si ukážeme pár možností využití tohoto barevného LED hada.
Práce s NeoPixel LED pásky je jednoduchá a intuitivní díky dobře zpracovaným knihovnám a nenáročnému zapojení. Po přečtení tohoto článku vám asi bude doma všechno hrát barvami! 🙂
NeoPixel LED pásek s adresovatelnými RGB svítivými diodami je napájený přímo z Arduina pěti volty. Není tak potřeba napětí 12V, jako u běžných LED pásků. Hlavní výhodou řešení s NeoPixel je ale to, že můžete ovládat barvu a jas u každé LED zvlášť a přitom pro připojení potřebujete jen 3 vodiče! Dva vodiče pro napájení pásku a jeden pro data. Pásky můžete navíc spojovat za sebe (vyžaduje pájení) a vytvořit delšího svítícího hada.
Obsah článku:
Co je potřeba, aby to svítilo a blikalo?
- základem je RGB NeoPixel LED pásek
- dále potřebujete Arduino desku, například Arduino UNO Rev3 nebo Arduino MICRO
- Propojení provedete například pomocí Propojovacích vodičů M/M
- Může se hodit také akumulátor pro provoz bez připojení k externímu napájení – Akumulátor Li-Po 3,7V 1800 mAh
- Zapojení doplňte o modul Bluetooth HC-05 / HC-06 pro možnost ovládání z mobilu
ZDE ke stažení
Schéma zapojení
LED pásek připojte k Arduinu na +5V, GND a na Arduino pin č. 6. Můžete připojit také Bluetooth modul HC-06 nebo HC-05 a akumulátor pro mobilní použití – třeba při nošení pod tričkem :).
Pokud se vám nechce hledat, kde co připojit, můžete využít pro připojení RJ25 Adaptér a Arduino desku mCore. Adaptér zajistí pohodlné připojení pásku s možností připojení ještě dalšího pásku. Deska mCore zase umožní jednoduché připojení dalších modulů, například pohybového čidla PIR, snímače zvuku, světelného senzoru apod. Na desce mCore je navíc integrovaný měnič napětí, a tak váš Arduino projekt bude z akumulátoru fungovat i pokud klesne jeho napětí pod 3,5V. Napadá vás, co by se s tím vším dalo vytvořit za projekt? 😉
Vložení knihovny
Stáhněte si a nainstalujte knihovny (Neo_pixel a GFX). Otevřete Arduino IDE – záložka projekt, přidat zip knihovnu a hotovo.
Příklad ovládání z mobilu si ukážeme později. Teď tady mám něco opravdu speciálního!
NeoPixel pásek jako efektní doplněk obrazovky
Tento příklad využití LED pásku ukazuje potenciál propojení s PC a prostředím Processing3. LED pásek v tomto projektu tvoří efektní doplnění monitoru a osvětluje prostor za ním. Rozložení barev je vytvořeno podle toho, co je zrovna na monitoru. Cool!
S využitím prostředí Processing3 jsem vytvořil jednoduchý sketch, který si načte printscreen monitoru a uloží si ho jako image. Poté se používá jen šířka obrazovky a 200 pixelů výšky. Ty se rozdělí na šestnáct stejných okýnek a vypočítá se průměrná hodnota barvy jednoho okýnka v RGB. Ta se uloží do pole pixelcolor [číslo NeoPixel diody][barva 0=červená, 1=zelená, 2=modrá]. Celé pole pixelcolor[][] se odešle po sériové lince do Arduina. To jen načte pixelcolor[][] a pod for() cyklem doplní dle pořadí na výstup k pásku. Stáhni si prostředí Processing 3.
Rychlokurz Processing3 zde:
Processing3 stáhnout:
Nejprve si nainstalujte knihovny, pak nahrajte program do Arduina. Nastartujte Processing3, otevřete program „pasek_za_televizi“ a spusťte. Najděte v programu šestnáctý řádek:
String portName = Serial.list()[ číslo portu ];
V konzoli dole v okně vidíte názvy COM portů a jejich index. Bude vás zajímat index. To je to první číslo v hranaté závorce. Zkontrolujte v Arduino IDE, jaký COM port používá připojené Arduino s již nahraným kódem, u mě je to COM27. V konzoli processingu najdu COM27, podívám se na index, u mě je to [0] a do řádku dám nulu takhle
String portName = Serial.list()[0];
V Arduino IDE nesmíte mít otevřený Sériový monitor, pak Procesing háže chybu Serail port „COM27“ port busy! Oba zdrojové kódy jsou odkomentovány, co která funkce dělá.
Kód pro Arduino s komentářem:
int inByte = 0; // příchozí data #include <Adafruit_NeoPixel.h> //knihovna pro Neopixel #ifdef __AVR__ // ověření co provádí knihovna #include <avr/power.h> #endif int pixelcolor[16][3]; // pole pro číslo LED a její barvu v RGB int i,o,kontakt; // klopné proměnné #define PIN 6 // DIN pin od pásku #define NUMPIXELS 16 // počet LED na pásku // (počet diod, DIN pin, typ barevného schématu + rychlost sběrnice) Adafruit_NeoPixel pixels = Adafruit_NeoPixel(NUMPIXELS, PIN, NEO_GRB + NEO_KHZ800); void setup() { // kontrola v knihovně #if defined (__AVR_ATtiny85__) if (F_CPU == 16000000) clock_prescale_set(clock_div_1); #endif Serial.begin(9600); // start sériového portu s rychlostí 9600 pixels.begin(); // inicializace pásku pixels.setBrightness(150); // nastavení svítivosti pásku 0 až 255 je max establishContact(); // makro pro navázání sériového spojení } void loop() { if (Serial.available() > 45) { // pokud jsou přijatá data rovná počtu 45 hodnot if(Serial.read()==11) // pokud je první hodnota 11 začni ukládat do pole (kontrolní 11 co jsme si poslali z processingu) { pixelcolor[0][0]=Serial.read(); pixelcolor[0][1]=Serial.read(); pixelcolor[0][2]=Serial.read(); pixelcolor[1][0]=Serial.read(); pixelcolor[1][1]=Serial.read(); pixelcolor[1][2]=Serial.read(); pixelcolor[2][0]=Serial.read(); pixelcolor[2][1]=Serial.read(); pixelcolor[2][2]=Serial.read(); pixelcolor[3][0]=Serial.read(); pixelcolor[3][1]=Serial.read(); pixelcolor[3][2]=Serial.read(); pixelcolor[4][0]=Serial.read(); pixelcolor[4][1]=Serial.read(); pixelcolor[4][2]=Serial.read(); pixelcolor[5][0]=Serial.read(); pixelcolor[5][1]=Serial.read(); pixelcolor[5][2]=Serial.read(); pixelcolor[6][0]=Serial.read(); pixelcolor[6][1]=Serial.read(); pixelcolor[6][2]=Serial.read(); pixelcolor[7][0]=Serial.read(); pixelcolor[7][1]=Serial.read(); pixelcolor[7][2]=Serial.read(); pixelcolor[8][0]=Serial.read(); pixelcolor[8][1]=Serial.read(); pixelcolor[8][2]=Serial.read(); pixelcolor[9][0]=Serial.read(); pixelcolor[9][1]=Serial.read(); pixelcolor[9][2]=Serial.read(); pixelcolor[10][0]=Serial.read(); pixelcolor[10][1]=Serial.read(); pixelcolor[10][2]=Serial.read(); pixelcolor[11][0]=Serial.read(); pixelcolor[11][1]=Serial.read(); pixelcolor[11][2]=Serial.read(); pixelcolor[12][0]=Serial.read(); pixelcolor[12][1]=Serial.read(); pixelcolor[12][2]=Serial.read(); pixelcolor[13][0]=Serial.read(); pixelcolor[13][1]=Serial.read(); pixelcolor[13][2]=Serial.read(); pixelcolor[14][0]=Serial.read(); pixelcolor[14][1]=Serial.read(); pixelcolor[14][2]=Serial.read(); } Serial.write( pixelcolor[0][0]); Serial.write( pixelcolor[0][1]); Serial.write( pixelcolor[0][2]); for(int e=0;e<16;e++) // for cyklus pro nastavení čísel diod a hodnotu barvy {// pixels.setPixelColor(číslo diody,červená,zelená,modrá) pixels.setPixelColor(e, pixels.Color(pixelcolor[e][0],pixelcolor[e][1],pixelcolor[e][2])); } pixels.show(); // odeslání do pásku } } void establishContact() { // makro pro navázání kontaktu while (Serial.available() <= 0) { //když nejsou přijatá žádná data Serial.write('A'); // pošli po sériové lince A } }
Kód pro Processing3
import java.awt.*; import processing.serial.*; // nainportování knihoven Serial port; // iniciazizace proměné pro sériovou linku PImage screenshot; // proměnná pro screenshot int R, G,B; // proměnné pro ověření spojení ukládá se hodnota prvního okýnka int[] serialInArray = new int[3]; // proměnná pro načtení COM portů int r,g,b,index,pozicex=0; // proměnné pro vypočet průměrné barvy okýnek int pixelcolor[][]= new int[16][3]; // [počet diod][RGB] pro uložení RGB hodnot Arduinu boolean firstContact = false; // pro ověrění spojení int serialCount = 0; // pro ověrění spojení void setup() { size(640,320); // nastaví okno programu na size(výška, šířka) printArray(Serial.list()); // zobrazí dostupné com porty String portName = Serial.list()[0]; // nastaví COM port, který se bude používat port = new Serial(this, portName, 9600); // nastavení rychlosti komunikace } void draw() { screenshot(); // makro pro vyfocení obrazovky if (screenshot != null) image(screenshot, 0, 0, width, height); //zobrazení vyfocené obrazovky v pozadí loadPixels(); // načtení pixelů pozadí a jejich barvi for (int o=0;o<16;o++) // for cyklus pro vypočítání průměrné hodnoty 16ti okýnek to odpovídá počtu diod na pásku { for(int i=0;i<height;i++) { for(int e=pozicex;e<pozicex+width/16;e++) { r+=(int(red(pixels[i*width+e]))); // uložení průměrné hodnoty barev v jedné diodě g+=(int(green(pixels[i*width+e]))); b+=(int(blue(pixels[i*width+e]))); index++; } pixelcolor[o][0]=r/index; // uložení barvy okýnka/diody pro odeslání po sériové lince pixelcolor[o][1]=g/index; pixelcolor[o][2]=b/index; } pozicex+=width/16; // posunutí výpočtu o další okýnko index=0; r=0; // vynulování dočasné proměnné pro barvy g=0; b=0; } pozicex=0; for(int i=0;i<16;i++) // zobrazení vypočítaných barev na pozadí programu 16 okýnek 50x50 pixelů { fill( pixelcolor[i][0], pixelcolor[i][1], pixelcolor[i][2]); rect(pozicex,0,width/16,50); pozicex+=width/16; } pozicex=0; // vynulování počátečního bodu } void screenshot() { // makro pro zachycení obrázku plochy try { screenshot = new PImage(new Robot().createScreenCapture(new Rectangle(0, 0, displayWidth,200))); } catch (AWTException e) { } } void serialEvent(Serial myPort) { // makro pro sériovou komunikaci int inByte = myPort.read(); // načtení kontaktního symbolu používáme 'A' if (firstContact == false) { if (inByte == 'A') { println("kontakt"); myPort.clear(); // vyčištění bufferu portu firstContact = true; // první kontakt proběhl myPort.write('A'); // dotaz na další } } else { // Přidá nejnovější bajt ze sériového portu do pole: serialInArray[serialCount] = inByte; serialCount++; //když máme 3 bytes: if (serialCount > 2 ) { // Arduino posílá nazpět hodnotu v RGB o prvním okýnku jako ověrění že se přenos povedl R = serialInArray[0]; G = serialInArray[1]; B = serialInArray[2]; // vypíše hodnotu v RGB o prvním okýnku načtenou zpětně z Arduina (pouze ověření spojení); println(R + " \t" +G+ "\t " +B); myPort.write(11); // pošleme číslo 11 aby arduino vědělo, že má začít ukládat proměnné pro pásek for(int i=0;i<15;i++) // for cyklus odesílající 16 hodnot pole, které má 3 podpole R=0 G=1 B=2 { myPort.write(pixelcolor[i][0]); // pošli R myPort.write(pixelcolor[i][1]); // pošli G myPort.write(pixelcolor[i][2]); // pošli B } serialCount = 0; // vynulovaní poroměnné pro další příjem dat } } }
RGB led ovládané ze smartphonu
A nyní si ukážeme slíbené ovládání LED pásku ze smartphonu. Teď už je potřeba připojit Bluetooth přijímač HC-06 nebo HC-05 dle výše uvedeného schématu. Stáhněte si aplikaci „Color Led Controller“, nainstalujte a spárujte se svým Bluetooth přijímačem. Zkopírujte si kód pod videem, vložte do Arduino IDE a nahrajte. Pozor na správné zapojení RX a TX pinů. Je to tak že TX z BT jde na RX Arduina a naopak RX z BT jde na TX Arduina. A tady je výsledek. Teď si můžete nastavit barvy podle svých představ.
Kód pro Arduino programování
#include <Adafruit_NeoPixel.h> // naimportování knihoven #ifdef __AVR__ #include <avr/power.h> #endif #define PIN 6 #include <SoftwareSerial.h> // softwareserial knihovna // (počet diod, DIN pin, pořadí barev, kmitočet) Adafruit_NeoPixel strip = Adafruit_NeoPixel(16, PIN, NEO_GRB + NEO_KHZ800); SoftwareSerial BT(2,3); // port softwareserial na pinech (2RX 3TX) String RGB = ""; //řetězec příjímající data z Bluetooth String RGB_Previous = "255.255.255)"; //řetězec předposledních dat z BT String ON = "ON"; // zapni String OFF = "OFF"; //vypni boolean RGB_Completed = false;// ověření přijímaných dat #define PIN 6 // DIN pin int svetlost=100; // světlost pásku 0-255; void setup() { #if defined (__AVR_ATtiny85__) if (F_CPU == 16000000) clock_prescale_set(clock_div_1); #endif strip.begin(); // start pásku strip.setBrightness(svetlost); BT.begin(9600); // start portu pro BT na 9600 RGB.reserve(30); Serial.begin(9600); // start sériového portu na 9600 } void loop() { while(BT.available()){ //pokud je BT přijal data char ReadChar = (char)BT.read(); // uloží se do ReadChar if(ReadChar == ')'){ // když řetězec obsahuje ")" RGB_Completed = true; // byl přenos dat uspěšný }else{ // pokud ne načte se zpět poslední hodnota RGB += ReadChar; } } if(RGB_Completed){ //vypíše hodnotu RGB Serial.print("RGB:"); Serial.print(RGB); Serial.print(" PreRGB:"); Serial.println(RGB_Previous); if(RGB==ON){ // zapni digitalWrite(13,HIGH); RGB = RGB_Previous; Light_RGB_LED(); }else if(RGB==OFF){ //vypni digitalWrite(13,LOW); RGB = "0.0.0)"; Light_RGB_LED(); }else{ Light_RGB_LED(); RGB_Previous = RGB; } RGB = ""; // reset proměnné pro příjem dat RGB_Completed = false; } } //konec loopu void Light_RGB_LED(){ // dekódování přijatých dat if(RGB.length()>4 && RGB.length()<11) // omezení čtení v rozsahu min a max délky správně načtených dat { RGB_Previous=RGB; int SP1 = RGB.indexOf('.'); //uložení délky indexu pro hodnotu int SP2 = RGB.indexOf('.', SP1+1); //(SP1).(SP2).(SP3) int SP3 = RGB.indexOf('.', SP2+1); // když je RGB 255. 45 . 3 tak SP1=3 SP2=2 a SP3=1 String R = RGB.substring(0, SP1); // převedení na jednotlivé hodnoty RGB String G = RGB.substring(SP1+1, SP2); String B = RGB.substring(SP2+1, SP3); Serial.print("R="); // vypíše samostatné hodnoty v RGB Serial.println( constrain(R.toInt(),0,255)); Serial.print("G="); Serial.println(constrain(G.toInt(),0,255)); Serial.print("B="); Serial.println( constrain(B.toInt(),0,255)); for(int i=0;i<16;i++) // for cyklus pro poslání dat do pásku { // máme 16 diod takže i=16 strip.setPixelColor(i,R.toInt(),G.toInt(),B.toInt()); } strip.show();// inicializace pásku po které začne svítit } }
A to je z dnešního hraní s NeoPixel LED pásky vše. Doufám, že se vám podařilo uvedené příklady zrealizovat a už blikáte. Pokud ne, pište do komentářů a podíváme se na to.
- 1. Arduino.cz Challenge – Dřevorubec - 3.4.2022
- Arduino Bluetooth RC auto - 21.3.2022
- Vytvořte si pro Arduino vlastní appku! - 24.7.2018