RGB WS2812 serial arduino

RGB WS2812 serial arduino è il progetto complementare alla realizzazione di una interfaccia seriale di controllo RGB

RGB WS2812 serial arduino led vert

Se hai letto il precedente articolo ti sarai chiesto a che scopo dovresti realizzare una interfaccia RGB in processing in grado di inviare in seriale i dati in una stringa RGB.

Questo articolo è un esempio di utilizzo di quella interfaccia applicata ad Arduino uno.

Come funziona RGB WS2812 serial arduino

RGB WS2812 serial arduino è uno sketch che puoi caricare su Arduino Uno per controllare una striscia di led neopixel WS2812B.

Quando modifichi il valore di una delle tre componenti RGB sull’interfaccia:

Processing RGB interface serial Neopixel processing

lo sketch processing invia sulla porta seriale il valore delle tre componenti impostate.

Per comodità tutte le tre componenti sono inviate anche se a cambiare è solo una delle tre.

In modo specifico l’idea è di non limitare l’uso dello sketch arduino, che trovi sotto, all’uso con la sola interfaccia mostrata; in altri ambienti o situazioni potrebbero cambiare tutte le componenti allo stesso tempo.

Il video

Puoi vedere un breve video sul funzionamento del progetto RGB WS2812 serial arduino di seguito:

prima di leggere lo sketch ti sarà utile per comprendere meglio i passaggi dello sketch stesso.

Schema di collegamento

Lo schema di collegamento della striscia di led di tipo neopixel è molto semplice in quanto necessiti di soli 3 pin:

  • +5v alimentazione positiva prelevata da Arduino;
  • Gnd o terra o massa, necessariamente connessa ad Arduino;
  • pin digitale, nell’esempio il pin 2, connesso all’arduino per il segnale da inviare ai WS2812B

ed il collegamento lo puoi eseguire così lato Arduino:

RGB Neopixel serial processing ws2812 arduino wire

mentre alla striscia di led dovrai connettere in ordine dall’alto il Gnd, il signal ed infine il +5v:

RGB WS2812 serial arduino led

Non ci sono altri collegamenti da rispettare a meno del cavo USB che userai sia per la comunicazione seriale verso il computer sia per alimentare Arduino ed i led.

Lo sketch del progetto

Lo sketch del progetto RGB WS2812 serial arduino ti richiede le conoscenze di base della comunicazione seriale tra Arduino ed un client, in questo esempio, processing.

Dopo aver collegato Arduino al computer potrai caricare lo sketch:

#include <Adafruit_NeoPixel.h>

#define PIN            2
#define NUMPIXELS      27

byte rgb[3]    = {127,127,127};
byte oldrgb[3] = {127,127,127};

String inputString  = "";
bool stringComplete = false;

Adafruit_NeoPixel pixels = Adafruit_NeoPixel(NUMPIXELS, PIN, NEO_GRB + NEO_KHZ800);

void setup() {
  Serial.begin(115200);

  pixels.begin();
  for(int i=0;i<NUMPIXELS;i++){
    pixels.setPixelColor(i, pixels.Color(255,255,255));
    pixels.show();
    delay(5);
  }
  for(int i=0;i<NUMPIXELS;i++){
    pixels.setPixelColor(i, pixels.Color(0,0,0));
    pixels.show();
    delay(10);
  }
}
 
void loop() {

  while (Serial.available()) {
    // get the new byte:
    char inChar = (char)Serial.read();
    inputString += inChar;
    if (inChar == '\n') {
      stringComplete = true;
      Serial.println(inputString);
    }
  }
  
  if (stringComplete) {
    inputString = getRGB( inputString," ",0 );
    inputString = getRGB( inputString," ",1 );
    inputString = getRGB( inputString," ",2 ); 

    inputString = "";
    stringComplete = false;
  }
  
  if ( (rgb[0] != oldrgb[0]) || (rgb[1] != oldrgb[1]) || (rgb[2] != oldrgb[2]) ) {
    oldrgb[0] = rgb[0];
    oldrgb[1] = rgb[1];
    oldrgb[2] = rgb[2];

    for(int i=0;i<NUMPIXELS;i++){
      pixels.setPixelColor(i, pixels.Color(rgb[0],rgb[1],rgb[2]));
      pixels.show();
      delay(20);
    }
  }
}

String getRGB( String input, String sep, byte rgbIndex ) { 
   byte i = input.indexOf(sep);
   if ( i > 0 ) {
       rgb[rgbIndex] = input.substring(0,i).toInt();
       return input.substring(i+1);
    }
}

iniziando dalle prime linee includi la libreria Adafruit Neopixel e definisci il pin 2 per la comunicazione con la striscia led di 27 led, nel mio esempio.

Se tu hai a disposizione una striscia led con un numero maggiore o inferiore di led, ricordati di modificare tale valore alla linea 04;

linee 06-07: definisci due array di tipo byte, ciascuno di 3 elementi, che userai come valori di default all’avvio dello sketch, se ricordi avevi il medesimo valore di start anche lato processing:

Processing RGB interface serial

in questo modo entrambe le componenti condividono il medesimo valore di start;

linee 09-10: definisci due variabili la prima, di tipo String, in cui memorizzerai la stringa ricevuta e la seconda, booleana, usata come valore di controllo alla ricezione della stringa completa;

linea 12: inizializza l’istanza di controllo dei led WS2812B;

linee 17-27: iniziano la comunicazione con la striscia led ed eseguono due semplici sequenze, la prima di accensione di tutti i led e la seconda di spegnimento degli stessi per accertarti che all’avvio del progetto i led stiano funzionando;

linea 32: crea un ciclo while all’interno della loop() che resta attivo fino a quando esistono dei valori nel buffer seriale. In pratica se non hai ricevuto alcun valore seriale, il buffer di quest’ultimo resta vuoto ed il ciclo while non esegue nulla, appena ricavi un valore attraverso la seriale il buffer acquisisce tale valore, o multipli se una stringa, ed il ciclo while esegue le istruzioni in esso contenute;

linea 34: il metodo read() legge un valore alla volta dal buffer seriale e lo elimina dallo stesso svuotandolo, in questa linea assegni alla inChar ogni singolo valore letto nel buffer allo scorrere del while;

la linea 35: memorizza nella variabile inputString i valori letti in modo sequenziale;

linee 36-39: controlla mediante if che il valore di inChar sia un valore di newline (\n) ed in tal caso poni a true il valore di stringComplete e scrivi sul monitor seriale la tringa ricevuta in inputString;

linea 42: se il valore di stringComplete è true;

linee 43-45: richiami la funzione getRGB() passandole come parametri:

  • la stringa di input
  • il valore di separazione da usare
  • l’indice di posizione dell’array rgb[] in cui vuoi che sia inserito tale valore

linea 47: ripulisci la stringa inputString;

linea 48: imposta la variabile booleana di controllo a false, per indicare che inputString è nuovamente pulita e dovrà essere riempita prima di poter essere nuovamente letta;

linea 51: confronta i valori correnti presenti nell’array rgb[] con quelli presenti nell’array oldrgb[] alla ricerca di un cambiamento, anche si un solo valore;

linee 52-54: reimposta i valori dell’oldrgb[] array ai valori correnti;

linee 56-60: esegui un ciclo sul numero completo di led a tua disposizione e per ciascuno imposta il colore RGB appena ricevuto.

linea 64: definisci la funzione getRGB che hai già visto richiamare alle linee 43-45, in mod che accetti i tre parametri elencati sopra e restituisca una stringa;

linea 65: nella variabile “i” inserisci la posizione numerica del primo carattere di separazione che hai trovato all’interno della stringa di input.

linee 66-69: valuta che il valore di “i” sia maggiore di 0, ossia che sia presente almeno una volta il carattere separatore passato alla funzione nella stringa da valutare. In funzione di tale posizione estrai il valore numerico corrispondente con il metodo substr e convertilo in un valore di tipo intero toInt() memorizzandolo nell’array rgb[] all’indice passato come terzo valore della stringa. La linea 68, infine, restituisce alla funzione chiamante ( loop() ) la parte della stringa decurtata del valore appena estratto.

Comprendi che senza una buona conoscenza della gestione del protocollo seriale e di come siano gestite le stringhe di questo tipo da parte di arduino risulta difficile comprendere fino in fondo il funzionamento dello sketch.

Tuttavia chiariti i concetti principali la lettura del programma dovrebbe risultarti alquanto scorrevole e di facile comprensione.

Prima di inserire un commento, per favore, leggi il regolamento

Permanent link to this article: http://www.mauroalfieri.it/elettronica/rgb-ws2812-serial-arduino.html

2 comments

    • zoomx on 29 Gennaio 2019 at 22:36
    • Reply

    Un solo led WS2812B consuma circa 52.5 mA che moltiplicato 27 fa 1417.5 mA, la linea a 5 V di Arduino è assolutamente insufficiente. I led vanno alimentati a parte.

    1. Zoomx hai ragione, per il primo test ed esperimento puoi usare la linea Arduino ma suggerisco anche io di usare una alimentazione esterna se il progetto deve funzionare stabilmente.
      Inoltre consiglio di porre in parallelo un condensatore da almeno 470uF 10v o superiore, come consigliato dal sito Adafruit.

Lascia un commento

Your email address will not be published.

Questo sito usa Akismet per ridurre lo spam. Scopri come i tuoi dati vengono elaborati.