Peter Mount has a tutorial on how to connect an arduino to a raspberry pi using I2C.
Some time ago I created a weather station using a Raspberry PI and an off the shelf weather station, connecting the two via USB.
However, for some time not I’ve been meaning to create a weather station from scratch – i.e. one or more Raspberry PI’s which connect to the network (via Ethernet or WiFi) and directly monitor the sensors directly.
Now the problem here is that some sensors are analog – for example the leaf, soil and UV sensors I have generate an analog signal so we need an ADC (Analogue to Digital Converter) which the Raspberry PI doesn’t have.
So we have two possible solutions:
- Add a Raspberry PI compatible ADC
- Use an Arduino
With the parts I have available, the Arduino won, not just on available ADC channels but also with the additional digital ports available.
Now how to connect it to the PI? Well the easiest way is to use USB, however the PI only has two USB ports (one for the Model A) and as I’m intending to use Model A’s for the final station I need that for WiFi (there won’t be room or power for hubs) so USB is out.
There’s RS232 which both support, however the PI runs on 3v3 whilst the Arduino (UNO) is 5v so I need to add a level converter between the two. It also limits me to just one arduino and I might need to use more than one so another solution is needed.
Enter I2C
Both the PI and Arduino support two additional types of communication for talking to peripheral devices. There’s SPI which is a high speed serial protocol and I2C. Like RS232, SPI needs level shifters, but not exactly so for I2C.
I2C is a 2 wire protocol allowing for 127 devices to be connected to a single bus. One device is the master (The PI in our case) and then the peripherals.
In the above diagram you can see that there’s two connections between devices (other than ground), SDA (Serial Data Line) which is where the data is carried, and SCL (Serial Clock Line). There’s also a pair of resistors which pull up the signals to Vdd.
Now the trick, Vdd is only there to pull those signals up and in I2C a 1 is when the signal is pulled down to 0V. It’s not there to power the devices so, as long as we keep Vdd at 3v3 and no device has a pull up resistor on them (i.e. to 5V) then we are save to connect it to the PI. There’s only a problem if any device on the I2C bus also has a pull up resistor.
Now do the Arduino’s have pullup resisitors? Well they actually don’t, they actually cannot as the I2C interface is shared by two of the analogue inputs (4 & 5 to be precise) so there cannot be a resistor there else it would affect those pins when not being used for I2C.
So, we have a solution as long as the Raspberry PI is the I2C Master which is what we want. Also, of the available GPIO pins, only SDA and SCL have pull up resistors, so we are set.