Inclure LiquidCrystal dans une classe perso

Bonjour à tous !

Voilà en fait tout est dit dans le titre, pour des raisons de clarté dans mon code je m'essai aux classes, et j'aimerai inclure la librairie LiquidCrystal dedans. Pour l'instant j'ai juste fait un petit code de test.

J'inclue la librairie dans mes fichiers .ccp et .h mais l'IDE arduino ne compile pas et m'affiche :

Arduino\libraries\Test\Test.cpp:10: error: 'lcd' was not declared in this scope.

En fouillant sur internet j'ai vu que l'IDE arduino fonctionnait bizarrement au niveau des classes et intégrations de librairies, mais j'ai pas trouvé de solutions à mon problème.

Si vous pouviez jeter un coup d'oeil ce serait sympa :

fichier .ccp :

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

Test::Test()
{}

void Test::texte_1()
{
    lcd.clear();
    lcd.setCursor(0,0);
    lcd.print("YOYO");
    delay(3000);
}

fichier .h

#ifndef TEST_H
#define TEST_H

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

class Test
{
    public:
        Test();
        void texte_1();

};

#endif // TEST_H

et le sketch :

#include <Test.h>
#include <LiquidCrystal.h>

LiquidCrystal lcd(2,3,4,5,6,7);
Test test();


void setup()
{
  lcd.begin(20,4);
  lcd.clear();
}

void loop()
{
  lcd.setCursor(0,0);
  lcd.print("Yopla");
  delay(3000);
}

Merci et bon dimanche à tous :slight_smile:

Bonsoir,
Je ne sais pas si cela peut être utile mais regarde ici : [RESOLU] syntaxe #include - #7 by icare - Français - Arduino Forum
Et dans cas, il déclarer "toto.cpp" et "toto.h" au lieu de <toto.cpp> et <toto.h>
@+

Merci pour ta réponse icare,

Malheureusement j'ai déjà essayé et comme ton lien l'indique :

<> la recherche se fait dans les répertoires définis pour la chaîne de compilation
"" le chemin est relatif par rapport à l'emplacement des sources.

Et j'ai placé la librairie dans le dossier librairie de l'arduino donc à priori c'est ça ?

Par contre j'ai lu un lien pas mal sur le forum, la personne voulait introduire la librairie servo, et il s'en serait sorti en appelant la fonction begin dans l'étiquette private de la classe, pour qu'il est un "point de rappel" dans le sketch. Enfin je m'embrouille et doit dire de grosse âneries, je re-lirai tout ça demain ! Si vous avez des suggestions n'hésitez pas :slight_smile:

Hello,

Tu utilise dans ton fichier .cpp (Test) une variable globale (lcd) créée dans ton fichier de base... Ca ne peut pas marcher.

Il faut avoir une instance de la classe LiquidCristal dans ta classe Test pour pouvoir l'utiliser (soit créée dans la classe elle même, soit passée en paramètre au constructeur par exemple).

Bonjour,

La variable "lcd" n'existe pas dans ta classe -> erreur de compilation (forcément)

Trois choix :

  • soit tu déclares "lcd" dans ton sketch en variable globale et en "extern" dans ton .h (c'est très moche mais ça marche)
  • soit tu déclares une instance de LiquidCrystal dans ton .h (déjà plus propre)
  • soit tu déclares un pointeur/référence sur un objet de type LiquidCrystal dans ton .h que tu initialises via ton constructeur

Choix n°3 :

#ifndef TEST_H
#define TEST_H

class LiquidCrystal;

class Test {
  protected:
    LiquidCrystal& _lcd;

  public:
    Test(LiquidCrystal& lcd);
    void texte_1();
};
#endif // TEST_H
#include <Arduino.h>
#include <LiquidCrystal.h>
#include "Test.h"

Test::Test(LiquidCrystal& lcd) : _lcd(lcd) {
}

void Test::texte_1() {
  _lcd.clear();
  _lcd.setCursor(0,0);
  _lcd.print(F("YOYO"));
  delay(3000);
}
#include <Test.h>
#include <LiquidCrystal.h>

LiquidCrystal lcd(2, 3, 4, 5, 6, 7);
Test test(lcd);

void setup() {
  lcd.begin(20, 4);
  lcd.clear();
}

void loop() {
  lcd.setCursor(0, 0);
  lcd.print(F("Yopla"));
  delay(3000);
}

E-norme... Merci, ça va me donner des ailes ce coup de pouce, je vais bosser les pointeurs !

Salut à tous,

skywodd, pourrais-tu m'expliquer pourquoi tu as utilisé le "F" dans _lcd.print(F("YOYO")); ?

Et pourquoi doit-on mettre le tiret du bas pour LiquidCrystal& _lcd; ?
De manière générale le tiret du bas sert à quoi en fait ?

Merci :slight_smile:

discoveryarduino:
skywodd, pourrais-tu m'expliquer pourquoi tu as utilisé le "F" dans _lcd.print(F("YOYO")); ?

C'est pour placer le texte en mémoire flash et non en RAM, c'est une bonne habitude à prendre.
Détails techniques : PROGMEM - Arduino Reference

discoveryarduino:
Et pourquoi doit-on mettre le tiret du bas pour LiquidCrystal& _lcd; ?
De manière générale le tiret du bas sert à quoi en fait ?

Le "_" est une convention de nommage pour les attributs d'une classe.
Il en existe d'autre, ce n'est pas obligatoire de suivre les conventions mais pareil c'est une bonne habitude à prendre.

Merci beaucoup skywood, tes infos m'ont beaucoup aidé dans mes recherches :wink:

Par contre il y a quelque chose que j'ai du mal à comprendre :

J'ai deux classes, dans ma classe A j'ai une variable m_x privé qui s'incrémente à chaque fois que j'appuie sur un bouton poussoir.

Comment au moyens de pointeurs je peux récupérer cette valeur et la modifier dans ma classe B ?

Merci !

Re-bonjour, je vais donner un peu plus de détails sur ma question d'hier qui n'était pas super explicite.

En fait, pour m’entraîner, je souhaite afficher un menu sur un lcd 20x4.
Je suis arrivé à le faire, grâce à skywood, je peux naviguer dedans sans problème.
Dans une classe, je récupère grâce à l'attribut privé "m_x" la position du curseur sur l'écran lcd.
(Quand on appui sur le bouton haut, m_x s'incrémente, et quand on appui sur le bouton bas m_x décrémente.)

Ce que je souhaite, c'est récupérer cette variable m_x dans une autre classe, pour bénéficier de cette position du curseur.

Voici mon code (c'est un code épuré pour vous montrer) :

Test.h

#ifndef TEST_H
#define TEST_H

class Test {

public : 
void PositionCurseur();

private : 
int m_x;

};

#endif

Test.ccp

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

Test :: Test(){}

void Test::PositionCurseur(){

if (haut.isPressed() ){
 m_x=m_x++; 
 if(m_x >3){
 m_x=0;}
}

if(bas.isPressed() ){
 m_x=m_x--;
 if(m_x < 0){
 m_x=3;}
}

}

surTest.ccp

#ifndef SURTEST_H
#define SURTEST_H

class surTest {

public : 

void afficherPositionCurseur();

};

#endif

surTest CCP

#include "surTest.h"
#include <Arduino.h>
#include <Test.h>

surTest :: surTest(){}

void surTest :: AfficherPositionCurseur(){

lcd.print ( m_x );

}

J'ai testé différentes méthodes que j'ai trouvé sur internet, pointeur *, mutateur set, classe amie...
Je dois mal m'y prendre, je me tire les cheveux avec les pointeurs c'est la galère ^^

Si vous pouviez me mettre sur une piste... j'en serais très reconnaissant !

google -> getter() / setter() :wink:

int Test :: getX(){
  return m_x;
}

T'inquiètes pas Skywood pour getter et setter mes pages google sont violettes ^^

ça donnerait quelque chose comme ça ?

test.h

#ifndef TEST_H
#define TEST_H
 
class Test {
 
public :
void PositionCurseur();
int getValue() const;
 
private :
int m_x;
 
};
 
#endif

test.ccp

#include "Test.h"
#include <Arduino.h>
#include <Button.h>
#include<LiquidCrystal.h>
 
Test :: Test(){}
 
void Test::PositionCurseur(){
 
if (haut.isPressed() ){
 m_x++;
 if(m_x >3){
 m_x=0;}
}
 
if(bas.isPressed() ){
 m_x--;
 if(m_x < 0){
 m_x=3;}
}
 
}
 
int Test::getValue() const {
return m_x; }

surTest.h

#ifndef SURTEST_H
#define SURTEST_H
 
class Test;
class surTest {
 
public :
 surTest(Test& test);
void afficherPositionCurseur();
 
private :
    Test& _test;
     
};
 
#endif

surTest.ccp

#include "surTest.h"
#include <Arduino.h>
#include <Test.h>
 
surTest :: surTest(Test& test): _test(test){}
 
void surTest :: AfficherPositionCurseur(){
 
_test.getValue();
lcd.print(m_x);
 
}

Ô joie ya même le const sur le getter :slight_smile:

Par contre ce morceau va pas :

_test.getValue();
lcd.print(m_x);

Le getter te retourne la valeur d'un attribut privé, donc ici m_x n'as pas de sens.

Il faut faire :

lcd.print(_test.getValue());