Writing library that depends on other library

I would like to organize my project in MVC manner. In order to do so I need to write my own library for handling LCD screen which depends on LiquidScreen library.

Here is condensed sample of my code before separating it:

#include <LiquidCrystal.h>

LiquidCrystal lcd(12, 11, 5, 4, 3, 2);


void setup() {
  lcd.begin(16, 2);
}

void loop() {
  updateGpsPage(21.3456, 40.5683);

}

void updateGpsPage(double longi, double lati){
  lcd.clear();
  lcd.setCursor(0,0);
  lcd.print("lon: ");
  lcd.print(longi, 6);
  lcd.setCursor(0,1);
  lcd.print("lat: ");
  lcd.print(lati, 6);
  Serial.println(longi, 6);
}

It works.

And here it is after:

#include <LiquidCrystal.h>
#include <Libtest.h>

Libtest screen;

void setup() {

}

void loop() {
  screen.updateGpsPage(21.3456, 40.5683);

}

Libtest.h:

#ifndef Libtest_h
#define Libtest_h

#include "Arduino.h"
#include <LiquidCrystal.h>

class Libtest {
  public:
    void updateGpsPage(double longi, double lati);    
  private:
  	  	
};

#endif

Libtest.cpp:

#include "Arduino.h"
#include "Libtest.h"

//Constructor
Libtest::Libtest(){
	LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
	lcd.begin(16, 2);
}

void Libtest::updateGpsPage(double longi, double lati){
  lcd.clear();
  lcd.setCursor(0,0);
  lcd.print("lon: ");
  lcd.print(longi, 6);
  lcd.setCursor(0,1);
  lcd.print("lat: ");
  lcd.print(lati, 6);
  Serial.println(longi, 6);
}

I won’t post all possible places where I included LiquidCrystal lcd, but I just can’t seem to get it right.
So please, can someone tell me where to include what so that this simple code works.
Oh yeah… forgot to tell… I get “no lcd declared”, “Libtest does not name a type”, and all sort of error messages… Beginner

Don't paraphrase, copy and paste all error messages completely. Put them in Code Tags too.

This:

Libtest::Libtest(){
 LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
 lcd.begin(16, 2);
}

Makes 'lcd' a local variable in the constructor. It goes out of scope / existence as soon as that function exits. I'd do one of two things. Either make 'lcd' a private object within your new class or have your new class inherit from the 'LiquidCrystal' class. Without a complete picture of what you're trying to do, I can't make a recommendation as to which. It's kind of a subjective call anyway. Ask yourself the question: "Does my class HAVE a LiquidCrystal object, or IS my class a type of LiquidCrystal object?"

I went with first case, making lcd private object of my new class Libtest. I’m not even sure how to do the second (sorry, I’m new in programming). In my project I need to have GUI with some 12 different pages, some of them updating frequently, so I wanted to separate this from the rest of my sketch which will make future changes easier.

So, here it is… sketch:

#include <LiquidCrystal.h>
#include <Libtest.h>

Libtest screen;

void setup() {

}

void loop() {
  screen.updateGpsPage(21.3456, 40.5683);
}

Libtest.h:

#ifndef Libtest_h
#define Libtest_h

#include "Arduino.h"
#include <LiquidCrystal.h>


class Libtest {
  public:
    void updateGpsPage(double longi, double lati);
    
  private:
  	LiquidCrystal lcd;  	
};

#endif

Libtest.cpp:

#include "Arduino.h"
#include "Libtest.h"

//Constructor
Libtest::Libtest(){
	lcd(12, 11, 5, 4, 3, 2);
	lcd.begin(16, 2);
}

void Libtest::updateGpsPage(double longi, double lati){
  lcd.clear();
  lcd.setCursor(0,0);
  lcd.print("lon: ");
  lcd.print(longi, 6);
  lcd.setCursor(0,1);
  lcd.print("lat: ");
  lcd.print(lati, 6);
  Serial.println(longi, 6);
}

…and error messages:

Arduino: 1.8.9 (Windows 10), Board: "Arduino/Genuino Mega or Mega 2560, ATmega2560 (Mega 2560)"

testingLibrary:4:9: error: use of deleted function 'Libtest::Libtest()'

 Libtest screen;

         ^

In file included from C:\Users\denisov\Documents\Arduino\testingLibrary\testingLibrary.ino:2:0:

C:\Users\denisov\Documents\Arduino\libraries\Libtest/Libtest.h:8:7: note: 'Libtest::Libtest()' is implicitly deleted because the default definition would be ill-formed:

 class Libtest {

       ^

C:\Users\denisov\Documents\Arduino\libraries\Libtest/Libtest.h:8:7: error: no matching function for call to 'LiquidCrystal::LiquidCrystal()'

In file included from C:\Users\denisov\Documents\Arduino\testingLibrary\testingLibrary.ino:1:0:

C:\Program Files (x86)\Arduino\libraries\LiquidCrystal\src/LiquidCrystal.h:55:3: note: candidate: LiquidCrystal::LiquidCrystal(uint8_t, uint8_t, uint8_t, uint8_t, uint8_t, uint8_t)

   LiquidCrystal(uint8_t rs, uint8_t enable,

   ^

C:\Program Files (x86)\Arduino\libraries\LiquidCrystal\src/LiquidCrystal.h:55:3: note:   candidate expects 6 arguments, 0 provided

C:\Program Files (x86)\Arduino\libraries\LiquidCrystal\src/LiquidCrystal.h:53:3: note: candidate: LiquidCrystal::LiquidCrystal(uint8_t, uint8_t, uint8_t, uint8_t, uint8_t, uint8_t, uint8_t)

   LiquidCrystal(uint8_t rs, uint8_t rw, uint8_t enable,

   ^

C:\Program Files (x86)\Arduino\libraries\LiquidCrystal\src/LiquidCrystal.h:53:3: note:   candidate expects 7 arguments, 0 provided

C:\Program Files (x86)\Arduino\libraries\LiquidCrystal\src/LiquidCrystal.h:50:3: note: candidate: LiquidCrystal::LiquidCrystal(uint8_t, uint8_t, uint8_t, uint8_t, uint8_t, uint8_t, uint8_t, uint8_t, uint8_t, uint8_t, uint8_t)

   LiquidCrystal(uint8_t rs, uint8_t rw, uint8_t enable,

   ^

C:\Program Files (x86)\Arduino\libraries\LiquidCrystal\src/LiquidCrystal.h:50:3: note:   candidate expects 11 arguments, 0 provided

C:\Program Files (x86)\Arduino\libraries\LiquidCrystal\src/LiquidCrystal.h:47:3: note: candidate: LiquidCrystal::LiquidCrystal(uint8_t, uint8_t, uint8_t, uint8_t, uint8_t, uint8_t, uint8_t, uint8_t, uint8_t, uint8_t)

   LiquidCrystal(uint8_t rs, uint8_t enable,

   ^

C:\Program Files (x86)\Arduino\libraries\LiquidCrystal\src/LiquidCrystal.h:47:3: note:   candidate expects 10 arguments, 0 provided

C:\Program Files (x86)\Arduino\libraries\LiquidCrystal\src/LiquidCrystal.h:45:7: note: candidate: constexpr LiquidCrystal::LiquidCrystal(const LiquidCrystal&)

 class LiquidCrystal : public Print {

       ^

C:\Program Files (x86)\Arduino\libraries\LiquidCrystal\src/LiquidCrystal.h:45:7: note:   candidate expects 1 argument, 0 provided

C:\Program Files (x86)\Arduino\libraries\LiquidCrystal\src/LiquidCrystal.h:45:7: note: candidate: constexpr LiquidCrystal::LiquidCrystal(LiquidCrystal&&)

C:\Program Files (x86)\Arduino\libraries\LiquidCrystal\src/LiquidCrystal.h:45:7: note:   candidate expects 1 argument, 0 provided

exit status 1
use of deleted function 'Libtest::Libtest()'

This report would have more information with
"Show verbose output during compilation"
option enabled in File -> Preferences.

Not sure what to do now…

I found that I haven’t included constructor in “public” when defining class in libtest.h. Also, when making private LiquidCrystal object I have obviously made a mistake not passing arguments… Now .h looks like this:

#ifndef Libtest_h
#define Libtest_h

#include "Arduino.h"
#include <LiquidCrystal.h>

class Libtest {
  public:
    Libtest();
    void updateGpsPage(double longi, double lati);
    
  private:
  	LiquidCrystal lcd(12, 11, 5, 4, 3, 2);  	
};

#endif

And .cpp:

#include "Arduino.h"
#include "Libtest.h"

//Constructor
Libtest::Libtest(){
	lcd.begin(16, 2);
}

void Libtest::updateGpsPage(double longi, double lati){
  lcd.clear();
  lcd.setCursor(0,0);
  lcd.print("lon: ");
  lcd.print(longi, 6);
  lcd.setCursor(0,1);
  lcd.print("lat: ");
  lcd.print(lati, 6);
  Serial.println(longi, 6);
}

Sketch is still the same.

And list of error messages is lot shorter:

Arduino: 1.8.9 (Windows 10), Board: "Arduino/Genuino Mega or Mega 2560, ATmega2560 (Mega 2560)"

In file included from C:\Users\denisov\Documents\Arduino\testingLibrary\testingLibrary.ino:2:0:

C:\Users\denisov\Documents\Arduino\libraries\Libtest/Libtest.h:13:22: error: expected identifier before numeric constant

    LiquidCrystal lcd(12, 11, 5, 4, 3, 2);   

                      ^

C:\Users\denisov\Documents\Arduino\libraries\Libtest/Libtest.h:13:22: error: expected ',' or '...' before numeric constant

exit status 1
Error compiling for board Arduino/Genuino Mega or Mega 2560.

But I still can’t see what’s wrong…

private:
  	LiquidCrystal lcd(12, 11, 5, 4, 3, 2);

This is not valid code. You can't call a constructor inside a class declaration. Use an initializer list instead:

.h

//...
  private:
  	LiquidCrystal lcd;

.cpp

//Constructor
Libtest::Libtest() : lcd(12, 11, 5, 4, 3, 2) {
	lcd.begin(16, 2);
}

Thank you very much for your help. It works!

If it is not too much to ask I would very much appreciate if you could explain what initializer list is and where it is used?

Don’t call lcd.begin() from the constructor, the hardware may not be ready to access the pins. Provide a begin method that you call from setup(). That will call lcd.begin().

Also, to make your code more flexible, use parameters:

#include <LiquidCrystal.h>

class Libtest {
  public:
    Libtest(uint8_t rs, uint8_t enable, uint8_t d0, uint8_t d1, uint8_t d2, uint8_t d3);
    void begin(uint8_t cols, uint8_t rows);

  private:
    LiquidCrystal lcd;

};

Libtest::Libtest(uint8_t rs, uint8_t enable, uint8_t d0, uint8_t d1, uint8_t d2, uint8_t d3) :
  lcd(rs, enable, d0, d1, d2, d3) {}

void Libtest::begin(uint8_t cols, uint8_t rows) {
  lcd.begin(cols, rows);
}

Libtest myLib(12, 11, 5, 4, 3, 2);

void setup() {
  myLib.begin(16,2);
}

void loop() {
}

See: When do we use Initializer List in C++?

Will do so. Thanks.