6 years, 11 months ago.

TextLCD Lib - PCF8574 - Nucleo L476RG I2C Connectivity

Hi,

I am very new to mbed 32bit world and need your assistance on the below issue.

I'm trying to use the TextLCD-enhanced library to drive a 16x2 LCD PCF8574AT backpack with Nucleo L476RG dev board. As the LCD is 5V I'm using a level shiftier and 4.7k pullup resistors on SDA and SCL lines on both LCD and Nucleo board side (attached image).

I2C bus connected on PB_9, PB_8 (SDA, SCL) and same address (0x3F) as used in Arduino. Note that I was able to drive this (without pullup resistors) from Arduino Uno board.

Issue is that I2C LCD is not even showing in scanning result (as you can see from Serial output) and I can only rectangle box on the display.

Could you please advise what is going wrong and need your help.

Reference Image

/media/uploads/dhamukrish/fullsizerender.jpg

Code

// Hello World! for the TextLCD
#include "mbed.h"
#include "TextLCD.h"

#define Device_Name_ADDR   (0xEE) // Device You Wish to Use Address - using i2c Address
#define WRITE              (0x00) // i2c Write bit
#define READ               (0x01) // i2c Read bit

// Host PC Communication channels
Serial pc(USBTX, USBRX); // tx, rx

// I2C Communication
I2C i2c_lcd(PB_9, PB_8); // SDA, SCL

//I2C Portexpander PCF8574
TextLCD_I2C lcd(&i2c_lcd, 0x3F, TextLCD::LCD16x2); // I2C bus, PCF8574 Slaveaddress, LCD Type ok

char ucdata_write[2];
short count=0;

void I2CScan (void);

void I2CScan()
{
    unsigned int uibaudrate=57600;
    pc.baud(uibaudrate);

    unsigned int uifrequency=400000; //400KHz for i2c Max
    i2c_lcd.frequency (uifrequency);

    pc.printf("\n\rHello World ");
    pc.printf("at %u BAUD and %uKHz i2c Frequency\n\r", uibaudrate,uifrequency/1000);
    pc.printf("Using mbed.org Martin\n\r");

    ucdata_write[0]=0;
    ucdata_write[1]=0;

    for (int Device_Adress=0; Device_Adress<=0xFE; Device_Adress+=2) { //Stepping in 2 Because Read/Write use LSB
        if (!i2c_lcd.write((Device_Adress|WRITE), ucdata_write, 1, 0)) { // Check for ACK from i2c Device NB I am 'ORing' the Write Bit
            pc.printf("ACK from the Device at Address %#4x\n\r",Device_Adress);
            count=count+1;
            wait(2);
        } else {
            //Left the following in for development/Future coding
            //pc.printf("\n\rCannot get an ACK from the Device check connections!\n\r");
            //lcd.printf("No ACK from\nDevice!");
        }
    }

    pc.printf("\n\r %d Devices have been detected!\n\r",count);
    pc.printf("\n\r");
}

int main()
{
    I2CScan();

    pc.printf("LCD Test. Columns=%d, Rows=%d\n\r", lcd.columns(), lcd.rows());

    for (int row=0; row<lcd.rows(); row++) {
        int col=0;

        pc.printf("MemAddr(Col=%d, Row=%d)=0x%02X\n\r", col, row, lcd.getAddress(col, row));
//      lcd.putc('-');
        lcd.putc('0' + row);

        for (col=1; col<lcd.columns()-1; col++) {
            lcd.putc('*');
        }
        pc.printf("MemAddr(Col=%d, Row=%d)=0x%02X\n\r", col, row, lcd.getAddress(col, row));
        lcd.putc('+');
    }

// Show cursor as blinking character
    lcd.setCursor(TextLCD::CurOff_BlkOn);

// Set and show user defined characters. A maximum of 8 UDCs are supported by the HD44780.
// They are defined by a 5x7 bitpattern.
    lcd.setUDC(0, (char *) udc_0);  // Show |>
    lcd.putc(0);
    lcd.setUDC(1, (char *) udc_1);  // Show <|
    lcd.putc(1);
    lcd.setUDC(2, (char *) udc_2);
    lcd.putc(2);
    lcd.setUDC(3, (char *) udc_3);
    lcd.putc(3);
    lcd.setUDC(4, (char *) udc_4);
    lcd.putc(4);
    lcd.setUDC(5, (char *) udc_5);
    lcd.putc(5);
    lcd.setUDC(6, (char *) udc_6);
    lcd.putc(6);
    lcd.setUDC(7, (char *) udc_7);
    lcd.putc(7);
}

Serial Output

Hello World at 57600 BAUD and 400KHz i2c Frequency                              
Using mbed.org Martin                                                           
                                                                                
 0 Devices have been detected!                                                  
                                                                                
LCD Test. Columns=16, Rows=2                                                    
MemAddr(Col=0, Row=0)=0x00                                                      
MemAddr(Col=15, Row=0)=0x0F                                                     
MemAddr(Col=0, Row=1)=0x40                                                      
MemAddr(Col=15, Row=1)=0x4F  

Hi, I have the same Display as you with an LCM1602 Serial Port-Expander. This lib you are using seems to be perfect for my Project, can you tell me the name and the author as well, that i can find it on mbed?

Thanks!

posted by Simon Aeschlimann 04 Jun 2017

@Simon, Here is the link for your reference https://developer.mbed.org/users/wim/code/TextLCD/

posted by Dhamodharan Krishnan 05 Jun 2017

1 Answer

6 years, 11 months ago.

The mbed libs use the 8bit format I2C addresses. That means you should shift left the 7bit format address that is conventionally used on the Arduino. So for the PCF8574A use 0x7E instead of 0x3F.

First, update the TextLCD lib (right click on the lib in your project) to make sure you have the latest version Then make sure you have identified the correct I2C portexpander module that is connected as backpack to your LCD. There are several different types around. Assuming you have the LCM1602 or a compatible clone:

Open the lib and adapt the TextLCD_config.h file, select LCM1602:

//Pin Defines for I2C PCF8574/PCF8574A or MCP23008 and SPI 74595 bus expander interfaces
//Different commercially available LCD portexpanders use different wiring conventions.
//LCD and serial portexpanders should be wired accordingly.
//
//Select Serial Port Expander Hardware module (one option only)
#define DEFAULT   0
#define ADAFRUIT  0
#define DFROBOT   0
#define LCM1602   1
#define YWROBOT   0
#define GYLCD     0
#define MJKDZ     0
#define SYDZ      0
#define WIDEHK    0
#define LCDPLUG   0 

In main select the correct slaveaddress:

// I2C Communication
I2C i2c_lcd(PB_9, PB_8); // SDA, SCL
 
//I2C Portexpander PCF8574
TextLCD_I2C lcd(&i2c_lcd, 0x7E, TextLCD::LCD16x2); // I2C bus, PCF8574 Slaveaddress, LCD Type

Compile and run the code

In case you see no scanning results at all there may also be a wiring problem somewhere.

Accepted Answer

Indeed great help Wim and all working fine now!!!

Here are the 2 steps followed for reference in future.

1. I have changed address to 0x7E as advised by you but nothing found in scanning

2. Then, I have removed the pullup resistors from LCD side and removed Logic Level Shifter out of this connection

Hello World at 57600 BAUD and 400KHz i2c Frequency                              
Using mbed.org Martin                                                           
ACK from the Device at Address 0x7e                                             
                                                                                
 1 Devices have been detected!                                                  
                                                                                
LCD Test. Columns=16, Rows=2                                                    
MemAddr(Col=0, Row=0)=0x00                                                      
MemAddr(Col=15, Row=0)=0x0F                                                     
MemAddr(Col=0, Row=1)=0x40                                                      
MemAddr(Col=15, Row=1)=0x4F

All good now and thanks again for your support.

posted by Dhamodharan Krishnan 10 Apr 2017