Questa pagina mostra come utilizzare il bus I2C in laboratorio dal punto di vista del progettista elettronico; in particolare verranno analizzati i segnali SDA e SCL usando un oscilloscopio digitale; negli esempi è utilizzato un Picoscope 3000A, ma vanno bene anche altri strumenti purché dotati di capacità di decodifica dei segnali seriali I2C. Se non disponete di un un oscilloscopio, trovate alcune forme d'onda esemplificative.
La fotografia di apertura mostra, da destra, un Master I2C (ESP8266), un sensore di pressione e temperatura (BMP280), un sensore di temperatura ed umidità (HTU21D) ed una memoria EEPROM seriale (24LC16).
Prima di proseguire è utile leggere la pagina che descrive il protocollo I2C.
Come Master I2C verrà utilizzato ESP8266 in ambiente Arduino-IDE. Questo microcontrollore gestisce i dispositivi I2C per mezzo della libreria Wire che contiene i metodi di base per leggere e scrivere messaggi generici secondo questo protocollo. Ovviamente sono disponibili anche librerie specializzate che rendono semplice l'uso di una miriade di dispositivi.
In questa pagina verrà usato come slave I2C un sensore di temperatura e pressione piuttosto diffuso: BMP280. Questo sensore è dotato sia di interfaccia SPI che I2C, solo quest'ultima qui descritta. Per utilizzare SPI: Laboratorio SPI.
A causa delle dimensioni molto piccole del sensore è necessario utilizzare una breakout board, un circuito stampato che rende agevole il collegamento alla breadboard e spesso contiene anche componenti di supporto. La fotografia di apertura mostra una possibile realizzazione fisica di una breakout board (il circuito di colore violetto vicino a ESP8266); qui sotto, è mostrato lo schema (nota 3):
L'hardware da realizzare è piuttosto semplice. I collegamenti necessari sono:
Collegare un sensore BMP280 ad un microcontroller ESP8266.
Occorre prestare attenzione al fatto che entrambi questi circuiti integrati funzionano con alimentazione di 3,3 V: tensioni più elevate sono distruttive! Vivamente consigliato procedere alle seguenti operazioni senza l'alimentazione, cioè scollegando il cavo USB da ESP8266:
In genere la prima operazione da fare è quella di individuare gli indirizzi degli Slave I2C connessi al Master. Nella pagina 28 del foglio tecnico è descritto quali sono i possibili indirizzi di BMP280.
É comodo utilizzare lo sketch seguente o uno simile presente nelle librerie; esso scansiona tutti gli indirizzi I2C alla ricerca degli indirizzi degli Slave presenti. La ricerca è fatta iniziando una comunicazione verso ciascuno dei 127 indirizzi possibili, da 0x00 a 0x7F, senza poi trasmettere nulla (nota 1):
#include <Wire.h>
void setup() {
Wire.begin();
Serial.begin(115200);
}
void loop() {
byte error, address;
Serial.println("Scanning...");
for (address = 1; address < 127; address++) {
Wire.beginTransmission(address);
error = Wire.endTransmission();
if (error == 0) {
Serial.print("I2C device found at address 0x");
Serial.println(address, HEX);
}
}
Serial.println("done\n");
delay(1000);
}
L'output tipico potrebbe, per esempio, essere qualcosa di simile alla seguente schermata che mostra la presenza di quattro dispositivi con indirizzo (esadecimale) 0x48, 0x4A, 0x4D e 0x4F:
Durante l'esecuzione dello sketch è possibile osservare con l'oscilloscopio i due segnale SDA e SCL. Se l'oscilloscopio lo consente, è decisamente comodo attivare la decodifica dei segnali I2C: Serial decoding → I2C. Nel diagramma temporale seguente si vede, ad esempio, come l'indirizzo 0x40 è stato riscontrato (ACK = 0, giallo); gli indirizzi 0x41 e 0x42 non sono invece stati riscontrati (ACK = 1, rosso) e quindi non sono presenti dispositivi con tali indirizzi:
Non è certo sufficiente saper che uno Slave esiste e quale è il suo indirizzo! Occorre anche conoscere il tipo di dispositivo. Purtroppo non esiste un metodo standard per avere questa informazione. A volte è necessario leggere il contenuto di uno dei tanti registri dello Slave e da questo risalire al modello; altre volte è necessaria la verifica fisica della sigla del componente.
Nel caso di BMP280 questa informazione è contenuta nel registro "id", come descritta alla pagina 24 del foglio tecnico. Leggiamolo con il seguente codice:
#include <Wire.h>
#define BMP_ADDRESS 0x...
#define ID_REGISTER 0x...
void setup() {
Wire.begin();
Serial.begin(115200);
Serial.println("\nStart");
}
void loop() {
Wire.beginTransmission( BMP_ADDRESS );
Wire.write( ID_REGISTER );
Wire.endTransmission( false );
Wire.requestFrom( BMP_ADDRESS, 1);
int ID = Wire.read();
Serial.print("Chip ID: 0x");
Serial.println(ID,HEX);
delay(1000);
}
La lettura dei valori di temperatura e pressione è piuttosto complessa a causa della presenza all'interno del sensore di numerosi parametri di calibrazione, diversi per ciascun componente.
La procedura dettagliata, tutt'altro che semplice, è descritta nei fogli tecnici di BMP280 (paragrafi 3.11), insieme a numerosi esempi di codice adatti per processori a 8, 32 e 64 bit (paragrafo 3.12 e appendici). Numerose sono le librerie disponibili. Di seguito tre:
Collegare al master un sensore o un altro Slave I2C ed analizzarne il funzionamento con le librerie (se disponibili) e scrivendo il codice con i metodi della libreria wire.
Un esempio. TC74 è un sensore di temperatura con modeste caratteristiche: risoluzione di 1 °C, accuratezza a temperatura ambiente di ± 2 °C.
Questo circuito può utilizzare un solo indirizzo I2C, scelto dal produttore e stampato sul contenitore. La documentazione è riportata al termine del foglio tecnico (nota 4).
Il codice per leggere la temperatura è piuttosto semplice: basta leggere il contenuto del registro 0x00.
Pagina creata nel marzo 2023
Ultima modifica: 20 aprile 2024
Appunti scolastici - Versione 0.1029 - Gennaio 2025
Copyright 2012-2025, Vincenzo Villa (https://www.vincenzov.net)
Creative Commons | Attribution-ShareAlike 4.0 International (CC BY-SA 4.0)