I2C on the Raspberry Pi

I2C is s standard means to communicate between integrated circuits, and is used
by microcontrollers to talk to integrated circuits or other devices. It is a 2-wire bus, consisting of a
clock signal (SCL) and a data signal (SDA). It can be used to interface the Raspberry Pi to LCD displays,
memory or realtime clock chips, or to other microcontrollers, such as the Arduino's ATmega328.

Raspberry Pi Configuration

The I2C ports on the Raspberry Pi are disabled in the kernel by default.
To enable them, you need to run raspi-config and turn on kernel support. It can be found in
the "Interfacing Options" section.

You will be prompted to reboot by raspi-config. Do it to install the kernel I2C module.

Once the kernel I2C support is enabled, you need to install a utility
that allows you to verify I2C addresses of your peripheral devices.

sudo apt-get install i2c-tools

Now you need to attach your I2C device. Before you do, shutdown and power off the Raspberry Pi.

sudo shutdown -h now

The pins involved are SDA on pin 3 and SCL on pin 5 of the GPIO connector. Connect your
I2C device to
the pins, either directly (if it is a 3.3V device) or through a level shifter (if it is a 5V device).

The Raspberry Pi is a 3.3V device

You must not connect a 5V peripheral device to the GPIO header! The inputs on the processor are not
5V tolerant, and they could be damaged by the resulting excessive current.

In this example, we connect a 5V LCD display to the Raspberry Pi through a Sparkfun level shifter breakout.
The breakout just goes between the Raspberry Pi and the LCD in the SDA and SCL lines. The "LV" pin on the
breakout connects to the 3.3V line on the RPi (pin 1). The "HV" pin connects to the 5V line (pin 4) and "GND"
connects to the RPi ground (pin 6).

The SCL line (pin 3) from the Raspberry Pi goes to the "LV1" pin on the level shifter and the SDA line (pin 5) goes to
the "LV2" pin. The LCD signals connect to the high voltage side. SCL is "HV1" and SDA is "HV2".

To check your work, boot the Rasberry Pi and run i2cdetect on the I2C
port. The port number will be either 0 or 1, depending on the model of Raspberry Pi you have. It doesn't
hurt anything to run it against the wrong port. This unit is a Model 3B, which assigns port 1 to the
GPIO header pins 3 and 5.

It finds two LCDs at addresses 0x20 and 0x27, right where they belong. I have two LCDs - one 16 x 2 and one
20 x 4. They each have different backpacks, and each backpack has a different pinout on the PCF8574 I2C to parallel chip.
With a little work and an oscilloscope I was able to determine which pin was which on the backpacks, and I
made two LCD libraries - one for each.

The temperature/humidity sensor is on the 3.3V I2C bus directly connected to the Raspberry Pi, while the two
LCD displays are on the 5V I2C bus created by the level shifter.

You can have multiple displays on the Raspberry Pi at the same time as long as they have different I2C
addresses. You will need to make some changes to the code, something like this:

That assumes one LCD uses the lcd_device_a module, the other uses the "b" module, and are addressed at
0x20 and 0x27. Adjust to suit your needs. They can both be the same code as long as they are different addresses.
Don't use this code with multiple threads or you may have a collision in the I2C hardware from two threads
talking at the same time.

No LCD display is complete without something to display, so I wired up an HTU21D temperature/humidity sensor
to get some interesting data. It can be seen at address 0x40, above. I have also included a module for
interfacing to the HTU21D.

CompuLab Fit-Headless Display Emulator

When you want to operate a Raspi headless, you might want to get into it using VNC, to give you a remote desktop
on your PC. The display on the Raspberry Pi defaults to 640 x 480 pixels if it can't find a display. To get around
this, and provide a 1080p desktop, CompuLab makes a display emulator that fools the Pi into thinking it has a
monitor. You can find them on Amazon (link below). I use them on a couple of
Mac Minis and a Raspberry Pi, and couldn't get by without them.

And the two LCD modules. These could be made into one module, but it would be complex and hard to read. For this
article, it is best to have two simple modules. The main difference is in the translation of bit to pin. One has the
data lines on the high nibble and the other has them on the low nibble. This makes the byte to nibble conversion in
'lcd_write()' and 'lcd_write_char()' different for each.