arduino
Comunicazione I2C
Ricerca…
introduzione
I2C è un protocollo di comunicazione che può far dialogare due o più schede Arduino. Il protocollo utilizza due pin: SDA (linea dati) e SCL (linea orologio). Questi pin sono diversi da un tipo di scheda Arduino a un altro, quindi controlla le specifiche della scheda. Il protocollo I2C impostava una scheda Arduino come master e tutte le altre come slave. Ogni slave ha un indirizzo diverso che il programmatore ha impostato con hard-coded. Nota: assicurarsi che tutte le schede siano collegate alla stessa sorgente VCC
Schiavi multipli
L'esempio seguente mostra come il master può ricevere dati da più slave. In questo esempio lo slave invia due numeri brevi. Il primo è per la temperatura e il secondo per l'umidità. Si prega di notare che la temperatura è un galleggiante (24.3). Per utilizzare solo due byte e non quattro (float è quattro byte), ho più volte la temperatura in 10, e lo salvo come un breve. Quindi ecco il codice principale:
#include <Wire.h>
#define BUFFER_SIZE 4
#define MAX_NUMBER_OF_SLAVES 24
#define FIRST_SLAVE_ADDRESS 1
#define READ_CYCLE_DELAY 1000
byte buffer[BUFFER_SIZE];
void setup()
{
Serial.begin(9600);
Serial.println("MASTER READER");
Serial.println("*************");
Wire.begin(); // Activate I2C link
}
void loop()
{
for (int slaveAddress = FIRST_SLAVE_ADDRESS;
slaveAddress <= MAX_NUMBER_OF_SLAVES;
slaveAddress++)
{
Wire.requestFrom(slaveAddress, BUFFER_SIZE); // request data from the slave
if(Wire.available() == BUFFER_SIZE)
{ // if the available data size is same as I'm expecting
// Reads the buffer the slave sent
for (int i = 0; i < BUFFER_SIZE; i++)
{
buffer[i] = Wire.read(); // gets the data
}
// Parse the buffer
// In order to convert the incoming bytes info short, I use union
union short_tag {
byte b[2];
short val;
} short_cast;
// Parse the temperature
short_cast.b[0] = buffer[0];
short_cast.b[1] = buffer[1];
float temperature = ((float)(short_cast.val)) / 10;
// Parse the moisture
short_cast.b[0] = buffer[2];
short_cast.b[1] = buffer[3];
short moisture = short_cast.val;
// Prints the income data
Serial.print("Slave address ");
Serial.print(slaveAddress);
Serial.print(": Temprature = ");
Serial.print(temprature);
Serial.print("; Moisture = ");
Serial.println(moisture);
}
}
Serial.println("*************************");
delay(READ_CYCLE_DELAY);
}
}
E ora il codice slave:
#include <Wire.h>
#include <OneWire.h>
#include <DallasTemperature.h>
//=====================
// This is the hard-coded address. Change it from one device to another
#define SLAVE_ADDRESS 1
//=====================
// I2C Variables
#define BUFFER_SIZE 2
#define READ_CYCLE_DELAY 1000
short data[BUFFER_SIZE];
// Temprature Variables
OneWire oneWire(8);
DallasTemperature temperatureSensors(&oneWire);
float m_temperature;
// Moisture Variables
short m_moisture;
// General Variables
int m_timestamp;
void setup()
{
Serial.begin(9600);
Serial.println("SLAVE SENDER");
Serial.print("Node address: ");
Serial.println(SLAVE_ADDRESS);
Serial.print("Buffer size: ");
Serial.println(BUFFER_SIZE * sizeof(short));
Serial.println("***********************");
m_timestamp = millis();
Wire.begin(NODE_ADDRESS); // Activate I2C network
Wire.onRequest(requestEvent); // Set the request event handler
temperatureSensors.begin();
}
void loop()
{
if(millis() - m_timestamp < READ_CYCLE_DELAY) return;
// Reads the temperature
temperatureSensors.requestTemperatures();
m_temperature = temperatureSensors.getTempCByIndex(0);
// Reads the moisture
m_moisture = analogRead(A0);
}
void requestEvent()
{
data[0] = m_temperature * 10; // In order to use short, I multiple by 10
data[1] = m_moisture;
Wire.write((byte*)data, BUFFER_SIZE * sizeof(short));
}