Arduino: a code library for MCP23S17 LCD


In today’s blog post I will explain to you how to control Liquid Crystal Displays (LCDs) based on the Hitachi HD44780 (or a compatible) chipset, which is found on most text-based LCDs, using one MCP23S17 port expander.

I tried to make things as simple as possible, so everything comes as a code library – a fork of the well-known Adafruit LiquidCrystal library.

The reason for choosing that library as a starting point is that I wanted to make all the high-level functions work just as with the Arduino or the Adafruit I2C/SPI LCD backpack.


However, deep inside the library, there are many changes – all the low-level functions that are used to communicate with the Arduino board and with the LCD have been heavily modified.

My library comes with some simplifications:

  • only five data lines are used for the communication between the Arduino board and the MCP23S17 port expander:
    • Standard SPI: MISO, MOSI, SCK
    • /CS line has to be specified by the user when he creates the LCD object
    • The/RST pin for MCP23S17 is also configured when creating the LCD object.
  • The LCD works in 4-bit mode only, so it uses only one data port of the MCP23S17. The user chooses between PORTA and PORTB when he creates the LCD object. However, within the data port, the connections to the LCD are hardwired and cannot be changed at this moment.

With the above simplifications, one does only need to have a basic understanding on how the MCP23S17 operates – so if you are not familiar with it, download the datasheet and study it before going any further.


For developing this library I used one Expand Click from MikroElektronika, configured for 5V operation. The Expand click was placed in mikroBUS socket #1 of an Arduino Uno Click Shield. The board used for testing is the ubiquitous Arduino Uno.

The connection diagram is as follows:

Arduino: connecting an LCD using MCP23S01 port expander

Arduino: connecting an LCD using MCP23S01 port expander

On the Arduino side, the layout Arduino Uno Click Shield dictates the pins used:

  • /CS is D10
  • /RST is connected to A3.
  • The SPI pins are the standard pins:
    • MOSI – 11
    • MISO – 12
    • SCK – 13

The MCP23S17 hardware address is set as 0 using the jumpers on the Expand click board. I felt no need to change this, and the 0.0.1 library version works only with this hardware address.

MikroElektronika Expand Click with MCP23S17 port expader

MikroElektronika Expand Click with MCP23S17 port expander

On the LCD side, the connections are as follows:

  • LCD D7 pin to GPx7
  • LCD D6 pin to GPx6
  • LCD D5 pin to GPx5
  • LCD D4 pin to GPx4
  • LCD EN pin to GPx3
  • LCD RS pin to GPx2
  • LCD R/W pin to ground
  • LCD VSS pin to ground
  • LCD VCC pin to 5V
  • 10K resistor:
    • ends to +5V and ground
    • wiper to LCD VO pin

Where GPx is either GPA or GPB of MCP23S17.

Choosing this pin order is not a random thing – the LCD mini click from MikroElektronika uses that pin order, and I have plans to create a derivative of this library that works with that click board.


Besides this, allowing the user to choose the LCD pins at random would complicate the code a bit, and the code will run much slower.

However, if you know other MCP23S17 boards that use different wiring, drop me a comment, and I will see what I can do.

1 2

Leave A Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.