I have an LCD display attached to my Arduino Mega 2560 using the following code:
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C myLCD(0x27, 20, 4);
void setup() {
myLCD.begin();
myLCD.backlight();
}
void loop() {
myLCD.clear();
myLCD.print("Hello");
delay(2000);
}
This works fine and the display shows "Hello". But since I need certain custom functions for the display, I would like to move them all to a separate "ldc"-class that I created:
ldc.h
#ifndef Lcd_h
#define Lcd_h
#include "Arduino.h"
#include <LiquidCrystal_I2C.h>
class Lcd {
private:
unsigned int lcd_address = 0;
unsigned int rows = 0;
unsigned int columns = 0;
LiquidCrystal_I2C myLCD;
public:
// Construtor
Lcd();
void begin(unsigned int _columns, unsigned int _rows, unsigned int _lcd_address = 0x27);
void write();
};
#endif
lcd.cpp
#include "Lcd.h"
#include "Arduino.h"
#include <LiquidCrystal_I2C.h>
// Construtor
Lcd::Lcd() : myLCD(lcd_address, columns, rows) {
}
void Lcd::begin(unsigned int _columns, unsigned int _rows, unsigned int _lcd_address = 0x27) {
lcd_address = _lcd_address;
columns = _columns;
rows = _rows;
LiquidCrystal_I2C myLCD(lcd_address, columns, rows);
myLCD.begin();
myLCD.backlight();
}
void Lcd::write() {
myLCD.clear();
myLCD.print("hello");
Serial.println("I am here");
}
Main file
#include <LiquidCrystal_I2C.h>
#include "lcd.h"
Lcd thisLCD;
void setup() {
Serial.begin(9600);
thisLCD.begin(20, 4, 0x27);
}
void loop() {
thisLCD.write();
delay(2000);
}
The code compiles without errors. Also I do get "I am here" on the serial monitor, so the write() function is called. But the display does not show anything.
I suspect I am doing something wrong on the constructor:
Lcd::Lcd() : myLCD(lcd_address, columns, rows) {...
If I change the constructor to
Lcd::Lcd() : myLCD() {...
I get compile errors:
lcd.cpp: In constructor 'Lcd::Lcd()':
lcd.cpp:9:20: error: no matching function for call to 'LiquidCrystal_I2C::LiquidCrystal_I2C()'
Lcd::Lcd() : myLCD() {
^
What am I doing wrong? Is there a mistake on the constructor? Or is it something else?
Inside begin() method you define a local variable with the same name as your class field
LiquidCrystal_I2C myLCD(lcd_address, columns, rows);
At the end of the begin() method this object is destroyed. myLCD object in the write() method has nothing to do with the local object myLCD in begin()
In the constructor Lcd() maybe you can add some arguments to pass address, columns and rows.
As LiquidCrystal_I2C doesn't have methods to update these fields after creation, it seems to be the only way.
So
// Construtor
Lcd::Lcd(int addr, int ncols, int nrows) : myLCD(addr, ncols, nrows) {
//...
}