Today we introduce a great LCD expansion shield for Raspberry Pi that allows you to create an interface to control applications without the need to constantly keep a monitor, keyboard and mouse connected.
Cool! Isn’t it?
The enhanced value of a micro PC as Raspberry Pi with respect to a classic microcontroller is to be able to perform various tasks in resource sharing. Beyond the devices already available on the board you can add more, just being limited by the number of I/Os, processing power and memory.
In this post we describe the hardware of the shield, a library that terrifically improves the shield ease of use and a little deepening about the MCP23017, which has been used as an interface between the Raspberry Pi and the LCD modules.
Much of the potential and use cases depend on how the apps are designed, especially with regard to the ability to share resources used and avoid unsolvable deadlocks. Take for example the shield described in this article, which, as we shall see, requires the use of the I2C bus for the communication with Raspberry Pi.In fact, in case we wanted to build an application using the LCD exclusively the software is equivalent to what we would have written for a microcontroller. A program that runs in an infinite loop, managing the buttons and showing information on the screen.
If we want that the LCD display to serve a multiplicity of applications we should handle things differently. Let’s say we want to use the shield as in the previous case, but also allowing different applications to display messages, for example, for notifications such as phone calls or whatever.
In such an architecture, the different applications work simultaneously and in correspondence with given events, they require access to the I2C bus and then to the LCD to communicate their message.
If an application is already using the bus, other applications requiring to bind the same bus, finding it busy can’t do anything but go error. The first solution that might come to our mind is to create a single application handling all the needs in a monolithic way, a bit like a huge microcontroller.
This would lead to more negative than positive aspects such as application rigidity, difficulty in planning, maintenance and updating, difficulties in managing inter-parts timing, fragility (if something insignificant blocks, all the applications crash).
To solve such a need you should better rely on an architecture based on servers that can support concurrent applications, orchestrating the access to shared resource and where the different client application requirements can be fulfilled. For example, assume that two parts exclusively use the resources assigned to them: the LCD shield with the I2C bus and the GSM / GPS shield (which we already presented here), which uses the serial port.
For each of these resources is necessary to create a “server” or “demon” that manages the resource autonomously and manages the different clients requests on a predefined channel. There are many possible alternatives: TCP / IP sockets, semaphore files, and so on: in fact it’s all about managing “traffic lights” to properly coordinate client requests and forcing clients, ultimately, to access a centrally managed resource using the default communication channel with the protocol and the procedures previously defined. Better or worse than the microcontroller? This question does not have a definitive answer: it depends on what you want to accomplish and the requirements associated with it. Surely we will find ourselves increasingly in a position to integrate and these two environments with others such as FPGA and PLC.
Having said that, let’s get back to our shield.
To avoid to bind most of the input/output pins available on the Raspberry Pi connector just for the LCD functionality, we used the Microchip MCP23017 component which offers 16 Digital I/Os controllable through the I2C bus. In this way, we take advantage (also in a non-exclusive manner) of only two pins to drive the LCD screen, to interface five switches and manage three auxiliary inputs.
The basic configuration is designed to create a cascading menus system that allows to choose between hierarchies of items and then to configure parameters and visualize data. In reality, programmatically, we could use the buttons and inputs as we wish. The shield is provided with several connectors that can accommodate different types of LCDs which, while having different size, share the same pin configuration and commands.
The MCP23017 provides 16 digital I/Os divided into two banks of eight lines each, named GPA and GPB. The GPB is entirely dedicated to the LCD display management, while the five button are connected to the pins of the GPA.
A 5V power is taken from pin 2 of the GPIO connector on the board and the ground is connected to pin 6. The 10 kOhm potentiometer, connected to V0 pin of the LCD allows you to adjust the intensity of the backlight.
INTA and INTB outputs are connected, by means of the JA and JB jumpers, to GPIO17 and GPIO27, in order to make them available to possible applications. On the shield you can also find a a comb connector exposing also GPA5, GPA6 and GPA7 pins of the MCP23017, left over from the buttons management needs.
The practical use of the shield
First step: let’s assemble one of the LCD displays on the shield and then mount the shield on the Raspberry Pi’s connector.
Let’s than connect the peripherals, network, and power the Raspberry Pi in the usual way.
To communicate with the MCP23017 we must to use the I2C bus: as a result we have to power the I2C management module that, in a default Raspbian installation, is disabled. We must first enable the driver to manage the I2C bus, then install the python library for the LCD management and then make a first test program to see that everything is working properly.
First go with the following commands (as user “root”):
subsequently to use the I2C bus management module you must remove it from the blacklist and then add it to the set of modules available to the kernel .
Open the configuration file that contains the list of blacklisted modules, with the command:
nano /etc/modprobe.d/raspi-blacklist.conf (nano is a minimalist text editor that runs inside the terminal).
And eliminate the I2C module from the blacklist by erasing the lines or just commenting it with a “#”
You have to save the file and reboot for the changes to take effect.
Now we need to make sure that the two modules are loaded in the kernel. We can do this in two ways: loading the modules dynamically by command line (making them available for the entire session, at the next boot the modules need to be reloaded) or by loading the modules directly during the boot phase, which is essential in a system that runs unattended, especially thinking of resets.
The first option requires the use of the command modprobe (command: modprobe i2c-dev). Modprobe can be also used to disable a previously loaded module by using the remove option in the command (modprobe-r i2c-dev).
If you want the modules to be loaded in the kernel at the boot phase, after having whitelisted them as we saw above, you’ll need to enable permanent loading by modifying the configuration file /etc/modules, which contains the list of drivers to load at boot time. To edit the file we can use the command:nano /etc/modules
and add a new line to the configuration file that contains
In any case, you can always check the success of the activation of the driver by displaying the list of all installed modules with the lsmod command. Also, as in Linux everything (or almost) is a file if you go in the /dev folder you’ll see link files to devices i2c-0 and i2c-1.
Now let’s install the i2c-tools package, that provides a number of functions you can use with command line to verify the operation of the i2c bus:
apt-get install i2c-tools
and then add our user to the i2c group:
adduser pi i2c
Then reboot the RaspberryPi to activate the new configuration with the reboot command.
After RaspberryPi reboot connect with with Putty or Kitty to check whether the I2C bus is visible to the ADC with the command
i2cdetect -y 0 per RaspberryPi rev. 1 or
i2cdetect -y 1 per RaspberryPi rev. 2
You will get a result that is similar to that shown in the figure where the address 0x20 identifies the MCP23017.
The best procedure to download it is to use the version management tool invented by Linus Thorvalds, called git.
For more detail: An LCD Expansion Shield for your RaspberryPi