I want to communicate to an ARM microprocessor via I2C protocol (Multitech mDot, which uses Mbed platform). I successfully receive data from it (and got it displayed on Arduino's serial monitor), but when I want to send data from the Arduino I don't receive nothing on the other end. This is my sketch:
#include <DHT.h>
#include <Wire.h>
// Sensor temperatura, humedad DHT11 (test).
#define DHTPIN 10
#define DHTTYPE DHT11
DHT dht(DHTPIN, DHTTYPE);
// Comunicacion i2c con nodo lora. 7bitaddress 010 1001 (r/w)
#define SLAVE_ADDRESS 0x29
// Variables globales de sensores
float h;
float t;
void setup() {
Wire.begin(SLAVE_ADDRESS);
Wire.onReceive(receiveEvent);
dht.begin();
Serial.begin(9600);
}
void loop() {
delay(5000);
h = dht.readHumidity();
t = dht.readTemperature();
// Comprobamos si ha habido algún error en la lectura
if (isnan(h) || isnan(t)) {
Serial.println("Error obteniendo los datos del sensor DHT11");
return;
}
Serial.print("Humedad: ");
Serial.print(h);
Serial.print(" %\t");
Serial.print("Temperatura: ");
Serial.print(t);
Serial.println(" *C ");
Wire.onReceive(receiveEvent);
}
// Total de bytes del arreglo de datos a transmitir: 28 bytes.
void receiveEvent(int howMany) {
Serial.print("Mensaje recibido por i2c desde MDOT LoRa Node: ");
while (Wire.available() > 0) {
Serial.print(char(Wire.read()));
}
Serial.println();
char enviar = "Cacatua";
Wire.write(enviar);
return;
}
I wanted to know if this schematic is correct and if the wire write as it is written is performed. If so, I will need to see what is wrong with the code on my ARM device.
1 Answer 1
It is important to understand, that Wire.write()
will not actually send data over the I2C bus. It will only put the data bytes into the send buffer of the library.
The normal way of the Wire
library to send data as a slave is to implement the onRequest
callback function. It will be called from an I2C ISR when a master on the I2C bus requests data from this slave. In the callback, you use Wire.write()
to fill the buffer with data, which then get's send out to the master.
I'm not quite sure about the following: My guess regarding your previous code is, that the Wire
library clears the send buffer at some time during the send or read code. That would mean, that the data written in the onReceive
callback will simply be lost, instead of used for transmission of requested data. That might be meant that way, so that the users will stick to implementing the onRequest
callback, which is the correct way of doing it.
Note: In your code, you call Wire.onReceive(receiveEvent)
on every void loop()
iteration. That isn't necessary. The Wire.onReceive()
method only set's a function pointer to the callback function. It does NOT execute this callback function, which only will be called by the corresponding I2C ISR, when data is actually received. You should use this line only once in setup()
to setup the callback function. Though using it multiple times does not break things here. It's just useless.
onRequest
callback function and trigger an LED there, so that you can check, if the request is actually reaching the Arduino