«

»

Ott 23

Stampa Articolo

Rotary encoder attiny85 neopixel

Rotary encoder attiny85 neopixel si distacca dall’utilizzo per cui è nata la rotary encoder attiny85 come hai letto nell’articolo di presentazione.

Rotary encoder attiny85 neopixel light on

puoi utilizzare la board disegnata per leggere i passi di un encoder rotativo via I2C come sistema autonomo in cui hai necessità di leggere l’encoder per controllare ad esempio dei neopixel o un altro output.

Per riuscirci ho utilizzato uno dei due pin destinati all’I2C dell’attiny85 per il controllo dei led WS2812B.

Il pinout dell’attiny85

Leggendo il pinout dell’Attiny85 sai che i pin destinati all’i2c sono il pin 0 ed il pin 2:

ATtiny85 pinout

le cui funzioni sono per il pin 0 quella di poter essere utilizzato come INPUT/OUTPUT digitale e funzione PWM, mentre per il pin 2 la funzionalità di Analog Input 1 ( A1 ).

Potresti utilizzare il pin 0 per controllare, ad esempio la velocità di un motore con l’encoder o la luminosità di una luce o di un faretto Led, con apposito drive, direttamente dalla scheda.

In questo esperimento leggi come realizzare un rotary encoder attiny85 neopixel usando, ad esempio, un neopixel ring 24 led WS2812B adafruit come indicatore.

Come funziona il rotary encoder attiny85 neopixel

l’idea alla base del progetto è di utilizzare l’encoder per accendere un anello di led in funzione della rotazione dell’encoder. 

Ruotando la manopola otterrai l’accensione successiva dei led, partendo dal primo e fino al 24esimo.

Inoltre ho voluto usare la funzione di switch, il pulsante dell’encoder, per cambiare la luminosità dei led, in modo che premendo la manopola dell’encoder e ruotandola contemporaneamente decrementi o incrementi la luminosità di tutti i led accesi.

Da questo semplice esempio potrai facilmente ricavare altri controlli possibili con questa scheda.

Lo schema dei collegamenti rotary encoder attiny85 neopixel

Connettere l’anello da 24 led WS2812B alla rotary encoder attiny85 è semplice in quanto devi collegare solo 3 pin:

Rotary encoder attiny85 neopixel collegamenti

  • +5v
  • Gnd
  • Pin 2 output eopixel

ed alimentare la rotary encoder attiny85 attraverso i pin Vcc e Gnd del connettore ISP attraverso cui esegui la programmazione.

Rotary encoder attiny85 neopixel

Sketch rotary encoder attiny85 neopixel

Lo sketch che puoi utilizzare esegue quanto descritto nella descrizione del funzionamento e per farlo parte dal concetto che hai 256 valori ( 0-255 ) e 24 led da controllare.

Esegui la divisione 255/24 ed arrotonda ad un numero intero .. otterrai 10, che rappresenta il valore che utilizzerai nello sketch per definire il numero di led da accendere.

#include <Adafruit_NeoPixel.h>
#ifdef __AVR__
  #include <avr/power.h>
#endif

#define encA 3
#define encB 4
#define swtc 1
#define PIN  2
#define NUMPIXELS      24

volatile byte currentValue = 0;
volatile int  lastEncoded  = 0;
volatile byte mybrightness = 128;

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

void setup() {
    pinMode(encA, INPUT);
    pinMode(encB, INPUT);
    pinMode(swtc, INPUT);
    digitalWrite(encA, HIGH);
    digitalWrite(encB, HIGH);
   
    GIMSK = 0b00100000;       // Enable pin change interrupts
    PCMSK = 0b00011010;       // Enable pin PB3 and PB4 and PB1
    sei();                    // Turn on interrupts

    pixels.setBrightness(mybrightness);
    pixels.begin();
}
 
void loop() {
    byte numLed = (currentValue*NUMPIXELS/255);
    
    for(int i=0;i<numLed;i++) { 
       pixels.setPixelColor(i, 38,114,184, mybrightness); 
    }
    for(int i=numLed;i<NUMPIXELS;i++) { 
       pixels.setPixelColor(i, 0,0,0, 0); 
    }
    pixels.show();

    if (digitalRead(swtc) == LOW ) { 
       currentValue = setCurrBrightness();  
    }
    delay(20);
}

byte setCurrBrightness() {
  byte oldValue = currentValue;
  currentValue = mybrightness;
  
  while (digitalRead(swtc) == LOW) {
    mybrightness = currentValue;
    pixels.setBrightness(currentValue);
    pixels.show();
  }
  return oldValue;
}

ISR(PCINT0_vect) {
  byte MSB=digitalRead(encA); //MSB=most significant bit
  byte LSB=digitalRead(encB); //LSB=least significant bit
  
  int encoded = (MSB << 1) |LSB;
  int sum  = (lastEncoded << 2) | encoded;
 
  if(sum==0b1101||sum==0b0100||sum==0b0010||sum==0b1011) currentValue++;
  if(sum==0b1110||sum==0b0111||sum==0b0001||sum==0b1000) currentValue--;
  
  lastEncoded = encoded; //store this value for next time
}

la linea 01: includi la libreria neopixel di adafruit per il controllo dei led WS2812B;

linee 02-04: includi la libreria di gestione avr/power.h per la gestione dei chip AVR;

linee 06-09: definisci i pin per la lettura dell’encoder ed il controllo dei led;

linea 10: definisci il numero di led che hai a disposizione per endere lo sketch parametrico;

linee 12-14: definisci le variabili che userai per il conteggio della posizione dell’encoder e la luminosità del led, impostata a 128 in partenza;

linea 16: crea l’istanza pixel della classe Adafruit_NeoPixel;

linee 19-21: definisci le modalità di utilizzo dei pin;

linee 22-23: imposta a 1 ( HIGH ) il valore sui pin a cui è collegato l’encoder;

linee 25-27: servono ad abilitare la funzionalità di interrupt in caso di change sui pin interessati dalla lettura di Enc_A, Enc_B e Switch;

linea 29: imposta la luminosità dei led a 128 ( mybrightness );

linea 30: inizializza la comunicazione con l’anello da 24 led neopixel;

linea 34: calcola il numero di led da accendere in funzione del valore currentValue che viene incrementato dalla funzione di lettura dell’ancoder. Come leggi è un valore calcolato partendo dal valore dell’encoder moltiplicato il numero di pixel che devi controllare e diviso il valore massimo che currentValue può raggiungere;

linee 36-38: per ciascun led, partendo dal led 0 al numero di led che vuoi accendere, imposti il colore e la luminosità usando il metodo setPixelColor;

linea 39-41: al contrario della linea precedente, partendo dal led corrente e procedendo fino al numero massimo di led disponibili NUMPIXELS imposterai il colore a 0, ossia spegni il led;

linea 42: invia i dati ai led usando il metodo show() della libreria neopixel di adafruit;

linee 44-46: se il pulsante dell’encoder viene premuto, il suo valore diventa LOW, e richiami la setCurrBrightness;

linea 50: definisci la funzione setCurrBrightness che restituisce, alla funzione chiamante, al termine delle sue attività, il valore che l’encoder possiede quando viene richiamata;

linea 51: salva nella variabile oldValue il valore che ti servirà al termine di setCurrBrightness per restituirlo alla fine;

linea 52: imposta currentValue come la luminosità corrente, in modo da applicare la rotazione dell’encoder partendo dal valore precedentemente impostato;

linea 54: inizia un ciclo while valido fino a quando lo switch non sarà rilasciato;

linea 55: ad ogni ciclo del while associa a mybrightness il valore corrente currentValue;

linea 56: imposta la luminosità dei led;

linea 57: applica ai led i valori calcolati;

linea 59: al termine del ciclo while, ultimate le regolazioni di luminosità, restituisci alla funzione chiamante il valore salvato in oldValue;

le linee 62-73 riportano la funzione, più volte descritta, relativa alla lettura dell’encoder e la fase di incremento e decremento del currentValue usato in tutto lo sketch;

Il video

Se hai caricato lo sketch rotary encoder attiny85 neopixel  sulla board puoi vedere un effetto simile: 

mandami altre idee da te realizzate con questa board.

Permalink link a questo articolo: http://www.mauroalfieri.it/elettronica/rotary-encoder-attiny85-neopixel.html

1 ping

  1. Rotary encoder attiny85 neopixel color wheel - Mauro Alfieri WS2812B

    […] « Rotary encoder attiny85 neopixel […]

Lascia un commento

Il tuo indirizzo email non sarà pubblicato. I campi obbligatori sono contrassegnati *

Puoi usare i seguenti tag ed attributi HTML: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>