arduino
Comunicación I2C
Buscar..
Introducción
I2C es un protocolo de comunicación que puede hacer que dos o más tableros Arduino se comuniquen entre sí. El protocolo utiliza dos pines: SDA (línea de datos) y SCL (línea de reloj). Esos pines son diferentes de un tipo de placa Arduino a otro, así que verifique la especificación de la placa. El protocolo I2C estableció una placa Arduino como maestro y todas las demás como esclavo. Cada esclavo tiene una dirección diferente que el programador configuró de forma rígida. Observación: asegúrese de que todas las tarjetas conectadas a la misma fuente VCC
Esclavos múltiples
El siguiente ejemplo muestra cómo el maestro puede recibir datos de varios esclavos. En este ejemplo el esclavo envía dos números cortos. El primero es para la temperatura, y el segundo es para la humedad. Tenga en cuenta que la temperatura es un flotador (24.3). Para usar solo dos bytes y no cuatro (el flotador es de cuatro bytes), multiplico la temperatura en 10 y lo guardo como un corto. Así que aquí está el código maestro:
#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);
}
}
Y ahora el código esclavo:
#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));
}