including libraries.. into libraries

so, i've got my little "menu" library and was trying to make it works when suddenly, after a little modification, it said: 'LiquidCrystal' was not declared in this scope
after a little debugging i realized that the problem could be in the way i attached the liquidcrystal library into my library. the question is: how should i include the liquidcrystal library into mine?

the question is: how should i include the liquidcrystal library into mine?

No, the question is how DID you include the LiquidCrystal library? And, did you include the LiquidCrystal header file in your sketch?

You are not allowed to hide the use of a library.

when i included the LiquidCyristal library in the my_menu.h library it didn't work, and so if the inclusion was in the .cpp file. i also get the same error if i don't include thwe library, nowhere.

when i included the LiquidCyristal library in the my_menu.h library it didn't work

"it didn't work" has to be the most overused phrase on this forum. It doesn't tell us anything.

"When I use this code, it fails to compile, with this error message" tells us something.

"When I use this code, it compiles, but nothing appears on the LCD when I run the code" tells us something.

"it didn't work" tells us nothing.

i also get the same error if i don't include thwe library, nowhere.

Lucky you.

If you care to quit dancing around, and post some code and error messages, we'll be happy to help.

as i've said on the first post, i get the " 'LiquidCrystal' was not declared in this scope " message. so, here's the code for the header:

#ifndef MenuLCD_h
#define MenuLCD_h

#include "Arduino.h"

// identificatori degli stati (bottoni e stato di idle)
#define UP 0
#define DOWN 6
#define SEL 2
#define BACK 4
#define IDLE 10

class MenuLCD
{
public:
typedef struct // database menù
{
byte id; // PK: identificatore univoco della voce
byte id_par; // FK: riferimento al menu genitore della voce
char str[18]; // Stringa contenente il testo visualizzato
} MenuItem;
MenuLCD(byte rs,
byte enable,
byte d4,
byte d5,
byte d6,
byte d7,
String intro,
MenuItem _menu
);
MenuItem menu; // Database contenente le voci del menù
byte menu_lenght; // Numero di voci del menu
byte current_menu; // Menu corrente
byte current_sel; // Voce attualmente selezionata
byte pin; // Pin della pulsantiera
boolean sthToDo; // Necessità di eseguire azioni
String intro_str; // Stringa contentente l'intro
byte getFirstOption(byte submenu);
byte getLastOption(byte submenu);
byte getPreviousMenu(byte submenu);
String getMenuTitle(byte submenu);
void showIntro();
void showMenu();
virtual void doSomething(byte action);
byte buttonCheck();
void editSetting(String title, String descr, byte *val, char *list[]);
void editSetting(String title, String descr, byte *val, byte min, byte max);

private:
static byte sel_dot[8]; // Carattere indicante la selezione
byte old_menu; // Menu precedente
byte old_sel; // Voce precedentemente selezionata
boolean old_sthToDo; // Stato precedente di sthToDo
void menuPrint(byte submenu, byte sel);

};

#endif

and here's the one for the MenuLCD.cpp file:

#include "MenuLCD.h"

MenuLCD::MenuLCD(byte rs, byte enable, byte d4, byte d5, byte d6, byte d7, String intro, MenuItem _menu)
{
// inizializza le variabili della navigazione
current_menu = 0;
current_sel = 1;
sthToDo = false;
old_menu = 255;
old_sel = 255;
old_sthToDo = false;
// inizializza il display
LiquidCrystal lcd(rs, enable, d4, d5, d6, d7);
menu_lenght = sizeof(_menu)/sizeof(MenuItem);
lcd.begin(20, 4);
// inizializza il carattere per la selezione
sel_dot[0] = B00000;
sel_dot[1] = B00100;
sel_dot[2] = B01110;
sel_dot[3] = B11111;
sel_dot[4] = B01110;
sel_dot[5] = B00100;
sel_dot[6] = B00000;
lcd.createChar(1, sel_dot);
}

i've tried to put the #include <LiquidCrystal.h> in both of them, using various combination, but nothing changed: all i've got was that error message. by the way, this is the complete compilation log:

In file included from MenuLCD.cpp:7:
/MenuLCD.h:11:27: error: LiquidCrystal.h: No such file or directory
MenuLCD.cpp: In constructor 'MenuLCD::MenuLCD(byte, byte, byte, byte, byte, byte, String, MenuLCD::MenuItem)':
MenuLCD.cpp:18: error: 'LiquidCrystal' was not declared in this scope
MenuLCD.cpp:18: error: expected `;' before 'lcd'
MenuLCD.cpp:20: error: 'lcd' was not declared in this scope

White space is nice. It can be used to make your code more readable.

Unless I am going blind, I don't see that the header file includes LiquidCrystal.h anywhere. Nor, do I see that the source file includes it, either.

Nor, do I see the sketch that uses the MenuLCD library.

i think you're going blind, because after the two pieces of code i said:

i've tried to put the #include <LiquidCrystal.h> in both of them, using various combination, but nothing changed: all i've got was that error message. by the way, this is the complete compilation log:

i thought it was enough self-explanatory.
also, i don't see how the problem could stay in the sketch file.

also, i don't see how the problem could stay in the sketch file.

Then, you don't understand the build process.

All files in the sketch directory are copied to a temp, directory for the build process. All include files referenced by the sketch are copied to that temp. directory, too, along with the associated source files.

Only the stuff in that temp. directory is involved in the build.

So, if sketch.pde (or .ino) does not include LiquidCrystal.h, LiquidCrystal.h and LiquidCrystal.cpp are NOT copied to the temp. directory, and are not available for MenuLCD to include.

it means that the LiquidCrystal.h library has to be included in both the sketch and the library .h file?

it means that the LiquidCrystal.h library has to be included in both the sketch and the library .h file?

Yes. See reply #1.

ok, that's weird. it looks so redundant :confused:

however, thanks a lot! can i ask you a little bit of help?

i've just added this code:

// menuPrint
// stampa il menù sul display
// submenu: id del menu da stampare
// sel: id della voce da evidenziare
void menuPrint(byte submenu, byte sel)
{
byte screen_line = 0;
byte i;
String titolo;

lcd.clear();
lcd.setCursor(0, screen_line);
for(i=0; i<menu_lenght; i++)
{
if(menu*.id == submenu)*

  • {*
    _ titolo=menu*.str;_
    _
    titolo.toUpperCase();_
    _
    lcd.print(titolo);_
    screen_line++;
    _
    }*_

if(menu*.id_par == submenu)
_ {
if(menu.id == sel)
{_

lcd.setCursor(0, screen_line);
_ lcd.write(1);
lcd.print(" ");
lcd.print(menu.str);
}
else*

* {_
lcd.setCursor(2, screen_line);
_ lcd.print(menu.str);
}_

screen_line++;
_ }
}
}
[/quote]*

to my menuLCD.cpp file, just after the constructor declaration (see the code posted above). when trying to compile, it says that "lcd was not declared in this scope" (on the line lcd.clear();). then i thought "that's ok, it's because the "lcd" is declared into the constructor, allowing me only to use it as long as my constructor is running". so i put the "LiquidCrystal lcd;" in the .h file, among the other variables declarations, but then the compiler says : 'LiquidCrystal' does not name a type.
i have no idea of how to initialize the screen (my lcd variable) in order to use it in all my other methods._

ok, that's weird. it looks so redundant :confused:

Yes, and no. It simplifies the build process, for one thing. For another, it prevents you from using a library that uses a library that uses a library that (tries to) use a library that you don't have.

Declare up front that your sketch will need library A, B, C, and D. No need to chase after libraries. All required libraries are defined up front.

to my menuLCD.cpp file, just after the constructor declaration (see the code posted above). when trying to compile, it says that "lcd was not declared in this scope" (on the line lcd.clear()smiley-wink. then i thought "that's ok, it's because the "lcd" is declared into the constructor, allowing me only to use it as long as my constructor is running". so i put the "LiquidCrystal lcd;" in the .h file, among the other variables declarations, but then the compiler says : 'LiquidCrystal' does not name a type.

You do need to move the declaration and initialization of the instance out of the constructor. As you have discovered, a local variable in the constructor is of no use to the rest of the class.

You need to add a line to the header file that says that lcd is an instance of the LiquidCrystal class. The, it needs to be instanced/valued at the same time as the constructor of your class is called:

MenuLCD::MenuLCD(byte rs, byte enable, byte d4, byte d5, byte d6, byte d7, String intro, MenuItem _menu), lcd(rs, enable, d4, d5, d6, d7)

PaulS:
You need to add a line to the header file that says that lcd is an instance of the LiquidCrystal class. The, it needs to be instanced/valued at the same time as the constructor of your class is called:

MenuLCD::MenuLCD(byte rs, byte enable, byte d4, byte d5, byte d6, byte d7, String intro, MenuItem _menu), lcd(rs, enable, d4, d5, d6, d7)

to be honest, i didn't understand. how can i say that lcd is an instance of LiquidCrystal?

how can i say that lcd is an instance of LiquidCrystal?

LiquidCrystal lcd;

nive. so i added the LiquidCrystal lcd; statement among all the other declarations in the MenuLCD.h, then, i modified my MenuLCD.cpp constructor like this:

MenuLCD::MenuLCD(byte rs, byte enable, byte d4, byte d5, byte d6, byte d7, String intro, MenuItem _menu), lcd(rs, enable, d4, d5, d6, d7)
{
  // inizializza le variabili della navigazione
  current_menu = 0;
  current_sel = 1;
  sthToDo = false;
  [all the rest]

but the compiler says:

MenuLCD.cpp:8: error: declaration of 'MenuLCD::MenuLCD(byte, byte, byte, byte, byte, byte, String, MenuLCD::MenuItem)' outside of class is not definition
MenuLCD.cpp:8: error: expected constructor, destructor, or type conversion before '(' token

It might (probably will) be a lot easier if MenuLCD derived from LiquidCrystal.

Then, you could initialize the base class using
MenuLCD::MenuLCD(a bunch of args) : LiquidCrystal(most of those args)

Then, since this (a special C++ variable) IS an instance of LiquidCrystal, you could simply

this->print(someMessage);

(Or, the this-> bit is not really needed, so just print(someMessage):wink:

If this is too complicated, just make lcd a global variable, declared in the header file, outside of the class definition.

If this is too complicated, just make lcd a global variable, declared in the header file, outside of the class definition.

never thought it could be possible!! thanks!

ps: just before pressing "post", here what the compiler says about that: no matching function for call to 'LiquidCrystal::LiquidCrystal()'

It's unfortunate that the LiquidCrystal library does not play by the rules. Every class is supposed to have a no-argument constructor. All the stuff that the class needs to do it's work is supposed to be defined in the begin() method.

However, there is only one LCD attached to the Arduino, presumably. The LCD should be available to the sketch as well as the MenuLCD library. So, creating the instance of the LiquidCrystal class in the MenuLCD class is not the best approach.

Create the LiquidCrystal instance in the sketch, and pass a reference to that instance to the MenuLCD class.