SerialLCD et utilisation de class!

Bonjour,

J’ai quelques soucis pour afficher au coeur d’une classe via un SerialLCD (http://www.seeedstudio.com/depot/grove-serial-lcd-p-773.html) :

Voici mon code principal :

// include the library code:
#include <SerialLCD.h>
#include <SoftwareSerial.h> //this is a must

// initialize the library
SerialLCD slcd(0,1);//this is a must, assign soft serial pins

void setup() {
  // set up : 
  slcd.begin();
  // Print a message to the LCD.
  slcd.print("hello, world!");
}

void loop() {
  // Turn off the blinking cursor:
  slcd.noBlink();
  delay(1000);
   // Turn on the blinking cursor:
  slcd.blink();
  delay(1000);
  
  classX XXXX;
  slcd.print(XXXX.val);

  XXXX.affiche();
}

La déclaration de la classe.h :

class classX{
public:
  int val;

  classX();
  void affiche();

};

Et le code de la classe.cpp :

#include <SerialLCD.h>
#include <SoftwareSerial.h> //this is a must

#include "classX.h"

classX::classX(){
  val=10;
}

void classX::affiche(){
  SerialLCD slcd(0,1);//this is a must, assign soft serial pins
  slcd.print("Test Affichage...");
  // Ne fais rien!!!
}

La méthode affiche() est simple ici mais dans le projet final, celle-ci traitera des attributs de la classe et de l’affichage, d’où la nécessité de pouvoir faire l’affichage dans la méthode affiche().

Mes connaissances en POO ne me permettent pas de savoir ce qu’il faut écrire pour que ça marche…
Si une âme charitable pouvait me mettre sur la voie…

Merci d’avance.
Olivier

Bin déjà tu réinstancies slcd dans affiche alors que tu l'as déjà fait dans ton programme principal.

Deuxième remarque : 1 et 0 ce sont les pins série hardware

J’ai fait le test avec la déclaration suivante :

classX.cpp :

#include <SerialLCD.h>
#include <SoftwareSerial.h> //this is a must

#include "classX.h"

classX::classX(){
  val=10;
}

void classX::affiche(){
  //SerialLCD slcd(0,1);//this is a must, assign soft serial pins
  slcd.print("Test Affichage...");

}

Mais je tombe sur l’erreur :
error: ‘slcd’ was not declared in this scope
Comme si les variables globales n’étaient pas vues à l’intérieur de la classe!

J’ai oublié de précisé, c’est fait avec des .h et .cpp

Et oui, 1 et 0 ce sont les pins série hardware. donc je débranche le LCD pour faire l’upload et je teste l’ensemble sur batterie.

A+
Olivier

Bernardino:
Et oui, 1 et 0 ce sont les pins série hardware. donc je débranche le LCD pour faire l'upload et je teste l'ensemble sur batterie.

Oué sauf que ça utilise softwareserial donc tu peux le mettre sur n'importe quel pin, le port série ça aide à débuguer :wink:

Sinon il me semble que c'est normal : qu'on m'arrête si me trompe mais ce qui est public dans la librairie est accessible dans le programme, mais pas l'inverse. Donc il faut que tu l'instancies à l'instanciation de ClasseX :

classX::classX(int _RX, int TX){
SerialLCD slcd(RX,TX);
slcd.begin();
  val=10;
}

Bonjour,

Voilà le test du matin

en écrivant ceci dans le fichier classX.cpp :

#include "classX.h"

classX::classX(){
  SerialLCD slcd(0,1);//this is a must, assign soft serial pins
  slcd.begin();
  val=10;
}

void classX::affiche(){
  slcd.print("Test Affichage...");

}

J’ai le message :
error: ‘slcd’ was not declared in this scope

Ce qui me semble normal puisque slcd ne fait pas parti des attributs de classX

J’ai donc modifié le fichier classX.h en conséquence :

#include <SerialLCD.h>
#include <SoftwareSerial.h> //this is a must


class classX{
public:
  SerialLCD slcd;
  int val;

  classX();
  void affiche();

};

Mais je tombe sur le message :

classX.cpp: In constructor ‘classX::classX()’:
classX.cpp:4: error: no matching function for call to 'SerialLCD::SerialLCD()'
C:\Users\Olivier\Documents\Arduino\libraries\SerialLCD/SerialLCD.h:68: note: candidates are: SerialLCD::SerialLCD(uint8_t, uint8_t)
C:\Users\Olivier\Documents\Arduino\libraries\SerialLCD/SerialLCD.h:65: note: SerialLCD::SerialLCD(const SerialLCD&)

Je suis donc toujours à la recherche d’une solution à mon souci…

A+
Olivier

Bin oui, si tu ne mets pas les arguments ça ne marche pas :wink:

Vire la déclaration du .h et ajoute les librairies SerialLCD.h SoftwareSerial.h dans .cpp

Bin non, comme ça :

#include <SerialLCD.h>
#include <SoftwareSerial.h> //this is a must

#include "classX.h"

classX::classX(){
  SerialLCD slcd(0,1);//this is a must, assign soft serial pins
  slcd.begin();
  val=10;
}

void classX::affiche(){
  slcd.print("Test Affichage...");

}

J’ai le message suivant à la compil :

classX.cpp: In member function ‘void classX::affiche()’:
classX.cpp:13: error: ‘slcd’ was not declared in this scope =(

Je viens de trouver une solution qui n’est peutêtre pas très élégante, vous me direz…

Puisque je n’arrive pas à déclarer et à utiliser un objet SerialLCD dans ma classe, je me suis dis pourquoi pas utiliser celui déclarer en global en y faisant référence via son adresse. Et voilà ce que j’ai écris qui semble fonctionner pour les premiers tests effectués :

pour le fichier classX.h :

#include <SerialLCD.h>
#include <SoftwareSerial.h> //this is a must

class classX{
public:
  SerialLCD* currentLCD;
  int val;

  classX(SerialLCD*);
  void affiche();

};

Pour le fichier classX.cpp :

#include "classX.h"

classX::classX(SerialLCD* wLCD){
  currentLCD = wLCD;
  val=10;
}

void classX::affiche(){
  (*currentLCD).print("Test Affichage...");
}

Et pour l’appel de tout ça :

// include the library code:
#include <SerialLCD.h>
#include <SoftwareSerial.h> //this is a must

#include "classX.h"

// initialize the library
SerialLCD slcd(0,1);//this is a must, assign soft serial pins

void setup() {
  // set up : 
  slcd.begin();
  // Print a message to the LCD.
  slcd.print("hello, world!");
}

void loop() {
  // Turn off the blinking cursor:
  slcd.noBlink();
  delay(1000);
   // Turn on the blinking cursor:
  slcd.blink();
  delay(1000);
  
  classX XXXX(&slcd);
  slcd.print(XXXX.val);
    
  XXXX.affiche();
  
}

Vos remarques seront les biens venues.

Olivier

Ah jsuis couillon, il faut imbriquer les class, exemple : ds18b20/ds18b20.h at master · JChristensen/ds18b20 · GitHub

Désolé mais je n'ai pas tout compris!...
Des explications complémentaires sont nécessaire pour mettre en oeuvre cette technique.

A+
Olivier

Regarde le début du .h de la lib DS18B20 :

#include <OneWire.h>              //http://www.pjrc.com/teensy/td_libs_OneWire.html

class DS18B20 : public OneWire
{
    public:
        DS18B20(uint8_t pin);

Et le début du .cpp :

DS18B20::DS18B20(uint8_t pin) : OneWire(pin)
{

Donc pour toi :

#include <SerialLCD.h>
#include <SoftwareSerial.h> //this is a must

class classX : public SerialLCD {
public:
classX();
    int val;
  void affiche();

};

.cpp :

#include "classX.h"

classX::classX() : SerialLCD(0,1){
    val=10;
}

void classX::affiche(){
  print("Test Affichage...");
}

Programme :

#include <SerialLCD.h>
#include <SoftwareSerial.h> //this is a must

#include "classX.h"

classX slcd(0,1);//this is a must, assign soft serial pins

void setup() {
  // set up : 
  slcd.begin();
  // Print a message to the LCD.
  slcd.print("hello, world!");
}

void loop() {
  // Turn off the blinking cursor:
  slcd.noBlink();
  delay(1000);
   // Turn on the blinking cursor:
  slcd.blink();
  delay(1000);
    slcd.affiche();
}

Et en "composition", on inclut la classe SerialLCD, qu'on doit impérativement construire dans le constructeur de la classe qui le contient.

class maClass
{
SerialLCD lcd;

maClass() : lcd(initialisateurs) {}
};

Pourquoi il ne le font dans la lib DS18B20 ?

Tout dépend si tu veux faire de l’encapsulation ou de l’héritage. Soit tu veux que ta classe se comporte comme une LCD, soit tu veux qu’elle pilote une LCD.

Au final, tu auras la même chose, c’est juste une question de concept OO.

Ah ok donc ce que j'avais proposé était OK ? Parce que effectivement j'avais l'héritage en tête plus que l'encapsulation

oui, ce que tu proposes est OK :wink:

Ok merci :slight_smile: