AtTiny85 Encoder – Attiny Master

Continuando a fare esperimenti ho provato l’AtTiny85 Encoder delegando all’AtTiny85 la lettira di un encoder rotativo.

Attiny85 Encoder

Gli encoder sono affascinanti e complessi allo stesso tempo oltre che onerosi dal punto di vista dei pin disponibili per il loro controllo da parte di Arduino.

Ho trattato in passato l’argomento encoder rotativi ( puoi leggerlo qui ) per spiegare la teoria con la quale è possibile leggere il valore di rotazione ed il verso.

Come hai letto un aspetto importante nella lettura di un encoder è la necessità di pin di interrupt che come sai sono solo 2 in un arduino / Genuino uno ( pin 2 e 3 ) da cui il limite di poter leggere al massimo un solo encoder.

Sperimentando con l’AtTiny85 Encoder leggerai che è possibile utilizzare questo piccolo microcontrollore per leggere l’encoder ed il pulsante installato in alcune versioni di encoder trasferendo solo il valore ad un arduino o genuino uno connesso  mediante i2c al tuo AtTiny85 Encoder.

Schema dei collegamenti AtTiny85 Encoder

Il primo passo per comprendere come puoi collegare il tuo Attiny85 Encoder è comprendere il pinout dell’Attiny85 stesso:

attiny-pinout

come vedi hai a disposizione 5 pin PB0-PB4 da utilizzare e controllare tramite codice, avrai notato che è presente anche un PB5 con funzione RESET che io ho scelto di utilizzare proprio con questa funzione per cui non è incluso nello schema di collegamento dell’Attiny85 Encoder:

Attiny85 Encoder schema

collega i pin A e B dell’encoder a quadratura ai pin PB3 e PB4 dell’Attiny e lo switch dell’encoder al pin PB1.

Per la connessione I2C tra Attiny85 Encoder e Arduino usa i pin PB0 connesso ad A4 e PB2 ad A5, il resto dovrebbe essere tutto chiaro.

L’encoder che ho utilizzato per questo esperimento è del tipo con cursore trasparente e illuminazione bicolore rosso/verde:

Attiny85 Encoder only

Programmazione dell’Attiny85 Encoder come master

Ho scelto di usare l’Attiny in modalità master ed arduino, o genuino, in modalità slave i2c per semplificare il codice lato arduino in questo esperimento.

Sull’Attiny85 Encoder puoi caricare lo sketch:

/* Tiny85 encoder 
 *
 * pin I2C: SDA = 5 = PB0; SCL = 7 = PB2
 * pin Enc: A = PB3; B =  PB4; Switch = PB1 
 *
 */

#include <TinyWireM.h>
#include "avr/interrupt.h"; 

#define TARGET_ADDR   0x08
#define encA 3
#define encB 4
#define swtc 1

volatile byte currentValue = 0;
volatile int  lastEncoded  = 0;
volatile byte lastValue    = 0;
volatile byte lastSwitch   = 0;


void setup() {
  TinyWireM.begin();

  pinMode(encA, INPUT_PULLUP);
  pinMode(encB, INPUT_PULLUP);
  pinMode(swtc, INPUT_PULLUP);
  digitalWrite(encA, HIGH);
  digitalWrite(encB, HIGH);
 
  GIMSK = 0b00100000;       // Enable pin interrupts
  PCMSK = 0b00011010;       // Enable pin interrupt PB3,PB4,PB1
  sei();                    // Turn on interrupts
}

void loop() {
  byte currentSwitch = digitalRead(swtc);

  if ((lastValue != currentValue)||(lastSwitch != currentSwitch)) {
    TinyWireM.beginTransmission(TARGET_ADDR);
    TinyWireM.send(currentValue);
    TinyWireM.send(currentSwitch);
    TinyWireM.endTransmission();
   
    lastValue  = currentValue;
    lastSwitch = currentSwitch;
  }
  delay(10);
}

ISR(PCINT0_vect) {
  byte MSB = digitalRead(encA); //MSB = most significant bit
  byte LSB = digitalRead(encB); //LSB = least significant bit
  
  int encoded = (MSB << 1) |LSB; //converting the 2 pin 
                                 //value to single number
  int sum  = (lastEncoded << 2) | encoded; //adding it to 
                                           //the previous
                                           //encoded value
 
  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
}

che per la maggior parte del codice è identico a quello che hai già letto nell’articolo dedicato all’encoder con arduino, tuttavia ci sono alcune modifiche che ti evidenzio:

linea 08: includi la libreria TinyWireM.h che permette all’AtTiny85 di diventare Master nella comunicazione I2C

linea 09: includi una libreria nativa avr/interrupt.h dell’Attyny85 e delle istruzioni AVR;

linee 11-14: definisci l’indirizzo I2C della parte Slave a cui l’Attiny85 Encoder deve inviare i valori conteggiati e i pin a cui hai connesso i pin A,B e switch dell’encoder;

linee 16-19: definisci delle variabili che userai per memorizzare i valori ricevuti dall’encoder;

linea 23: inizializza l’istanza Master per l’AtTiny85;

linee 25-29: imposta la modalità PULLUP per i pin a cui è collegato l’encoder e lo switch e poni HIGH le uscite A e B dell’encoder per attivare le resistenze di PULLUP definite;

linea 31: imposta il registro dell’Attiny85 in modo che attivi la modalità di interrupt sui pin che gli indicherai;

linea 32: imposta i pin su cui desideri sia attivato l’interrupt, per farlo usi i codici binari con una maschera in cui il valore 1 indica i pin che devono essere abilitati come interrupts. Nella maschera proposta hai 00011010 corrispondente ai pin PB1,PB3 e PB4

linea 33: richiama la funzione sei() della libreria AVR per impostare l’AtTiny85 con i pin di interrupts come da maschera;

linea 37: definisci la variabile di tipo byte currentSwitch in cui memorizzerai i valori digitali letti sul pin switch ossia PB1;

linea 39: controlla se il valore corrente rilevato dall’encoder o dallo switch sia differente dal valore precedente, in caso di differenze procedi ad inviare il valore variato;

linee 40-43: apri la comunicazione I2C verso l’indirizzo Target definito alla linea 11 e invia un byte (0-255) come valore letto sull’encoder ed un byte per il valore letto sullo switch;

linee 45-46: imposta le variabili di tipo last* con i valori correnti per evitare l’invio di valori identici;

linee 51-65: sono identiche a quanto già descritto nei precedenti articoli dedicati agli encoder e l’unica parte rilevante è data dalle linee 61 e 62 in cui in funzione del verso di rotazione dell’encoder incrementi o decrementi il valore della variabile currentValue che serve al loop() per definire il valore da inviare all’arduino o altro MCU usato come slave.

Nel prossimo articolo leggerai come realizzare e usare un semplice ricevitore I2C con arduino o genuino uno per visualizzare sul monitor seriale i valori ricevuti dall’AtTiny85 encoder i2c.

Il video con AtTiny85 master e Arduino Slave

ecco il video in cui il monitor seriale visualizza i valori provenineti dall’encoder:

Cortesemente, prima di inserire i commenti leggi il regolamento

Permanent link to this article: http://www.mauroalfieri.it/elettronica/attiny85-encoder-attiny-master.html

2 pings

  1. […] corso degli ultimi articoli dedicati all’Attiny85 e l’encoder hai letto come usare quest’ultimo come master ed arduino come […]

  2. […] Attiny85 encoder master […]

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.