Ma première class Async

Bonjour à tous,

je veux apprendre à créer une classe. Pour cela, j'ai un petit projet tout simple: une horloge avec température extérieure et température intérieure. La température extérieure est lue via FTP sur un site serveur. En ligne de commande, il faut 6 secondes. Pendant ce temps, l'horloge est arrêtée. C'est pourquoi je veux sous-traiter la lecture FTP. Ainsi, l'horloge ne devrait plus s'arrêter. Je pars de zéro sinon quelques intuitions.

Voici le code actuelle - celui qui arrête mon horloge pendant 6 secondes.

#include <FTPClient_Generic.h>

String tempEXT = "";
bool rendu = true;

//Transfert FTP des images et infos saisies
char ftp_server[] = "adresse.serveur.net";
char ftp_user[]   = "usager@serveur.net";
char ftp_pass[]   = "MotDePasse";
FTPClient_Generic ftpRCmission   (ftp_server, uint16_t(21), ftp_user, ftp_pass, uint16_t(5000));

setup()  {
}

loop  () {
   if (rendu) {
      tempEXT = "";
      ftpRCmission.OpenConnection();
      ftpRCmission.InitFile(COMMAND_XFER_TYPE_ASCII);
      ftpRCmission.DownloadString("dehorsPond_temp.txt", tempEXT);
      ftpRCmission.CloseConnection();
      Serial.print  ("Voici la valeur lue : ");
      Serial.println(tempEXT);
      rendu = false;
    } 
}

Voici ce que j'ai en tête:

---------Page principale ---------

#include "TemperatureLocale.h"

TemperatureLocale LireValeur("ville");

loop () {
      Serial.println(LireValeur.valeurLue);
}

-------- Page appelée TemperatureLocale.h -----------

#include <FTPClient_Generic.h>

#ifndef _cetteConnexion
#define _cetteConnexion

#ifndef _ftpServ
#define _ftpServ = "repertoire.serveur.net";

#ifndef _ftpUser
#define _ftpUser = "usager@serveur.net";

#ifndef _ftpPass
#define _ftpPass  = "MotdePasse";

#ifndef _ftpPort
#define _ftpPort = 21;

#ifndef _valeurLue
#define _valeurLue = "";

class TemperatureLocale : public FTPClient_Generic {
  FTPClient_Generic _cetteConnexion  (_ftpServ, uint16_t(_ftpPort), _ftpUser, _ftpPass, uint16_t(5000));

  _cetteConnexion.OpenConnection();
  _cetteConnexion.ChangeDir("%ville");
  _cetteConnexion.InitFile(COMMAND_XFER_TYPE_ASCII);
  _cetteConnexion.DownloadString("dehors_temp.txt", _valeurLue);
  _cetteConnexion.CloseConnection();

  return _valeurLue;
}

Pouvez-vous m'aider ?

Merci à l'avance.

1 Like

Après lecture de Une introduction aux Librairies et Classes C++ avec Arduino, mais fichiers sont les suivants:

--fichier principal : appel de la valeur:


loop () {
   string valeur = TemperatureLocale.Reponse();

fichier TemperatureLocale.cpp

#include <FTPClient_Generic.h>
#include "TemperatureLocale.h"

TemperatureLocale::TemperatureLocale(char Serv, char User, char Pass, int Port) {
  FTPClient_Generic ftpRCmission   (Serv, uint16_t(Port), User, Pass, uint16_t(5000));
}

void TemperatureLocale::Lire(char[] Ville, char[] Fichier) {
  _cetteConnexion.OpenConnection();
  _cetteConnexion.ChangeDir(Ville);
  _cetteConnexion.InitFile(COMMAND_XFER_TYPE_ASCII);
  _cetteConnexion.DownloadString(Fichier, _valeurLue);
  _cetteConnexion.CloseConnection();
}

void TemperatureLocale::Reponse() {
  return _valeurLue;
}

fichier TemperatureLocale.h

#ifndef TemperatureLocale
#define TemperatureLocale

#include <FTPClient_Generic.h>

#ifndef _cetteConnexion
#define _cetteConnexion

#ifndef _ftpServ
#define _ftpServ = "carte178.hostpapavps.net";

#ifndef _ftpUser
#define _ftpUser = "meteoPond@rcmission.net";

#ifndef _ftpPass
#define _ftpPass  = "..$@339F1k.okdk";

#ifndef _ftpPort
#define _ftpPort = 21;

#ifndef _valeurLue
#define _valeurLue = "";

class TemperatureLocale : public FTPClient_Generic {
  private:
    boolean current_state;

  public:
    _ftpServ(char[]);
    _ftpUser(char[]);
    _ftpPass(char[]);
    _ftpPort(int);
    TemperatureLocale(char[], char[], char[], int);
    char[] _valeurLue();

  FTPClient_Generic _cetteConnexion  (_ftpServ, uint16_t(_ftpPort), _ftpUser, _ftpPass, uint16_t(5000));

  _cetteConnexion.OpenConnection();
  _cetteConnexion.ChangeDir("%ville");
  _cetteConnexion.InitFile(COMMAND_XFER_TYPE_ASCII);
  _cetteConnexion.DownloadString("dehors_temp.txt", _valeurLue);
  _cetteConnexion.CloseConnection();

  return _valeurLue;
}

#endif;

Si vous voulez faire de la programmation orientée objet il faut commencer par définir quels sont ces objets.

Naturellement il vient à l’idée une classe pour l’horloge et une classe pour un capteur de température

Le code liant le tout aurait une instance de l’horloge et deux instances des capteurs.

Si vous voulez du non bloquant, il faut que la classe offre une API non bloquante. On demande l’information et si elle n’est pas encore dispo, on ne bloque pas. A vous de voir comment donner régulièrement la main aux instances pour qu’elles fassent le nécessaire.

Je m'inspirerai de timeClient.h pour ma première expérience..
Merci J-M-L.

Bonjour à tous,
après quelques heures de travail, j'arrive à une première étape: tous les fichiers nécessaires.

Je ne sais, cependant, comment appeler les fonctions d'une classe intégrée. Pouvez-vous m'aider?
Ma classe doit lire un fichier via connexion FTP. Pour cela, évidemment, il faut une connexion Wifi active (Wifi, car c'est avec ESP-10 que je veux faire fonctionner initialement).
Alors, comment créer et interpeler l'objet Wifi dans ma classe ?

Mes pages de codes sont ici: https://github.com/Patriboom/FTP_lireFichier
Mais voici ce qui est pertinent

#include "FTP_lireFichier.h"

FTP_lireFichier::FTP_lireFichier(LIREFTP& lireFTP, char* ftpSrv, char* ftpUsr, char* ftpPsw, char* ftpFile) {
  this->_lireFTP	= &lireFTP;
  this->_ftpSev 	= ftpSrv;
  this->_ftpUsr 	= ftpUsr;
  this->_ftpPsw 	= ftpPsw;
  this->_ftpFile 	= ftpFile;
}

FTP_lireFichier::FTP_lireFichier(LIREFTP& lireFTP, char* ftpSrv, char* ftpUsr, char* ftpPsw, char* ftpFile, char* ftpRep) {
  this->_lireFTP	= &lireFTP;
  this->_ftpSev 	= ftpSrv;
  this->_ftpUsr 	= ftpUsr;
  this->_ftpPsw 	= ftpPsw;
  this->_ftpFile 	= ftpFile;
  this->_ftpRep 	= ftpRep;
}
FTP_lireFichier::FTP_lireFichier(LIREFTP& lireFTP, char* ftpSrv, char* ftpUsr, char* ftpPsw, char* ftpFile, char* ftpRep, int ftpFreq) {
  this->_lireFTP	= &lireFTP;
  this->_ftpSev 	= ftpSrv;
  this->_ftpUsr 	= ftpUsr;
  this->_ftpPsw 	= ftpPsw;
  this->_ftpFile 	= ftpFile;
  this->_ftpRep 	= ftpRep;
  this->_ftpFreq 	= ftpFreq;
}
FTP_lireFichier::FTP_lireFichier(LIREFTP& lireFTP, char* ftpSrv, char* ftpUsr, char* ftpPsw, char* ftpFile, char* ftpRep, int ftpFreq, ftpPort) {
  this->_lireFTP	= &lireFTP;
  this->_ftpSev 	= ftpSrv;
  this->_ftpUsr 	= ftpUsr;
  this->_ftpPsw 	= ftpPsw;
  this->_ftpFile 	= ftpFile;
  this->_ftpRep 	= ftpRep;
  this->_ftpFreq 	= ftpFreq;
  this->_ftpPort 	= ftpPort;
}


void FTP_lireFichier::begin() {
  this->begin(this->_ftpSrv, this->_ftpUsr, this->_ftpPsw, this->_ftpFile);
}

void FTP_lireFichier::begin(char* ftpRep) {
	this->_ftpRep = ftpRep;
}

void FTP_lireFichier::begin(char* ftpRep, int ftpFreq) {
	this->_ftpRep = ftpRep;
	this->_ftpFreq = ftpFreq;
}

void FTP_lireFichier::begin(char* ftpRep, int ftpFreq, int ftpPort) {
	this->_ftpRep = ftpRep;
	this->_ftpFreq = ftpFreq;
	this->_ftpPort = ftpPort;
}

bool FTP_lireFichier::forceUpdate() {
  #ifdef DEBUG_FTP_lireFichier
    Serial.println("Forcing update of your FTP`s file into the RAM");
  #endif
  if(!this->Status) { return false; }
  this->getText;
  this->_lastUpdate = millis();
  return true;
}

bool FTP_lireFichier::update() {
	if ((millis() - this->_lastUpdate >= this->_updateInterval) || this->_lastUpdate == 0) {      // Update after _updateInterval or Update if there was no update yet (if lastUpdate == 0)
		return this->forceUpdate();
	} else {
		return false;   // return false if update does not occur
	}
	return true;
}

char FTP_lireFichier::getText() {
	if(!this->Status) { 
		if (FTP_lire->Connexin()) {
			this->Wifi.OpenConnection();
			this->Wifi.InitFile(COMMAND_XFER_TYPE_ASCII);
			this->Wifi.DownloadString(this->_ftpFile, this->contenuLU);
			this->Wifi.CloseConnection();
			Serial.print  ("Voici la valeur lue : ");
			Serial.println(this->contenuLU);
			this->fileSize = Wifi.Size();
		} else {
			return "";
		}
	}
	return this->_contenuLU;
}

bool Connexion() {
	int combien = 0;
	this->WiFi.begin(this->_ssid, this->_pswd);
	while (this->WiFi.status() != WL_CONNECTED && ++combien <= 40) {
		delay(500);
		Serial.print(".");
	}
	if (combien > 40) { 
		Serial.println(" échouée"); 
		return false; 
	} else { 
		Serial.println( " réussie! "); 
		if (this->_ftpRep != "") { this->wifi.ChangeWorkDir(_ftpRep); }
		return true; 
	}
}

bool FTP_lireFichier::isTimeSet() const {
  return (this->_lastUpdate != 0); // returns true if the time has been set, else false
}

unsigned long FTP_lireFichier::getTime() const {
  return this->WiFi.GetLastModifiedTime();
}

int FTP_lireFichier::getTime() {
  return this->fileTime;
}

int FTP_lireFichier::getSize() {
  return this->fileSize;
}


void FTP_lireFichier::end() {
  this->_udp->stop();
  this->_udpSetup = false;
}


void FTP_lireFichier::setFrequ(unsigned int ftpFreq) {
  this->_ftpFreq = ftpFreq;
}

void FTP_lireFichier::setServerName(const char* ServerName) {
    this->_ftpSrv = ServerName;
}

void FTP_lireFichier::setServerUser(const char* ServerUser) {
    this->_ftpUsr = ServerName;
}

void FTP_lireFichier::setServerPswd(const char* ServerPassword) {
    this->_ftpPsw = ServerPassword;
}

void FTP_lireFichier::setDirectory(const char* ServerDir) {
    this->_ftpRep = ServerDir;
}

void FTP_lireFichier::setFileName(const char* FileName) {
    this->_ftpFile = FileName;
}

void FTP_lireFichier::setFrequency(const int ServFreq) {
    this->_ftpFreq = this->setFrequ(ServFreq);
}

void FTP_lireFichier::setPort(const int ServPort) {
    this->_ftpPort = ServPort;
}

#pragma once

#include <FTPClient_Generic.h>

#define DEBUG_FTP_lireFichier false
#define FTP_FREQUENCE 55000
#define FTP_DEFAULT_PORT 22

class FTP_lireFichier {
  private:
    LIREFTP*      dclient;
    bool          _udpSetup       = true;

    const char*   _ftpSrv = "ftp.server.org"; // Default time server
    const char*   _ftpUsr;
    const char*   _ftpPsw;
    const char*   _ftpRep = "";
    const char*   _ftpFile = "contenu.txt";
    unsigned int  _ftpPort = FTP_DEFAULT_PORT;
    long          _timeOffset     = 0;

    unsigned long _ftpFreq = FTP_FREQUENCE;  // In ms
    unsigned long _lastUpdate     = 0;      // In ms
    char*		   _contenuLU = "";

    void			contenuLU();
    int			fileSize = 0;
    char*			fileTime = "";

  public:
  	FTP_lireftp(LIREFTP& dclient, ftpSrv, ftpUsr, ftpPsw, ftpFile);
  	FTP_lireftp(LIREFTP& dclient, ftpSrv, ftpUsr, ftpPsw, ftpFile, const char* ftpRep);
  	FTP_lireftp(LIREFTP& dclient, ftpSrv, ftpUsr, ftpPsw, ftpFile, const char* ftpRep, int ftpFreq);
  	FTP_lireftp(LIREFTP& dclient, ftpSrv, ftpUsr, ftpPsw, ftpFile, const char* ftpRep, const int ftpFreq, const int ftpPort);


    /**
     * Set time server name
     *
     * @param poolServerName
     */
    void setftpSrv(const char* ftpSrv);

     /**
     * Set random local port
     */
    void ftpPort(unsigned int ftpPort);

    /**
     * Starts the underlying UDP client with the default local port
     */
    void begin();
    void begin(unsigned char* ftpRep);
    void begin(unsigned char* ftpRep, unsigned int ftpFreq;
    void begin(unsigned char* ftpRep, unsigned int ftpFreq, unsigned int ftpPort);

    /**
     * This should be called in the main loop of your application. By default an update from the NTP Server is only
     * made every 60 seconds. This can be configured in the FTP_lireFichier constructor.
     *
     * @return true on success, false on failure
     */
    bool update();
    /**
     * This will force the update from the NTP Server.
     *
     * @return true on success, false on failure
     */
    bool forceUpdate();

    /**
     * Définition des commandes accessibles à l'usager
     */
	void setFrequ(unsigned int ftpFreq);
	void setFrequency(unsigned int ftpFreq);
	void setServerName(unsigned char* ServerName);
	void setServerUser(unsigned char* ServerUser);
	void setServerPswd(unsigned char* ServerPassword);
	void setDirectory(unsigned char* ServerDir);
	void setFileName(unsigned char* FileName);
	void setPort(unsigned int ServPort);

    /**
     * Définition des valeurs retournées par l'objet
     */
    unsigned char* getText() const;
    unsigned long getTime() const;
    unsigned int getSize() const;

    //Vérifions ici si la connexion Wifi est bien active
    bool getStatus() const;

    /**
     * Demande de déconnexion Wifi
     */
    void end();
};

Merci à l'avance.

Votre modèle objet est donc incomplet.

Il vous faut une objet qui représente le WiFi et vous passez une référence à une instance (singleton sans doute) à votre classe qui a besoin d’utiliser le WiFi.

vous pouvez aussi déclarer (comme Serial par exemple) une instance globale et tous les modules peuvent y avoir accès. C’est un peu moins propre mais comme ça représente une capacité unique de votre système (une fonction hardware unique) c’est acceptable.

Merci encore J-M-L. Toujours là pour m'aider.

Je comprends ce que vous m'écrivez et c'est exactement l'objet de ma question ... Comment faire cela ? Je veux une référence à WiFi dans ma classe.

Questions:

  • dois-je appeler « ESP8266WiFi.h » dans le .h ou dans le .cpp ?
  • Puisque « ESP8266WiFi.h » est déjà appelé dans le programme principal, puis-je y simplement référer ? .. avec un
#ifndef WiFi_h
#define WiFi_h

?

  • comment nommer ce membre de l'objet ?

Si je comprends, voici à quoi ressemblerait le début de mon fichier FTP_lireFichier.h

#pragma once

#include <ESP8266WiFi.h>
#include <FTPClient_Generic.h>

#define DEBUG_FTP_lireFichier false
#define FTP_FREQUENCE 55000
#define FTP_DEFAULT_PORT 22

class FTP_lireFichier {
  private:
  	 WiFi*			WiFi_h
    LIREFTP*      dclient;
    bool          _udpSetup       = true;

    const char*   _ftpSrv = "ftp.server.org"; // Default time server
    const char*   _ftpUsr;
    const char*   _ftpPsw;

Ensuite, je compte appeler WiFi (oui, j'ai changé Wifi pour WiFi dans tout mon code, je sais que cpp est sensible à la casse) ainsi dans mon fichier .cpp:

char FTP_lireFichier::getText() {
	if(!this->Status) { 
		if (FTP_lire->Connexin()) {
			this->WiFi.OpenConnection();
			this->WiFi.InitFile(COMMAND_XFER_TYPE_ASCII);
			this->WiFi.DownloadString(this->_ftpFile, this->contenuLU);
			this->WiFi.CloseConnection();
			Serial.print  ("Voici la valeur lue : ");
			Serial.println(this->contenuLU);
			this->fileSize = WiFi.Size();
		} else {
			return "";
		}
	}
	return this->_contenuLU;
}

Merci de votre aide

Note: l'expression WiFi_h vient des première lignes de ESP8266WiFi.h :

#ifndef WiFi_h
#define WiFi_h

pouvez vous clarifier exactement l'arduino utilisé ? est-ce juste un ESP8266 ou alors un combo genre UNO + ESP-01connecté sur le port série ?

L'objectif est d'utiliser un ESP-01 de manière autonome.
Pour l'instant, je le programme et en suis les réactions à l'aide d'un FT-232RL

OK - c'est un puce un peu datée, Espressif ne développe plus activement l'OS pour l'ESP01 (ils ont cessé de se concentrer activement sur le développement de l'OS pour l'ESP01 autour de 2016, lorsque l'ESP32 a été introduit et est devenu le produit phare de la société)

Perso je n'investirais pas du temps sur cette puce aujourd'hui pour bâtir un projet mais si c'est juste pour faire vos armes avec la programmation objet, pourquoi pas.

Pour votre question, si vous travaillez dans le monde Arduino, du moment que vous faites

#include <ESP8266WiFi.h>

vous avez accès à une instance globale de la class ESP8266WiFiClass, déclarée dans le .h comme extern

et définie dans le .cpp correspondant ESP8266WiFi.cpp

donc si vos classes font

#include <ESP8266WiFi.h>

elles ont accès à l'instance sans avoir besoin de déclarer quoi que ce soit (tout comme Serial).

Il faudra cependant que le code principal configure le WiFi bien entendu.

J'aime bien ce petit module ESP-01. Le cas qui nous intéresse ici, est un cas d'apprentissage de programmation. Merci du conseil.

Mon appel WiFi doit-il comporter une référence interne ( this-> ) ou non ?

char FTP_lireFichier::getText() {
	if(!this->Status) { 
		if (FTP_lire->Connexin()) {
			this->WiFi.OpenConnection();
			this->WiFi.InitFile(COMMAND_XFER_TYPE_ASCII);
			this->WiFi.DownloadString(this->_ftpFile, this->contenuLU);
			this->WiFi.CloseConnection();
			Serial.print  ("Voici la valeur lue : ");
			Serial.println(this->contenuLU);
			this->fileSize = WiFi.Size();
		} else {
			return "";
		}
	}
	return this->_contenuLU;
}

ou

char FTP_lireFichier::getText() {
	if(!this->Status) { 
		if (FTP_lire->Connexin()) {
			WiFi.OpenConnection();
			WiFi.InitFile(COMMAND_XFER_TYPE_ASCII);
			WiFi.DownloadString(this->_ftpFile, this->contenuLU);
			WiFi.CloseConnection();
			Serial.print  ("Voici la valeur lue : ");
			Serial.println(this->contenuLU);
			this->fileSize = WiFi.Size();
		} else {
			return "";
		}
	}
	return this->_contenuLU;
}

bof, il est pénible à connecter pour programmer, l'OS est buggy ... il y a mieux maintenant, si vous voulez un microcontrôleur petit, monocœur mais plus puissant, regardez du côté de la Carte XIAO ESP32C3

image

mais bon, souvent le bon microcontrôleur pour bidouiller est celui qu'on a sous la main :slight_smile:


Non. si vous avez fait #include <ESP8266WiFi.h> alors WiFi est connu, c'est une variable globale, vous n'avez pas besoin de l'avoir comme variable d'instance.

Je note la suggestion de micro-contrôleur, mais j'ai encore 4 ou 5 ESP-10 en main ...alors ...

Je lis le code de FTPclient_Generic mais n'y trouve aucune ligne

extern

ou

class

J'ai conclu que la référence à la classe devait se faire ainsi:

		if (FTP_lire->Connexion()) {
			FTPclient.OpenConnection();
			FTPclient.InitFile(COMMAND_XFER_TYPE_ASCII);
			FTPclient.DownloadString(this->_ftpFile, this->contenuLU);
			FTPclient.CloseConnection();
			Serial.print  ("Voici la valeur lue : ");
			Serial.println(this->contenuLU);
			this->fileSize = WiFi.Size();
		} else {
			return "";
		}

car je trouve ceci en tête du fichier FTPClient_Generic.h

#ifndef FTPCLIENT_GENERIC_H
#define FTPCLIENT_GENERIC_H

et que j'ajoute la ligne suivante à mon FTP_lireFichier.h

    FTPCLIENT_GENERIC_H FTPclient;

de sorte que la tête de mon FTP_lireFichier.h soit

class FTP_lireFichier {
  private:
    LIREFTP*      dclient;
    FTPCLIENT_GENERIC_H FTPclient;
    bool          _udpSetup       = true;

Ai-je bien compris ?

ils ont un exemple d'usage de la bibliothèque .

ils instancing un client FTP

et ensuite ils peuvent appeler des commandes comme

char fileName[] = "hello.txt";

  ftp.OpenConnection();
  ftp.InitFile(COMMAND_XFER_TYPE_ASCII);
  ftp.NewFile(fileName);
  ftp.Write("coucou");
  ftp.CloseFile();

si vous voulez "cacher" un client FTP il faut simplement que votre instance embarque (dans son constructeur) une instance de FTPClient_Generic

A regarder le code, FTPClient_Generic va essayer de deviner quelle interface utiliser en fonction de #define

et vous tombez dans le cas

je n'ai toujours pas compris la structuration objet que vous voulez avoir. Quelles sont vos classes et que représentent-elles ?

XIAO ESP32C3 me semble intéressant, oui, mais à 10$ chaque.
ESP-01 est à 2,50$ 4 pour 1 mais ESP-01 est TRÈS limité (c'est assez souvent frustrant, d'ailleurs).
Je vois aussi le ESP32 S2 min à 5,25$ chaque. Il me semble intéressant. Le connaissez-vous, qu'en pensez-vous ?

Sur aliexpress ils doivent plutôt être à $5 pièces avec l'antenne externe (hors frais de port qui varient suivant le vendeur)

l'ESP-01 est moins cher car c'est un produit "mort". Les modules ESP-01 disponibles actuellement proviennent principalement de stocks restants.

il est aussi mono-coeur mais pas de bluetooth sur le S2. Le PCB du module est environ 4 fois plus grand.

Perso je préfère les modules plus complets, bi-coeur.

oui, l'intenciation est ce que je faisais dans mon code initial arduino.
Cependant, c'est dans ma classe que je désormais le faire.

Comment connaître ou définir le nom de l'instanciation dans un classe ?

L'objet de lecture FTP de ma classe va comme suit :

char FTP_lireFichier::getText() {
	if(!this->Status) { 
		if (FTP_lire->Connexion()) {
			FTPclient.OpenConnection();
			FTPclient.InitFile(COMMAND_XFER_TYPE_ASCII);
			FTPclient.DownloadString(this->_ftpFile, this->contenuLU);
			FTPclient.CloseConnection();
			Serial.print  ("Voici la valeur lue : ");
			Serial.println(this->contenuLU);
			this->fileSize = WiFi.Size();
		} else {
			return "";
		}
	}
	return this->_contenuLU;
}

Fauti-il alors que mon début de FTP_lireFichier.h soit

#include <ESP8266WiFi.h>
#include <FTPClient_Generic.h>

#define DEBUG_FTP_lireFichier false
#define FTP_FREQUENCE 55000
#define FTP_DEFAULT_PORT 22

class FTP_lireFichier {
  private:
    LIREFTP*      dclient;
    FTPClient_Generic FTPclient;
    bool          _udpSetup       = true;

?

imaginez que vous ayez une classe A et vous voulez une classe B qui possède une instance de la classe A.

Vous définissez votre classe B avec une variable d'instance de type A et dans le constructeur vous l'initialisez

class A {
public:
    A(int value) : value(value) {}

private:
    int value;
};

class B {
public:
    B(int aValue) : a(aValue) // <=== on instancie la classe A dans le constructeur
      {}

private:
    A a; // Instance de la classe A comme variable de la classe B
};

Ah bon, là je crois que je comprends ... L'instanciation doit être faite dans la section public avec deux points ( : )

Comme ci-bas (fichier FTP_lireFichier.h?

#include <ESP8266WiFi.h>
#include <FTPClient_Generic.h>

#define DEBUG_FTP_lireFichier false
#define FTP_FREQUENCE 55000
#define FTP_DEFAULT_PORT 22

class FTP_lireFichier {
  private:
    LIREFTP*      dclient;
    FTPClient_Generic FTPclient;
    bool          _udpSetup       = true;

    const char*   _ftpSrv = "ftp.server.org"; // Default time server
    const char*   _ftpUsr;
    const char*   _ftpPsw;
    const char*   _ftpRep = "";
    const char*   _ftpFile = "contenu.txt";
    unsigned int  _ftpPort = FTP_DEFAULT_PORT;
    long          _timeOffset     = 0;

    unsigned long _ftpFreq = FTP_FREQUENCE;  // In ms
    unsigned long _lastUpdate     = 0;      // In ms
    char*		   _contenuLU = "";

    void			contenuLU();
    int			fileSize = 0;
    char*			fileTime = "";

  public:
   FTPClient_Generic : FTPclient (dclient, ftpSrv, ftpUsr, ftpPsw, ftpFile);
  	FTP_lireftp(LIREFTP& dclient, ftpSrv, ftpUsr, ftpPsw, ftpFile);
  	FTP_lireftp(LIREFTP& dclient, ftpSrv, ftpUsr, ftpPsw, ftpFile, const char* ftpRep);
  	FTP_lireftp(LIREFTP& dclient, ftpSrv, ftpUsr, ftpPsw, ftpFile, const char* ftpRep, int ftpFreq);
  	FTP_lireftp(LIREFTP& dclient, ftpSrv, ftpUsr, ftpPsw, ftpFile, const char* ftpRep, const int ftpFreq, const int ftpPort);

oui, on fait cela au moment où le constructeur est appelé.

C'est une liste d'initialisation après le :, ça permet de définir les variables d'instances

--

Non pour votre code, ça ne va pas. les paramètres pour instancier A sont passés à B et utilisés dans la liste d'initialisation.

un truc comme cela pour simplifier

#include <ESP8266WiFi.h>
#include <FTPClient_Generic.h>

#define DEBUG_FTP_lireFichier false
#define FTP_FREQUENCE 55000
#define FTP_DEFAULT_PORT 22

class FTP_lireFichier {
  private:
    const char* server;
    const char* user;
    const char* pwd;
    FTPClient_Generic FTPclient;

  public:
    FTP_lireFichier(const char *server, const char * user, const char * pwd) : server(server), user(user), pwd(pwd), FTPclient(server, user, pwd, 60000) {}
    void fonction1();
    void fonction2();
    void fonction3();
};

si le constructeur n'a rien d'autre à faire vous pouvez laisser comme ça dans le .h et seulement implémenter fonction1, fonction2, et fonction3 dans le .cpp

Notez que le constructeur de classe pour le nom de la classe (FTP_lireFichier)

si vous voulez une valeur par défaut pour le serveur, il faut que ce soit le dernier paramètre et vous pouvez alors le mettre dans le .h

#include <ESP8266WiFi.h>
#include <FTPClient_Generic.h>

#define DEBUG_FTP_lireFichier false
#define FTP_FREQUENCE 55000
#define FTP_DEFAULT_PORT 22
class FTP_lireFichier {
  private:
    const char* user;
    const char* pwd;
    const char* server;
    FTPClient_Generic FTPclient;

  public:
    FTP_lireFichier(const char* user, const char* pwd, const char* server = "ftp.server.org")
      : user(user), pwd(pwd), server(server), FTPclient(server, user, pwd, 60000) {}

    void fonction1();
    void fonction2();
    void fonction3();
};

vous pourrez alors appeler le constructeur juste en donnant le nom du user et le mot de passe et le constructeur saura que vous voulez prendre la valeur par défaut.

PS/ on utilise plutôt le cameCase sur arduino, ce serait donc plutôt

class LecteurFTP 

par exemple