0% found this document useful (0 votes)
57 views11 pages

I2C Serial Interface

Download as pdf or txt
Download as pdf or txt
Download as pdf or txt
You are on page 1/ 11

Chapter 4 ■ I2C LCD DIspLays

Figure 4-2 shows the bottom side of the module. The bottom side shows that
connector CON1 has 16 connections. The number of connections is a nuisance from a
wiring and interfacing standpoint, but there is a solution for that.

Figure 4-2. The bottom side of the 1602A LCD module

The logic and the LCD portions of this PCB require 5 volts, which makes this a
little bit of a challenge for the Pi. But there is a solution for that too. The unit includes
backlighting, so you must add the current for the logic plus the backlighting when
planning your power requirements. The figures seem to vary depending upon the
manufacturer, but one datasheet lists the current as 150mA for the logic plus another
100mA for the backlighting. So, this unit is likely to draw about 250mA total from your Pi’s
5V supply.
The 1602A module uses eight data lines and three control lines for data transfers.
That would require 11 GPIO lines to be allocated from the Pi. However, it is possible to
operate the module in 4-bit mode instead. This still requires seven GPIO lines, which is
inconvenient.
To work around this problem, there is a nice I2C adapter module that can be
economically purchased and used.

I2C Serial Interface


The module I purchased on eBay was titled “Black Arduino 1602LCD Compatible Serial
Interface (IIC/I2C/TWI/SPI) Board Module.” The SPI in the title is bogus, since this is an
I2C module. The module is based upon the PCF8574 chip, for which you can also obtain
a datasheet.
To find the module on eBay, search for 1602 serial module. I usually check the “Buy It
Now” option so that there is no need to mess around with auctions and wait times. These
modules can be purchased for as little as $1.10. Figure 4-3 illustrates the module that I
purchased.

36
Chapter 4 ■ I2C LCD DIspLays

Figure 4-3. The I2C Serial Interface module with the PCF8574 chip at the center. Pin 1 is at
the right side, despite the silk screen.

The module has three solderable jumpers marked A0, A1, and A2 (on the bottom
right of Figure 4-3). Since CMOS inputs must not be left floating, there are pull-up
resistors on the board. Based upon resistance readings taken, it appears that the three
surface mount resistors marked “103” are the 10kΩ pull-up resistors to each of the
address inputs. Soldering in a shorting jumper will change the address input to a logic 0.
Without any jumpers installed, this I2C PCB will respond to I2C address 27
hexadecimal (hex). With all jumpers installed, the I2C address changes to hex 20. If you
should get a unit with the PCF8574A instead, the I2C address changes to 3F hex, with no
jumpers or 38 with jumpers installed.
I have been unable to find a schematic for this exact PCB, but measuring between
the VCC connection and the SDA or SCL connections confirms a resistance of 4–7kΩ
(you can see resistors labeled “472” on the PCB). This evidence of a pull-up resistor is bad
news for 3.3V operation because VCC on the PCB will be connected to 5 volts when used
with the LCD module. The serial interface PCF8574 chip is able to operate from 3.3 volts,
however, so before you connect it to the LCD module, let’s check the I2C module to see
whether the unit is functional and usable by the Pi.

I2C Module Configuration


The PCF8574 peripheral is rather unique in that it does not require any formal configuration.
The datasheet specifies that its ports are quasi-bidirectional. So, how does this work?
To set an output, you simply write a bit pattern to the outputs over the I2C bus. Pins
written with a 1 bit turn off their pull-down transistor and cause the pull-up current
source to bring the output pin high. This pull-up current source is weak, supporting only
100μA. The NXP documentation indicates, however, that there is an accelerated strong
pull-up that is active during the high time of the I2C acknowledge clock cycle. This briefly
helps the output turn sharply high at the right time but requires only 100μA to maintain
that state after. This works fine for interfacing to CMOS input signals. But because of the
weak high-side drive, the ports cannot source current into LEDs.

37
Chapter 4 ■ I2C LCD DIspLays

Output ports that are written with a 0 bit cause their pull-down transistor to activate
to conduct port current to ground level. This driven output can sink up to 25mA of
current, though the chip total must not exceed 80mA. This makes the port capable of
driving LEDs when the ports are used to sink LED current.
To be able to read an input, there is a cheat step required: the port must first be
written with a 1 bit so that its weak pull-up current source can allow the port to rise high.
Then the component driving the input can pull the voltage down to ground level when
transmitting a 0 bit to the input. When a 1 bit is transmitted to the port, the signal is
simply brought high again with some assistance from the weak pull-up current source.
If the input port was left in the output 0 bit state, the port’s output driver transistor
would keep that port grounded. To indicate a 1 bit, the component driving this input
would have to overcome this with a struggle. This could result in high currents and
potential damage.

I2C Module Output


Figure 4-4 is a generic schematic of the different I2C modules available. For this
experiment, don’t attach the LCD display yet, since the display module will not function
on 3.3 volts. But the wiring of the unit is important to note because you need to know
where the port pins appear on the edge of the PCB.
From Figure 4-4 you can see that four of the outputs go to pins 11 to 14 of the
16-pin header strip. These will be used to send four bits at a time to the LCD module.
These are port bits 4 through 7, respectively. Three of the four remaining bits go to the
LCD interface pins 4, 5, and 6 to control the information handshaking. These are pins 0
through 2, respectively, with port pin 3 left unconnected (on some LCD modules, pin 3
switches backlighting on or off ).
JP1
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
LED+
GND

B/W
VDD

GND
DB4
DB5
DB6
DB7
BS
VO

GND

VDD

GND

VDD/VCC
1

4.7k

4.7k

2
10k

10k

10k
R2

R3

R4

R5

R6

IC1
R1

C1 16
3

VDD
SDA
RS 4 13
B/W 5 P0 INT
P1
E 6 P2 SDA 15 SCL
7 P3 SCL 14
DB4 9 P4 A0
DB5 10 1
P5 A0 A1
DB6 11 P6 A1 2
DB7 12 P7 A2 3
A2
8 VSS
PCF8574T
GND GND

Figure 4-4. Generic schematic of the 1602 I2C adapter PCB

38
Chapter 4 ■ I2C LCD DIspLays

Table 4-1 summarizes the port pins and the corresponding LCD pins for your
convenience.

Table 4-1. Port Locations on the 16×1 LCD Header Strip

Port 16×1 Pin Description


P0 4 LCD RS
P1 5 LCD R/W
P2 6 LCD E
P3 Internal Backlighting switch, when supported by I2C module
P4 11 LCD DB4
P5 12 LCD DB5
P6 13 LCD DB6
P7 14 LCD DB7

Let’s first verify that the I2C bus is available, as shown here:

$ i2cdetect -l
i2c-1 i2c 3f804000.i2c I2C adapter

If i2cdetect is not installed, then install it now, as shown here:

$ sudo apt-get install i2c-tools

Now that you have confirmed that the I2c-1 bus is available, attach the serial
module (without the LCD connected). Connect the VCC to the Pi’s 3.3V supply and GND
to the Pi’s ground. Finally, connect SDA and SCL to the Pi’s SDA and SCL connections,
respectively (the T-Cobbler silk screen should identify these plainly).
With this wired up, start your Pi and perform the following scan of I2C bus 1, as
shown here:

$ i2cdetect -y 1
0 1 2 3 4 5 6 7 8 9 a b c d e f
00: -- -- -- -- -- -- -- -- -- -- -- -- --
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
20: -- -- -- -- -- -- -- 27 -- -- -- -- -- -- -- --
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
70: -- -- -- -- -- -- -- --

39
Chapter 4 ■ I2C LCD DIspLays

The session output confirms that the I2C device is seen as address 27 (hex). This is a
good sign that the device is working. If you have a different model of the PCB, you may find
the unit at a different address, perhaps 3F. Substitute your address in the tests that follow.
Change to the subdirectory pcf8574 in the supplied source code. Perform a make
command (if not already performed), which should leave you with an executable named
i2cio. The command takes optional arguments, which are explained with the use of the
help (-h) option.

$ ./i2cio -h
./i2cio [-a address] [-i pins] [-h] [out_value1...]
where:
-a address Specify I2C address
-i 0xHex Specify input port pins (0=none=default)
-h Help

If your unit was found at a different address than the default hexadecimal address of
27, then you will need to supply that in the commands afterward with the option -a.
I recommend doing this experiment with Dupont wires only since it is easy to cause
a short circuit and ruin something. Either place the PCB module on the breadboard and
connect to it through the breadboard or locate some male/female Dupont wires to safely
attach your connections.
Connect the negative lead of your voltmeter/DMM to the ground of the Pi. Using the
plus lead of the DMM, measure the voltage present at pin 14 of the 16×1 header strip. You
should measure either 3.3 volts or 0 volts. Now run the following command (substituting
for the I2C address if necessary). Do not omit 0x where it appears, as this specifies that
the number is in hexadecimal notation.

$ ./i2cio -a0x27 0x80


I2C Wrote: 0x80

This command writes the hex value 80 to the I2C port at address 27. After this runs,
you should measure approximately 3.3 volts at pin 14. If you don’t get that, then check
that you have the correct pin. My PCB unit marks pin 16 with a square, suggesting it is pin
1, but this is actually pin 16.
To confirm the port’s operation, let’s now write a 0 out.

$ ./i2cio -a0x27 0
I2C Wrote: 0x00

After the message I2C Wrote: 0x00, you should immediately see the voltage go to 0
on pin 14. This confirms the following:
• That the unit is operating and responding to the I2C address you
specified
• That port bit 7 corresponds to connection 14 on the header strip
• That you know which end of the header strip is pin 1

40
Chapter 4 ■ I2C LCD DIspLays

This last item is important since it is easy to get this wrong. Cheap clones of the
original board are being made all the time, and important matters like this are often
incorrect or mislabeled.
Now check bit 4, using the value 0x10, followed by setting it to 0. Did pin 11 on
the PCB module obey? Finally, using the value 0x01, does the RS signal (header pin 4)
measure the correct changes?

■ Note If you are having trouble locating pin 1 on the I2C module, one way to confirm
this is to measure the resistance of V0 pin 3, which is attached to the potentiometer.

Measure the resistance between pin 3 and the GND pin (the first pin on the end nearest
the pin being tested). slowly rotate the potentiometer slightly and watch for a resistance
change. a change of reading will confirm pin 3.

I2C Module Input


Having succeeded in performing I2C output to the module, it is now time to try input.
Connect a Dupont wire to header pin 14 (DB7) and the other end to your breadboard. Just
leave it unconnected for the moment and perform this test:

$ ./i2cio -a0x27 -i0x80


I2C Read: 0x80 (Inputs: 80)

By adding the option -i0x80, you have made bit 7 an input. This was done by first
setting the output bit to a 1 so that inputs could be performed on it. The command then
performs a read and reports what it read. In this case, only the high bit is significant, and
since 0x80 indicates a high value, you know the input bit was a 1.
If you don’t want to see the other bits, you can force the others to 0 by doing an
output first and then repeating the following:

$ ./i2cio -a0x27 0
I2C Wrote: 0x00
$ ./i2cio -a0x27 -i0x80
I2C Read: 0x80 (Inputs: 80)

After setting all output bits to 0, only the input should ever show up as a 1 bit.
Before running the command again, connect your input Dupont wire to ground.
When you perform the read test this time, the reading should change, as shown here:

$ ./i2cio -a0x27 -i0x80


I2C Read: 0x00 (Inputs: 80)

Again, only the high bit (7) is significant since that is the only input you’re polling.
You can see from the value reported that the grounding of that pin caused the command
to read 0. Unground the Dupont wire and repeat. Did the read value change back to 0x80?

41
Chapter 4 ■ I2C LCD DIspLays

PCF8574P Chip
From the preceding experiments you can see that this module can be used as a cheap and
nearly configuration-free I2C GPIO extender. The main issue is that the PCB is designed to
work with the 1602A LCD. This might mean that only seven of the eight GPIOs are brought
out to the header strip (the blanking bit may be supported, however, to make eight).
The PCF8574P chip is available in the plastic DIP form from various sources
including eBay, for as little as $0.66. Since this chip will operate at 3.3 volts, it is a good
trick to keep in your back pocket when adding GPIOs to the Raspberry Pi. With no
complicated software configuration required, it is quite easy to use. Just keep in mind that
when driving a current load (like an LED), always arrange the port to sink the current.

3 Volts to 5 Volts
The LCD module must operate at 5 volts. So, now you must cross that digital divide from
the 3.3V realm to the 5V TTL world. Note that Chapter 2’s techniques do not apply to
the I2C bus, so you must find another way to do this. Figure 4-5 shows a tiny little level
converter with the header strips installed. On eBay, you can purchase these for a “Buy It
Now” price of $0.99.

Figure 4-5. Topside of I2C level converter with header strips installed
42
Chapter 4 ■ I2C LCD DIspLays

Figure 4-6 shows the bottom-side silk screen. There is a 3V output derived from the 5V
input, shown on the top right of the figure. But I recommend you use that as a last resort.
Use the Pi’s 3.3V power instead because I have found that this connection can be higher
than it should be. If you do use it, the silk screen indicates that it is limited to 150mA.
There are four remaining pins on the left and right sides. The idea is that on one side
you have your 5V signals and on the right are the 3.3V signals. This device is bidirectional,
using MOSFET transistors to do the level conversions. For these purposes, you need the
I2C SDA and SCL lines converted.

Figure 4-6. Bottom side of I2C level converter

To keep the various systems in perspective, Figure 4-7 illustrates the signal realms
involved, including the Raspberry Pi on the left, the level converter at the center, and the
5V I2C serial module for the LCD on the right.

43
Chapter 4 ■ I2C LCD DIspLays

VCC

5V

3.3 Volt I2C I2C


Regulator Level Serial 1602 LCD
Converter 5V 5V Module Module
SDA
5V
3.3 V
3.3 V 5V
GND

Pi SCL

GND

Figure 4-7. Block diagram of Raspberry Pi, I2C level converter, and I2C serial module

The dashed lines of Figure 4-7 illustrate the I2C signals as they progress from the Pi
to the I2C serial module at the right. Except for the fact that this level conversion adds
another module to the mix, the circuit remains otherwise simple. The two I2C signals
SDA and SCL are all that are required to communicate with the LCD module.

Attaching the I2C Serial Module


Take a good look at Figures 4-2 and 4-3. Note particularly where pin 1 of CON1 is shown
in Figure 4-2. This pin is near the mounting hole in the upper right of the photo. This is
where pin 1 of the I2C serial adapter needs to go.
On my serial adapter, the silk-screen square is shown at the top left. This is incorrect!
Using a DMM, I was able to confirm that V0, which is pin 3, is actually the third pin
from the top right of Figure 4-3. I seem to have a clone of the original design where they
botched the silk screening. The PCB square should have been at the top right instead. I
mention this to save you a lot of agony. Once the PCB is soldered to the LCD module, it is
difficult to separate them. Take your time getting the orientation correct before you plug
in that soldering iron.
Figure 4-8 shows the I2C module installed on the LCD module. The power and the
two I2C connectors should be located at the upper right. I put a piece of electrical tape
underneath the I2C module before soldering it in place. This will keep bare connections
from bumping into connections on the LCD module.

44
Chapter 4 ■ I2C LCD DIspLays

Figure 4-8. I2C module attached to LCD module

I like to test things as I go since this saves a lot of troubleshooting effort when things
go wrong and provides a confidence boost when things are going right. The best way
to do this is to yank the microSD card out of the Pi so that it doesn’t boot. That way, if
something goes wrong, you can yank the power without having to worry about corrupting
the microSD card. It also saves you from having to do a formal shutdown when you’re
done testing.
As part of this test, adjust the potentiometer so that you start to see the character
cells in the display. You’ll likely readjust again, once text is shown on the display later.
My LCD module initialized such that one line of cells was showing. Yours may show
a different pattern. Even if you get no pattern at all, don’t panic about it until you try
sending data to it under software control.
If you want to take a current reading, this is a good time to do it. While my LCD was
operating under test in Figure 4-9, I measured about 87mA of current. On the I2C module,
there is a jumper at one end. Removing it turns off the backlighting for the module by
disconnecting the power for it. Once I did this, the current dropped to about 6mA. If you
have a battery-operated system, you could save power this way.

45
Chapter 4 ■ I2C LCD DIspLays

Figure 4-9. The LCD powered from the Pi’s 5V supply, supplied through the I2C module on
the back

The next step is to hook up the I2C level converter. Wire the Pi’s +5 volt to the level
converter’s 5V input and its ground to ground. Also connect the serial module SDA and
SCL lines to the 5V side of the level converter, but save the 3.3V SDA and SCL for later.
Leave those unconnected. Using your voltmeter/DMM, measure the 3.3V SDA and SCL
pins on the level converter when powered. You should get a reading near 3.3 volts. If
you read something else, you need to investigate. If the voltage reads higher than +3.6
volts, then don’t go any further since hookup could damage your Pi’s GPIO ports. Once
you have good readings, you are clear to connect the Pi’s SDA and SCL ports to the level
converter’s 3.3V side.

Displaying Data
Once everything is wired, you are ready to display some data on the LCD. Figure 4-10
illustrates the LCD connected to the Pi with some text displayed. In the subdirectory
pcf8574, there is a program named lcd.cpp that should have been built as executable
lcd. If the executable does not yet exist, type the make command now to build it.
Invoke the command simply as follows:

$ ./lcd

46

You might also like