MCP9803 leggere i registri del sensore di temperatura
Continuiamo gli articoli sul bus I2C, utilizzando sempre il nostro amato sensore di temperatura MCP9803. Questa volta ho utilizzato il Netduino per ‘colloquiare’ con il sensore per fare un po di ‘pratica’ con le varie classi esposte dal .Net micro framework che permettono di utilizzare il bus I2C.
Devo dire che con MikroC ho un controllo maggiore (giustamente) sulla comunicazione con il sensore. L’esperienza con Netduino invece mi ha lasciato un po perplesso, forse è una mia impressione ma avrei preferito un codice più snello, forse più a basso livello.
Lo schema elettrico che ho creato per questa esperienza è il seguente:
Anche in questo caso i pin A0 A1 A2 servono per personalizzare l’indirizzo del sensore. Il pin1(SDA) del sensore è collegato al pin4(SDA) del Netduino. Il pin2(SCLK) del sensore è collegato al pin5(SCL) del Netduino.
Il circuito invia i dati al pc utilizzando la porta seriale. Lo schema per la comunicazione seriale è quello utilizzato negli esperimenti precedenti.
Il codice seguente riassume tutte le fasi necessarie per leggere il valore della temperatura dal Temperature Register del sensore MCP9803.
using System; using System.Threading; using Microsoft.SPOT; using Microsoft.SPOT.Hardware; using SecretLabs.NETMF.Hardware; using SecretLabs.NETMF.Hardware.Netduino; using System.IO.Ports; using System.Text; namespace NetduinoApplication1 { public class Program { public static void Main() { Byte[] tx = new Byte[1]; Byte[] rx = new Byte[2]; SerialPort UART1 = new SerialPort("COM1", 9600, Parity.None, 8, StopBits.One); //apro la porta seriale UART1.Open(); //Configurazione contenente l'indirizzo del sensore e la frequenza //di del bus i2c I2CDevice.Configuration cnf = new I2CDevice.Configuration(0x48, 400); //Creo un oggetto per eseguire le richieste di lettura e scrittura I2CDevice sensore = new I2CDevice(cnf); //creo un oggetto I2CReadTransaction che viene associato al buffere rx I2CDevice.I2CReadTransaction[] rd = new I2CDevice.I2CReadTransaction[] {I2CDevice.CreateReadTransaction(rx)}; //creo un oggetto I2CWriteTransaction che viene associato al buffere tx I2CDevice.I2CWriteTransaction[] wr = new I2CDevice.I2CWriteTransaction[] {I2CDevice.CreateWriteTransaction(tx)}; //Ciclo infinito while (true) { //eseguo una richiesta di lettura sensore.Execute(rd, 100); //invio i dati sulla seriale UART1.Write(rx, 0, rx.Length); //attendo 2 secondi Thread.Sleep(2000); } UART1.Close(); } } }
L’esempio è molto sintetico e tutto il codice ruota attorno alla classe I2CDevice.
Per utilizzare il modulo I2C del Netduino dobbiamo prima creare un oggetto di configurazione tramite la classe I2CDevice.Configuration. I parametri da passare al costruttore sono due, uno riguarda l’indirizzo del sensore (ottenuto con i 4 bit fissi preimpostati dalla casa costruttrice e i tre scelti dall’utente, A0 A1 A2, che nel nostro caso sono 1001 + 000 = 1001000 = 0x48 in esadecimale) e l’altro la frequenza di clock del segnale SCL (che stabilisce la velocità di comunicazione) impostato a 400Khz.
Ora creo un oggetto I2CDevice necessario per eseguire le richieste di lettura e scrittura sul bus I2C. Il costruttore richiede come parametro l’oggetto I2CDevice.Configuration (nel nostro caso l’oggetto cnf creato precedentemente).
Per leggere e scrivere dal bus I2C dobbiamo creare due oggetti I2CTransaction, il primo associa al comando di lettura il buffer dove verranno contenuti i byte letti dal sensore, il secondo associa al comando di scrittura il buffer dove sono contenuti i dati da inviare al sensore.
Netduino esegue ciclicamente (ciclo while) il metodo Execute relativo all’oggetto sensore. I parametri da passare al metodo sono l’oggetto I2CTransaction (che può essere quello di lettura o scrittura) e il tempo di timeout della richiesta.
Nell0 specifico il comando sensore.Execute(rd, 100); esegue una lettura sul bus I2C, l’oggetto rd permette di scrivere i dati letti dal sensore nel buffer rx.
Infine Netduino invia sulla seriale i byte relativi al registro di temperatura del sensore MCP9803.
Il .net micro framework rende semplice l’uso del bus I2C occupandosi di impostare il bit per la lettura/scrittura e per la gestione degli acknowledgee.
In pratica ci dobbiamo solo occupare di specificare l’indirizzo del sensore e la grandezza dei buffer di lettura e scrittura.
Come sempre suggerimenti e critiche sono sempre graditi.
Byte[] rx = new Byte[2];SerialPort UART1 = new SerialPort(“COM1”, 9600, Parity.None,
8, StopBits.One);
UART1.Open();// Create a new I2C bus instance at startup.
I2CDevice.Configuration cnf = new I2CDevice.Configuration(0x48, 400);
I2CDevice sensore = new I2CDevice(cnf);
I2CDevice.I2CReadTransaction[] rd = new I2CDevice.I2CReadTransaction[] {I2CDevice.CreateReadTransaction(rx)};
I2CDevice.I2CWriteTransaction[] wr = new I2CDevice.I2CWriteTransaction[] {I2CDevice.CreateWriteTransaction(tx)};while (true)
{
sensore.Execute(rd, 100);
UART1.Write(rx, 0, rx.Length);Thread.Sleep(2000);
}UART1.Close();