Raspberry Pi3 + Arduino UNO + DHT22 over I2C (test environment)

Hi! I would like to test the RPi3 + Arduino UNO + DHT22 over I2C communication: RPi3 send a request to Arduino. Arduino use the DHT22 sensor (temp, humidity) and send back the results to RPi. I tested the RPi3+GPIO+DHT22 communication. It works fine! :) But I would like to use the I2C, because it is elegant, fine solution.

So how can I configure the hardwares? RPi3 has GPIO: raspbery-pi-3-gpio-pinout-40-pin DHT22: DHT22 pins

The Arduino has power with USB cable. Do I need to use resistors like this: I2C configuration Or just I connect the RPi3 I2C GPIO pins to the Arduino UNO SDA/SCL pins directly?

(So the the RPi 5V level may be the problem.)

The GPIO pins are connected directly if both boards are 5V or both are 3.3v boards. If the boards are supplied with different voltages a level shifter is required. The pullup resistors (4.7K Ohm SDA to Vcc and SCL to Vcc) are [u]required[/u] for the I2C buss to work.

groundfungus: The GPIO pins are connected directly if both boards are 5V or both are 3.3v boards. If the boards are supplied with different voltages a level shifter is required. The pullup resistors (4.7K Ohm SDA to Vcc and SCL to Vcc) are [u]required[/u] for the I2C buss to work.

Is this I2C config good, but with 4.7kOhm resistors?

Yes. The resistor value is not critical as long as the value is over 1K and pulls the bus up strongly enough. A lower value resistor (but greater than 1K) can be used to more strongly pull the lines up in case of longer wires picking up noise. The higher value resistors consume less power. So it is a trade off. Use the highest value resistor that works reliably. 4.7K is the generally recommended value. The maximum net bus capacitance of 400pF limits the length.

groundfungus: Yes. The resistor value is not critical as long as the value is over 1K and pulls the bus up strongly enough. A lower value resistor (but greater than 1K) can be used to more strongly pull the lines up in case of longer wires picking up noise. The higher value resistors consume less power. So it is a trade off. Use the highest value resistor that works reliably. 4.7K is the generally recommended value. The maximum net bus capacitance of 400pF limits the length.

Is the 1.5KOhm value good too?

Sure, no problem with 1.5K.

So, do I need to use like this (see attachment)?

RPi3-Arduino_Uno.pdf (136 KB)

Yes, that is the proper wiring in terms of the Uno and pull ups. I don't know the Rpi pinout so that's for you.

groundfungus: Yes, that is the proper wiring in terms of the Uno and pull ups. I don't know the Rpi pinout so that's for you.

Ok, thanks!

RPi3 GPIO

Can I use parameter with wire requestEvent() handler?

for example:

// I2C, DHT
#include <Wire.h>
#include <dht.h>




// ***************************************************
// dht, variables
//

int dataPin = 8;
dht DHT;
int I2C_ADDR = 0;  // as slave
int readData;      // read from DHT
float h, t;        // humidity, temperature
// ***************************************************



// *****
// SETUP
// *****
void setup() {
  // put your setup code here, to run once:

  // Serial setup
  Serial.begin(9600);

  // I2C init
  Wire.begin(I2C_ADDR);
  Wire.onRequest(requestEvent);
}





// *********
// MAIN LOOP
// *********
void loop() {
  // put your main code here, to run repeatedly:

  // delay
  delay(100);
}





// *************
// receive event
// *************
void requestEvent( int data ) {
  // DHT22 read and output via serial port
  if ( data == 0 ) {
    readData = DHT.read22(dataPin);
    h = DHT.humidity;
    // I2C/wire result send: h
    Wire.print(h);
  } else if ( data ==1 ) {
    readData = DHT.read22(dataPin);
    t = DHT.temperature;
    // I2C/wire result send: t
    Wire.print(t);
  }
}

RPi3 C++ code:
wiringpi i2c-library

#include <iostream>
#include <errno.h>
# include <stdlib.h>
#include <wiringPiI2C.h>

using namespace std;

int main()
{
   int fd, result;

   // Initialize the interface by giving it an external device ID.
   fd = wiringPiI2CSetup(0x00);

   cout << "Init result: "<< fd << endl;

   result = wiringPiI2CWrite( fd, 0 );   // 0 for requestEvent()   ?
   if(result == -1)
    {
         cout << "Error.  Errno is: " << errno << endl;
         exit(1);
    }
   result = wiringPiI2CRead( fd );
   cout << "Read via I2C: " << result << endl;
}

Where can I receive the data from Arduino?

groundfungus: Yes, that is the proper wiring in terms of the Uno and pull ups. I don't know the Rpi pinout so that's for you.

Is the power pins of Arduino UNO board for in or out? So can I use the RPi3 GPIO 5V+GND for power supply of the Arduino board? Or do I need to use the USB cable for power supply?

int I2C_ADDR = 0;  // as slave

Address 0 is a special address in Wire so you need to choose a non-zero address (1 to 128).

Where can I receive the data from Arduino?

Someone else will have to help you with the Rpi side.

Is the power pins of Arduino UNO board for in or out?

Power pins are both, i guess, depending on the voltages.

So can I use the RPi3 GPIO 5V+GND for power supply of the Arduino board?

An Uno, conservatively, needs about 50mA. Can the Rpi supply 50mA? If so, you can connect the Rpi 5V and ground to the Uno 5V and ground. The grounds have to be connected, anyway, for I2C to work.

groundfungus: An Uno, conservatively, needs about 50mA. Can the Rpi supply 50mA? If so, you can connect the Rpi 5V and ground to the Uno 5V and ground. The grounds have to be connected, anyway, for I2C to work.

Pin #1: 3.3V -> 50mA, 5V -> 50mA+ RPi GPIO