ADAFRUIT_MCP23017 library and LCD 16x2 Display

Hi all,

I am using the Arduino UNO and the MCP23017 on my own LCD shield.

So far If I press a button, I get an LED going. So input and outputs are fine.

Now it comes to the LCD part:

What must I type in when I define the LCD pins? Code


#include <Wire.h>
#include "Adafruit_MCP23017.h"
#include <LiquidCrystal.h>

Adafruit_MCP23017 mcp;
LiquidCrystal lcd(rs, en, d4,d5,d6,d7);

void setup() {
mcp.begin(); // use default address 0
mcp.pinMode(0, INPUT);
mcp.pinMode(1, OUTPUT);
mcp.pinMode(2, INPUT);
mcp.pinMode(3, INPUT);
mcp.pinMode(4, OUTPUT);
mcp.pinMode(5, INPUT);
mcp.pinMode(6, OUTPUT);
mcp.pinMode(7, OUTPUT);
mcp.pinMode(8, OUTPUT);
mcp.pinMode(9, OUTPUT);
mcp.pinMode(10, OUTPUT);
mcp.pinMode(11, OUTPUT);
mcp.pinMode(12, OUTPUT);
mcp.pinMode(13, OUTPUT);
mcp.pinMode(14, OUTPUT);
mcp.pinMode(15, OUTPUT);
}

void loop() {
mcp.digitalWrite(8, mcp.digitalRead(5));
mcp.digitalWrite(4, mcp.digitalRead(0));
mcp.digitalWrite(9, mcp.digitalRead(3));

}


At the part where it say's :

LiquidCrystal lcd(rs, en, d4,d5,d6,d7);

How do I map the rs input from the LCD to mcp output 10.

mcp.digitalWrite(10) didnt work.

I am using my own shield design so the Adafruit_RGBLCDShield library doesnt help me a lot.

Regards

Andy

I don’t think you can do that out of the box with LiquidCrystal. Someone please correct me if I am wrong.

Maybe not what you are looking for, but I have a fork of LiquidCrystal that can work with 23017, 8574, Shift registers and arduino pins by changing the iodevice passed in to it.

If you are interested take a look at

It requires ioabstraction that can be installed from the library manager instead of the adafruit library.

The helloi2c example demos it’s additional capabilities.

Keep in mind that although ioabstraction is stable I’ve not fully released the lcd library yet, but have it working with 23017 and 8574 io expanders and even shift registers.

If this interests you please reply - I’ll follow the thread.

Hi davetcc,

what does that mean :

It requires ioabstraction that can be installed from the library manager

Regards

Andy

Hi Davetec

I did this now:


// include the library code:
#include <LiquidCrystalIO.h>
#include <IoAbstractionWire.h>
#include <Wire.h>

// initialize the library by associating any needed LCD interface pin
// with the arduino pin number it is connected to
const int rs = 10, en = 11, d4 = 12, d5 = 13, d6 = 14, d7 = 15;
LiquidCrystal lcd(rs, en, d4, d5, d6, d7, ioFrom8574(0x20));

void setup() {
pinMode(9, OUTPUT);
analogWrite(9, 10);

Wire.begin();
// set up the LCD's number of columns and rows:
lcd.begin(16, 2);
// Print a message to the LCD.
lcd.print("hello, world!");
}

void loop() {
// set the cursor to column 0, line 1
// (note: line 1 is the second row, since counting begins with 0):
lcd.setCursor(0, 1);
// print the number of seconds since reset:
lcd.print(millis() / 1000);
}

this is your code. I just changed my pin association ( RS = 10, EN = 11 etc) as I connected the LCD to my MCP23017.

it's not working unfortunately . Any suggestion what I'm doing wrong?

Regards

Andy

As you are using with MCP23017 you would instead change:

ioFrom8574

To

ioFrom23017

You’ll also need to make sure that ioabstraction library itself is installed - available in library manager.

See this page that describes all the options for more details:

https://www.thecoderscorner.com/ref-docs/ioabstraction/html/_io_abstraction_wire_8h.html

Sorry I had missed the prior reply.

Ioabstraction is a library the provides some extended IO capabilities that are not directly implemented in Arduino.

LiquidCrystalIO uses this library and so it must be installed from the standard Arduino IDE library manager.

Good morning Dave,

thanks for your support.

I changed ioFrom8574 ( which is formatted in red letters) to ioFrom23017. and it is in black letters as I changed it. But compiling goes right through without error messages.

Than I changed the

LiquidCrystal lcd(10,11,12,13,14,15); I hope that is the ioabstraction you where talking about.

thats the code:

// include the library code:
#include <LiquidCrystalIO.h>
#include <IoAbstractionWire.h>
#include <Wire.h>

// initialize the library by associating any needed LCD interface pin
// with the arduino pin number it is connected to
const int rs = 10, en = 11, d4 = 12, d5 = 13, d6 = 14, d7 = 15;
LiquidCrystal lcd(rs, en, d4, d5, d6, d7, ioFrom23017(0x20));

void setup() {
pinMode(9, OUTPUT);
analogWrite(9, 10);

Wire.begin();
// set up the LCD's number of columns and rows:
lcd.begin(16, 2);
// Print a message to the LCD.
lcd.print("hello, world!");
}

void loop() {
// set the cursor to column 0, line 1
// (note: line 1 is the second row, since counting begins with 0):
lcd.setCursor(0, 1);
// print the number of seconds since reset:
lcd.print(millis() / 1000);
}

as the pins RS,EN,D4,D5,D6,D7 are on the output from the MCP23017 GPOIB2,GPOIB3,GPOIB4,GPOIB5,GPOIB6,GPOIB7.

Do you need the schematics??

As I mentioned before I had it running with a button switching on a LED and both are connected via the MCP23017.

Regards

Andy

How is London by the way. My boss is there at the moment for 2 weeks visiting his daughter.

Regards

Andy

Hi Dave,

this one works fine.


#include <Wire.h>
#include "Adafruit_MCP23017.h"
#include <LiquidCrystal.h>

Adafruit_MCP23017 mcp;
void setup() {
mcp.begin(); // use default address 0
mcp.pinMode(0, INPUT); // Button UP
mcp.pinMode(1, OUTPUT); // NC
mcp.pinMode(2, INPUT); // Button Right
mcp.pinMode(3, INPUT); // Button Left
mcp.pinMode(4, OUTPUT); // Buzzer
mcp.pinMode(5, INPUT); // Button Down
mcp.pinMode(6, OUTPUT); // NC
mcp.pinMode(7, OUTPUT); // NC
mcp.pinMode(8, OUTPUT); // Green LED
mcp.pinMode(9, OUTPUT); // Red LED
mcp.pinMode(10, OUTPUT); // LCD RS
mcp.pinMode(11, OUTPUT); // LCD EN
mcp.pinMode(12, OUTPUT); // LCD D4
mcp.pinMode(13, OUTPUT); // LCD D5
mcp.pinMode(14, OUTPUT); // LCD D6
mcp.pinMode(15, OUTPUT); // LCD D7
}

void loop() {

mcp.digitalWrite(8, mcp.digitalRead(5));
mcp.digitalWrite(4, mcp.digitalRead(0));
mcp.digitalWrite(9, mcp.digitalRead(3));

}


Press button down and the green LED comes on, etc.

Is there any chance I can combine your ioabstraction with the above adafruit library???

Regards

Andy

Io Abstraction is very similar in it's offering the the library you've been using. The difference is that you can use many different IO devices in the same way.

Take a look at:

https://github.com/davetcc/IoAbstraction/blob/master/examples/ledsOnMCP23017/ledsOnMCP23017.ino

This shows the basic use of the library, very similar to what you've been using. In the mean time I'll build the circuit today and provide new example for 23017. Also take note that when using a 23017, the reset pin must either be connected to the Arduino or held in a constant state, otherwise you'll get instability (it'll almost work but keep resetting), in the sketch linked above note this section:

    // this is optional, in a real world system you could probably just connect the
    // reset pin of the device to Vcc, but when prototyping you'll want a reset
    // on every restart.
    pinMode(resetPin23017, OUTPUT);
    digitalWrite(resetPin23017, LOW);
    delayMicroseconds(100);
    digitalWrite(resetPin23017, HIGH);

Hi there,

Couple of things:

  1. You absolutely must hold RESET HIGH line as per my last post, otherwise it becomes unstable.
  2. You often need a small 0.1uF or so capacitor across Vdd - Vss as close to the device as physically permits. Without this instability may result.
  3. In my example I use a PWM arrangement to provide contrast input to Vo, you either need to do that or do the same with a potentiometer.
  4. More comments in the new sample.

There is a new example on the LiquidCrystalIO for 23017 that I've personally tested just now. I've also attached an image of how I've wired it on breadboard in case it helps. Notice the cap right next to the power input, this is important. Notice reset held high (just visible).

Example (also within latest library):

Hi Dave,

thanks alot. Its working now.

I downloaded the latest libraries.

I owe you one.

Many Thanks from Capetown.

Andy

No worries..

Glad it’s working for you!

Dave

Hi Dave,

If I want to address my output pin 5 of the ATmega328 I write

pinMode(3,OUTPUT);

How does the program know to use pin 5 from the MCP23017 and not from the ARDUINO?

// if you want to use the optional PWM contrast, you need to set the pin for it

const int pwmContrastPin = 5;

I then included into your HelloI2c.ino

#include <IoAbstraction.h>

I added Line

MultiIoAbstraction multiIo();

compiled it and no problem.

Then I added in the setup routine line

multiIo.addIoExpander(ioFrom23017(0x20), 16);

while compiling it brought me this error message

request for member 'addIoExpander' in 'multiIo', which is of non-class type 'MultiIoAbstraction()'

What can I do??

Regards

Andy

If you use multiIo abstraction, by default the first 100 pins are allocated to arduino pins, then any expanders you add will appear on subsequent pins. You can change the number of pins allocated to arduino by passing the number needed to the constructor.

In your code above, I don't think you need the empty parenthesis on the declaration of multiIO, I think that will clear the compile error. See below:

MultiIoAbstraction multiIo(numberOfArduinoPins);

// or otherwise for the default

MultiIoAbstraction multiIo; // omit the brackets in this case.


// when using a multiIo with something that's looking for an IoAbstractionRef (such as LiquidCrystalIO)

IoAbstractionRef multiIoRef = &multiIo;

see also: Using Arduino Pins and Io Expanders at the same time · The Coders Corner

Thanks Dave ,

This has saved me quite a bit of effort ,
I used a MCP23017 board sold for use with the the lcd displays , It took me a couple of iterations to work out the pin numbers required , then I very easily switched to 8 bit mode.

( I'll post the pin numbers I used, when get home)

Many Thanks

Dave

Pin numbers I used were
const int rs = 7, en = 5, d4 = 12, d5 = 13, d6 = 14, d7 = 15;
const int d0 = 8, d1 = 9, d2 = 10, d3 = 11;
LiquidCrystal lcd(rs, en, d0, d1, d2, d3 ,d4, d5, d6, d7, ioFrom23017(0x20));
or for 4bit mode
LiquidCrystal lcd(rs, en, d4, d5, d6, d7, ioFrom23017(0x20));