2

I'm trying to send the temperature value from the DHT sensor to a raspberry pi through I2C. Which is the best way to do it?. The temp value is a float, and I think I have to convert it to byte and send that with Wire.write() to the raspberry, is that right?. Right now I'm sending bytes from the raspberry (with Python) to the Arduino (C++): Python:

from smbus import SMBus
import time

address = 0x8 bus = SMBus(1)

While True: bus.write_byte(address, 4) time.sleep(1) print(bus.ready_byte(address))

Arduino code:

#include <Wire.h>
#include <DHT.h>
...

void setup() { dht.begin(); Wire.begin(0x8); Wire.onReceive(receiveEvent); }

void receiveEvent () { float temp = dht1.readTemperature(); delay(1000); byte tempByte[4] = {temp, 0, 0, 0}; Wire.write(tempByte[0]); }

So the raspberry is printing 0.

Thanks for any help.

Guille
  • 123
  • 3

1 Answers1

5

First of all, if you want the Arduino to send data as a slave, it should do so onRequest(), not onReceive(). Thus:

void setup() {
    Wire.begin(0x08);
    Wire.onRequest(handleRequest);
}

Next, as pointed out by chrisl in a comment, you should not delay within the onRequest handler. I would go further and say that you should not even call dht1.readTemperature(), as that could take too much time to be done in interrupt context. Instead, have the main loop query the sensor periodically, and have the latest reading always available:

volatile float temperature;  // latest valid reading

void loop() { float new_temperature = dht1.readTemperature(); noInterrupts(); temperature = new_temperature; interrupts(); // ... }

Note that the latest value is updated with interrupts disabled. This is to avoid a data race that could happen if the Arduino receives a request while it is in the middle of updating the value. Notice also that interrupts are disabled during a very short time: just the time needed to update the variable.

Lastly, to send the data, you can use the version of Wire.write() that accepts a buffer of arbitrary length:

void handleRequest() {
    Wire.write((uint8_t *) &temperature, sizeof temperature);
}

The temperature will be sent LSB-first, as a float, formatted as per IEEE 754. The Raspberry Pi should be able to digest it in this very same format.

Edgar Bonet
  • 45,094
  • 4
  • 42
  • 81