Impara ad usare l’I2C Attiny85 slave ADC ossia il micro controllore della famiglia Atmel a 8 pin per leggere un segnale analogico ( ADC ) e trasferirlo via I2C.
L’Attiny85 è uno dei micro controllori della famiglia Atmel a cui appartiene anche l’Atmega328, su cui si basa sia Arduino sia Genuino Uno.
In particolare si tratta di un AVR Core, programmabile con l’IDE Arduino, in modaliltà programmatore ISP.
Già in passato ho dedicato alcuni articoli alla programmazione dell’Attiny85 che ti segnalo come approfondimento sull’argomento:
- Attiny85 Program – prima puntata
- Attiny85 Program – seconda puntata
- Attiny85 Program – terza puntata
la programmazione puoi eseguirla attraverso l’Arduino Uno ed i collegamenti sui pin 13,12,11,10.
L’invio dello sketch “Arduino ISP” sulla scheda Arduino è necessario per consentirti di utilizzarla come programmatore.
Connessioni per I2C Attiny85 slave ADC
In questo esperimento l’Attiny85 lo userai in modalità slave i2c ( o iic ) per raccogliere le informazioni relativi e ad un sensore analogico, un potenziometro, e trasferirle ad una arduino uno:
e quest’ultimo li invierà al monitor seriale perchè li possa leggere.
Lo schema di collegamento dell’I2C Attiny85 slave ADC è il seguente:
i cui oltre all’alimentazione tra Arduino Uno e Attiny85 ci sono solo i collegamenti I2C: SDA ed SCL.
Il potenziometro è collegato al pin 2 ( fisico ) dell’ATtiny85 che corrisponde al pin A3 o ADC3 da datasheet:
Ecco come appaiono i collegamenti nell’esempio che ho costruito per testare lo sketch:
e lato Arduino Uno:
Sketch I2C Attiny85 slave
Lo sketchI2C Attiny85 slave ADC che per primo dovrai caricare sull’Attiny85 in quanto la medesima board arduino la userai, probabilmente prima come programmatore ISP e successivamente come Master del progetto per leggere i valori dall’IIC e trasferirli al monitor seriale.
Il codice della componente I2C Attiny85 slave ADC è:
// Code for the ATtiny85 #define I2C_SLAVE_ADDRESS 0x8 // Address of the slave #include <TinyWireS.h> #define ADC3 A3 void setup() { TinyWireS.begin(I2C_SLAVE_ADDRESS); // join i2c network TinyWireS.onRequest(requestEvent); pinMode(ADC3, INPUT_PULLUP); } void loop() { // This needs to be here TinyWireS_stop_check(); } // Gets called when the ATtiny receives an i2c request void requestEvent() { int val=analogRead(ADC3); byte valLow = val & 0xff; byte valHigh = (val >> 8); TinyWireS.send(valHigh); TinyWireS.send(valLow); }
in cui avrai di certo già individuato le parti fondamentali:
linea 02: definisci l’indirizzo IIC su cui dovrà rispondere lo slave;
linea 04: includi la libreria TinyWireS ossia la libreria Wire scritta per gli Attiny nella sua componente S ( Slave );
linee 09-10: inizializza la classe TinyWireS con il metodo begin in modo che il micro controllore conosca l’indirizzo su cui rispondere al Master e imposta lo sketch in modo che ad ogni richiesta da parte di quest’ultimo venga richiamata la funzione requestEvent;
linea 12: imposta il pin A3 ( ADC3 ) come INPUT_PULLUP ossia attivando la resistenza interna di pull-up anche se non necessario con un potenziometro, come sai;
linea 17: ad ogni ciclo di loop reimposta lo stop del check;
linea 21: definisci la funzione requestEvent;
linea 22: acquisici il valore analogico letto sul pin A3 e inserisci il risultato in una variabile di tipo int;
linee 23-24: poichè il valore acquisito è di tipo integer ed il metodo send della Wire ( anche della TinyWireS ) lavora con variabili di tipo byte, ossia invia un byte alla volta, dovrai scomporre il valore intero in byte. Leggendo nella doccumentazione arduino.cc trovi che una variabile di tipo int è composta da due byte per cui la conversione è fatta estraendo gli 8 bit meno significativi ( Low ) con ua maschera 0xFF in & ( And ) per cui se il valore fosse ad esempio 325:
0000 0001 0100 0101 in & con
0000 0000 1111 1111 avrebbe come risultato:
0000 0000 0100 0101 ossia 69
questo valore lo assegni alla variabile valLow. Il secondo byte sarà quindi dato dagli 8 bit più significativi per cui puoi recuperarlo facendo shiftare verso destra di 8 posizioni il valore letto usando l’operazione bitwise >> da cui sempre con il valore 325:
0000 0001 0100 0101 shift 8 bit 0000 0000 0000 0001 ossia 1
che assegni alla variabile valHigh.
linee 25-26: invia prima i bit più significativi e successivamente quelli meno significativi;
Puoi consultare la Reference Guide sulle funzioni Bitwise:
Il risultato, che potrai leggere sul monitor seriale dopo aver trasferito su arduino la parte Master del I2C Attiny85 slave ADC, sarà simile al seguente:
e ruotando il potenziometro verso il +5v:
Nel prossimo articolo analizzeremo la parte Master e la ricomposizione delle variabili byte 2 int.
6 commenti
1 ping
Vai al modulo dei commenti
Ho provato il tuo circuito master slave ma il master legge sempre 255 in entrambi i bytes. Ho provato ad inviare l’intero 69 invece di leggerlo da ADC ma risponde sempre 255.
Autore
Ciao Luca,
prova a inviare un numero inferiore a 255 ( es: 69 come hai fatto ) ma in un unica variabile senza translazioni di bit.
Salve,
Se compilo lo sketch “I2C Attiny85 slave ADC” mi da un errore con l’istruzione “TinyWireS.send()”, non la riconosce.
Ho verificato nella libreria che esiste il comando “TinyWireS.write()”, ho provato a sotituirlo ma mi da un errore:
/Users/ezio/Documents/Arduino/libraries/TinyWireS-master/TinyWireS.cpp: In function ‘void TinyWireS_stop_check()’:
/Users/ezio/Documents/Arduino/libraries/TinyWireS-master/TinyWireS.cpp:71:11: error: ‘USISR’ was not declared in this scope
if (!(USISR & (1 << USIPF))) return; // Stop not detected
^~~~~
/Users/ezio/Documents/Arduino/libraries/TinyWireS-master/TinyWireS.cpp:71:11: note: suggested alternative: 'SPSR'
if (!(USISR & (1 << USIPF))) return; // Stop not detected
^~~~~
SPSR
/Users/ezio/Documents/Arduino/libraries/TinyWireS-master/TinyWireS.cpp:71:25: error: 'USIPF' was not declared in this scope
if (!(USISR & (1 << USIPF))) return; // Stop not detected
^~~~~
Non so cosa fare.
Saluti
EzioGi
Autore
Ciao Ezio,
nella libreria che ho utilizzato esiste il metodo TinyWireS.send(), se nella tua libreria non ci fosse puoi sostituirlo controllando quali modifiche dovrai eseguire nel codice per adattarlo.
Ho provato a compilare il tuo sketch ma mi da questo errore:
Arduino:1.8.13 (Mac OS X), Scheda:”ATtiny25/45/85 (No bootloader), Disabled, CPU (CPU frequency), ATtiny85, 8 MHz (internal), EEPROM retained, B.O.D. Disabled (saves power), Enabled”
Attiny85slaveADC:25:15: error: ‘class USI_TWI_S’ has no member named ‘send’; did you mean ‘read’?
TinyWireS.send(valHigh);
^~~~
read
Attiny85slaveADC:26:15: error: ‘class USI_TWI_S’ has no member named ‘send’; did you mean ‘read’?
TinyWireS.send(valLow);
^~~~
read
exit status 1
‘class USI_TWI_S’ has no member named ‘send’; did you mean ‘read’?
La libreria TinyWireS_S è installata correttamente.
Saluti
Autore
Ciao Ezio,
la mia libreria è TinyWireS senza la “_S” aggiuntiva che hai indicato.
[…] I2C attiny85 slave ADC […]