Continuando i test con il Neopixel Ring 16led strandtest puoi provare questo esempio di sketch fornito con la libreria Adafruit.
Il Neopixel Ring 16led strandtest consente al tuo anello da 16 led RGB di eseguire una serie di giochi e sequenze luminose.
Come spesso ho scritto il valore dell’analisi linea per linea di esempi scritti da altri è più di natura didattica che funzionale, tuttavia trovo che spesso leggendo sketch scritti da altri possa imparare nuove tecniche per realizzare i progetti con arduino e non solo.
Lo sketch Neopixel Ring 16led strandtest
Lo strandtest è uno degli esempi, come ho scritto sopra, distribuito con la libreria Adafruit_Neopixel per cui puoi trovarlo nel percorso mostrato nell’immagine:
una volta aperto questo è il codice che vedrai:
#include <Adafruit_NeoPixel.h> #ifdef __AVR__ #include <avr/power.h> #endif #define PIN 6 // Parameter 1 = number of pixels in strip // Parameter 2 = Arduino 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(16, PIN, NEO_GRB + NEO_KHZ800); // IMPORTANT: To reduce NeoPixel burnout risk, add 1000 uF capacitor across // pixel power leads, add 300 - 500 Ohm resistor on first pixel's data input // and minimize distance between Arduino and first pixel. Avoid connecting // on a live circuit...if you must, connect GND first. void setup() { // This is for Trinket 5V 16MHz, you can remove these three lines // if you are not using a Trinket #if defined (__AVR_ATtiny85__) if (F_CPU == 16000000) clock_prescale_set(clock_div_1); #endif // End of trinket special code strip.begin(); strip.show(); // Initialize all pixels to 'off' } void loop() { // Some example procedures showing how to display to the pixels: colorWipe(strip.Color(255, 0, 0), 50); // Red colorWipe(strip.Color(0, 255, 0), 50); // Green colorWipe(strip.Color(0, 0, 255), 50); // Blue // Send a theater pixel chase in... theaterChase(strip.Color(127, 127, 127), 50); // White theaterChase(strip.Color(127, 0, 0), 50); // Red theaterChase(strip.Color(0, 0, 127), 50); // Blue rainbow(20); rainbowCycle(20); theaterChaseRainbow(50); } // Fill the dots one after the other with a color void colorWipe(uint32_t c, uint8_t wait) { for(uint16_t i=0; i<strip.numPixels(); i++) { strip.setPixelColor(i, c); strip.show(); delay(wait); } } void rainbow(uint8_t wait) { uint16_t i, j; for(j=0; j<256; j++) { for(i=0; i<strip.numPixels(); i++) { strip.setPixelColor(i, Wheel((i+j) & 255)); } strip.show(); delay(wait); } } // Slightly different, this makes the rainbow equally distributed throughout void rainbowCycle(uint8_t wait) { uint16_t i, j; for(j=0; j<256*5; j++) { // 5 cycles of all colors on wheel for(i=0; i< strip.numPixels(); i++) { strip.setPixelColor(i, Wheel(((i*256/strip.numPixels())+j)&255)); } strip.show(); delay(wait); } } //Theatre-style crawling lights. void theaterChase(uint32_t c, uint8_t wait) { for (int j=0; j<10; j++) { //do 10 cycles of chasing for (int q=0; q < 3; q++) { for (int i=0; i < strip.numPixels(); i=i+3) { strip.setPixelColor(i+q, c); //turn every third pixel on } strip.show(); delay(wait); for (int i=0; i < strip.numPixels(); i=i+3) { strip.setPixelColor(i+q, 0); //turn every third pixel off } } } } //Theatre-style crawling lights with rainbow effect void theaterChaseRainbow(uint8_t wait) { for (int j=0; j < 256; j++) { // cycle all 256 colors in the wheel for (int q=0; q < 3; q++) { for (int i=0; i < strip.numPixels(); i=i+3) { //turn every third pixel on strip.setPixelColor(i+q, Wheel( (i+j) % 255)); } strip.show(); delay(wait); for (int i=0; i < strip.numPixels(); i=i+3) { strip.setPixelColor(i+q, 0); //turn every third pixel off } } } } // Input a value 0 to 255 to get a color value. // The colours are a transition r - g - b - back to r. uint32_t Wheel(byte WheelPos) { WheelPos = 255 - WheelPos; if(WheelPos < 85) { return strip.Color(255 - WheelPos * 3, 0, WheelPos * 3); } if(WheelPos < 170) { WheelPos -= 85; return strip.Color(0, WheelPos * 3, 255 - WheelPos * 3); } WheelPos -= 170; return strip.Color(WheelPos * 3, 255 - WheelPos * 3, 0); }
linee 001-006: includi la libreria e definisci il pin a cui colleghi il Neopixel Ring 16;
linea 015: inizializza l’istanza strip passandole il numero di led presenti nell’anello ( 16 ), il pin ( 6 ) ed i parametri di comunicazione;
linee 025-027: imposti le istruzioni necessarie a impostare il prescale dell’ATtiny 85 a 16MHz;
linee 031-032: invoca i metodi begin() e show() dell’istanza strip in modo da spegnere tutti i led al setup;
linee 037-039: nella fase di loop() richiami solo delle funzioni esterne, in particolare in queste linee richiami la funzione colorWipe() passandole ogni volta un differente colore; prima rosso, poi verde ed infine blu;
linee 041-043: richiami la finzione theaterChase() passandole ogni volta un differente colore; prima bianco, poi rosso ed infine blu;
linea 045: richiami la funzione rainbow() passandole il tempo di 20;
linea 046: richiami la funzione rainbowCycle() passandole il medesimo tempo passato alla funzione rainbow();
linea 047: richiami la funzione theaterChaseRainbow() passandole il valore 50;
Analizza le singole funzioni per comprendere cosa eseguano sui led del Neopixel Ring 16led strandtest:
linee 051-057: funzione colorWipe( colore, tempo ) imposta un ciclo da 0 a 16, il totale dei led presenti sul Neopixel Ring 16 e per ciascun led imposta il colore passato ed attende il tempo definito ( 50 millisecondi );
linee 059-069: funzione rainbow( tempo ) crea un ciclo da 0 a 256 valori e per ciascun valore crea un secondo ciclo annidato da 0 al numero di pixel impostati su cui esegue, per ciascun led, l’impostazione del colore ricavato dalla funzione Wheel() che vedremo in seguito a cui invia il valore del pixel + il valore del ciclo precedente. Infine attiva il colore con il metodo show() e aspetta il tempo passatogli prima di passare al led successivo;
linee 072-082: funzione rainbowCycle( tempo ) crea 5 cicli da 256 valori ( 0-255 ) per ciascuno dei quali imposta tutti i led dell’anello secondo la formula ((i*256/strip.numPixels())+j)&255) passata alla funzione Wheel();
linee 085-100: funzione theaterChase( colore, tempo ) crea un ciclo di 10 valori per ciascuno dei quali imposta un ciclo di 3 in 3 ed imposta il colore al led corrispondente al valore di (q+i). Successivamente attende il tempo definito e crea un ciclo successivo in cui spegne i led impostando il colore a 0;
linee 103-119: funzione theaterChaseRainbow( tempo ) crei un ciclo di 256 valori e per ciascun valore imposti di 3 in 3 il colore del led come definito dalla funzione Wheel() secondo la formula (i+j) % 255). Successivamente all’impostazione del colore attendi il tempo impostato e spegni il medesimo led;
linee 123-134: funzione Wheel( posizione ) è la funzione con la quale hai impostato spesso, nel corso dello sketch, il colore dei led, ecco cosa esegue:
linea 124: calcola il valore di WheelPos come la differenza tra 255 ed il valore inviato;
linea 125-126: se il valore calcolato è inferiore a 85 ritorni il valore RGB, immaginando che sia 84 otterrai
R=(255 – WheelPos * 3) = (255 – 84 * 3 ) = 3
G=0
B=(WheelPos * 3) = ( 84 * 3 ) = 252
corrispondente a blu #0300fc.
Se il valore calcolato è minore di 170 lo riporti a 85 togliendo subito 85 da tale valore e, se il valore è 84, restituisci: R=0 G=252 B=3 corrispondente a #00fc03 ossia un verde;
Infine se il valore non è rientrato in nessuno dei precedenti casi lo riduci ulteriormente di 170, riportandolo nel range con valore massimo 85 e d ipotizzando che il valore dia 84 come nei precedenti casi, passi al led il valore: R=252 G=3 B=0 corrispondente al rosso #fc0300;
Il video
Ecco il video demo del Neopixel Ring 16led strandtest: