Compile error with LiquidCrystal_I2C within a class

Hello,

i have a problem using the LiquidCrystal_I2C library within my own class.
First of all, the code works fine if i put it directy into the main *.ino of a standard project.

Here is a part of the class:

class MenuCLS {
  
  #include <EEPROM.h>
  #include <LiquidCrystal_I2C.h>


  #define BACKLIGHT_PIN     3
  #define En_pin  2
  #define Rw_pin  1
  #define Rs_pin  0
  #define D4_pin  4
  #define D5_pin  5
  #define D6_pin  6
  #define D7_pin  7
  #define I2C_ADDR 0x27     //0x3F // Define I2C Address where the PCF8574A is
  LiquidCrystal_I2C lcd(I2C_ADDR,En_pin,Rw_pin,Rs_pin,D4_pin,D5_pin,D6_pin,D7_pin);

  
  public:
    void     Init(void);
    void     ReadButtons(void);

  private:
  void   readDataSet(void);
  void   set_menuindex(int rstat); 
  void   menu_text(void); 
  ...
  ...
  ...

Arduino says:

###############################################################

In file included from C:\Users\User\Documents\Arduino_8x8Truck_Slave_menu_8x8Truck_Slave_menu.ino:15:0:
MenuCLS.h:15: error: expected identifier before numeric constant
#define I2C_ADDR 0x27 //0x3F // Define I2C Address where the PCF8574A is
^
sketch\MenuCLS.h:16:25: note: in expansion of macro ‘I2C_ADDR’
LiquidCrystal_I2C lcd(I2C_ADDR,En_pin,Rw_pin,Rs_pin,D4_pin,D5_pin,D6_pin,D7_pin);
^
MenuCLS.h:15: error: expected ‘,’ or ‘…’ before numeric constant
#define I2C_ADDR 0x27 //0x3F // Define I2C Address where the PCF8574A is

###############################################################

The following errors are all like:

sketch\MenuCLS.h: In member function ‘void MenuCLS::set_menuindex(int)’:
MenuCLS.h:147: error: ‘((MenuCLS*)this)->MenuCLS::lcd’ does not have class type
lcd.setBacklightPin(BACKLIGHT_PIN,POSITIVE);
^

Even if i rename the label “I2C ADDR” the error still occurs.

What could be wrong?

greetings, Andreas

encapsulating preprocessor directives within a class definition…

  #include <EEPROM.h>
  #include <LiquidCrystal_I2C.h>


  #define BACKLIGHT_PIN     3
  #define En_pin  2
  #define Rw_pin  1
  #define Rs_pin  0
  #define D4_pin  4
  #define D5_pin  5
  #define D6_pin  6
  #define D7_pin  7
  #define I2C_ADDR 0x27     //0x3F // Define I2C Address where the PCF8574A is

prefer const over defines and pull the #include out to the top of the header.

If you are using an I2C LCD device, why are you not using the I2C interface? You should need only two data pins SCL and SDA for I2C. Looks like you should be using the LiquidCrystal interface not the LiquidCrystal_I2C one.

I using the i2c interface.
On the Display-board there is a Portexpander installed and the additional parameters are the pin config for it.

Now it works. I don’t know why, becauese i have made two changes.

First, i have renamed the instance name from “lcd” to something else.
And then i have move out all routines to an *.cpp file.
The classfile now contains only the headers of the routines.
I create the instance on the LCD lib now in that *.cpp file and it works.

cpp file

#include <LiquidCrystal_I2C.h>
#include "cfg.h"
#include "MenuCLS.h"
LiquidCrystal_I2C lcdsp(I2C_ADDR,En_pin,Rw_pin,Rs_pin,D4_pin,D5_pin,D6_pin,D7_pin);


void MenuCLS::Init(void) {
    lcdsp.begin (16,2); 
    pinMode(b_menu, INPUT);
    pinMode(b_inc, INPUT);
    pinMode(b_dec, INPUT);
    pinMode(b_back, INPUT);
    oldstat=-1;
    acstat=-1;
    readDataSet();
}
...
...
...

You are not using I2C interface if you are not using only SCL and SDA pins...period. You are bypassing it by using all those pins.

SDA and SCL are connected on the LCD board to the Port expander. The Display is connected to this Port expander too. The Display itself doesn't have an I2C interface. Every I2C Display i have ever seen is build like this.

Mine has both. It has an I2C interface board connected on the back of it which has a 4 pin header (+5v, GND, SCL, SDA). I can, if I wanted to, connect to all those 8 pins directly on the display board, and therefore bypass my I2C interface, but it makes no sense to do that. Why would I use 8 pins and bypass the I2C driver when I could use the supplied driver board and use only 2? You should grab the I2C pins SCL and SDA on your board and plug those into the arduino SCL/SDA pins and forget about all those other ones. Your code, when using I2C, should look something like: LiquidCrystal_I2C lcd( 0x27, 16, 2); // Mine is 16x2 but it is similar for other sizes.

If you have a "port expander" that uses I2C internally yet forces you to bypass it by connecting directly to CS, Dx, RW, RS and all that (which is NOT I2C), then your "port expander" is kinda useless. You might as well get rid of it and connect directly to the 8 LCD pins.

I suspect you are using the expander board incorrectly by not using its I2C pins to communicate with the arduino using the I2C interface. You only need 2 arduino pins to operate it using I2C interface. That's what LiquidCrystal_I2C.h is for. When you don't use I2C and instead use the 8 non-I2C pins to connect to the arduino, that's what LiquidCrystal.h is for.

AxeMurderer, you are very confused about the i2c library being used and how it works.

As Aldo666 was politely saying the LiquidCrystal_I2C class for the library he is using talks to a PCF8574 over I2C which in turn talks to a hd44780 display using an 8 bit i/o port, but it has to know how the 8 bit output port pins are attached to the hd44780 signals.

The constructor that you are referring to is for a different library that uses hard coded pin mappings. As a result, it will only work if the i2c backpack wires the PCF8574 output port pins exactly the way that library has hard coded them and as a result it only works on a fraction of the backpacks on the market. The library that Aldo666 is using allows the mapping to be configured so it can work on any/all backpacks.

The constructor for the library being used tells the library the PCF8574 i/o port pin mapping. The numbers in that constructor are the Px pin numbers on the PCF8574 chip, they have nothing to do with Arduino pins.

--- bill

That is correct bill. Thank you.

I have added an image of the display and a description of the way it is connected to my arduino.

Ok understood. Sorry about the confusion. Did not realize the mapping was not standardized.