PICO - instancier une classe avec constructeur en global dans le Setup

Bonjour,

J'ai une classe avec un constructeur qui prend 2 paramètres:

avant le Setup:

Maclassse maclasse;

dans le setup je voudrais l'initialiser du genre:

void Setup() {
 maclasse = Maclasse(Serial2, 21, 20);
....
}

Mais ca ne fonctionne pas.
Vous me direz pourquoi ne pas faire en global avant le Setup ceci.

Maclasse maclasse(Serial2, 21,20);

Malheureusement ca ne fonctionne pas car serial est initialisé avant le Setup et ca me brick le pico (Serial port removed), je suis obligé d'utiliser bootsel pour mettre un uf2 dessus pour que le port série du pico soit de nouveau visible.

Je peux utiliser un pointeur, ca fonctionne, mais je ne veux pas utiliser de pointeur sur la classe:

Maclasse * maclasse => avant le setup
et dans le setup
maclasse = new Maclasse(Serial2, 21, 20);

Comment initialiser une classe avec constructeur dans le Setup mais que cette classe soit globale ?

Merci de votre aide.

Bonjour,

La solution qui fonctionne a tous les coups (certes moins élégante) est de ne pas passer les paramètres dans le constructeur mais de créer une fonction init() qui prend ces paramètres.
Tu instancies la classe avant le setup() et tu appelles init() dans le setup.

Merci.
Exact je n'ai pas penser à cela, et ca devrait fonctionner.
Je vais tester cela.

J'ai supprimé le cosntructeur, ca devient:

class Minitel
{
public:
  //Minitel(SerialUART& serial);
  //Minitel(SerialUART& serial, pin_size_t rx, pin_size_t tx);
 
  void init(SerialUART& serial);
  void init(SerialUART& serial, pin_size_t rx, pin_size_t tx);
.....
private: 
  SerialUART& mySerial; 
  pin_size_t rxPin;
  pin_size_t txPin;

le .cpp

void Minitel::init(SerialUART& serial)  {
  // A la mise sous tension du Minitel, la vitesse des échanges entre
  // le Minitel et le périphérique est de 1200 bauds par défaut.
  mySerial = serial;
  rxPin = 17;
  txPin = 16;
  mySerial.begin(1200, SERIAL_7E1);
}
/*--------------------------------------------------------------------*/
void Minitel::init(SerialUART& serial, pin_size_t rx, pin_size_t tx)  {
  // A la mise sous tension du Minitel, la vitesse des échanges entre
  // le Minitel et le périphérique est de 1200 bauds par défaut.
  mySerial = serial;
  rxPin = rx;
  txtPin = tx;  
  mySerial.setRX(rxPin);
  mySerial.setTX(txPin);
  mySerial.begin(1200, SERIAL_7E1);
}
....

Dans le ino mainteant je fais ceci:


Minitiel minitel;

et dans le setup:

void setup() {
  //Serial2.begin(1200, SERIAL_7E1, 17, 16);
  // Le premier port série matériel de l'ATMega (Serial / RXD0 TXD0)
  // ou de l'ESP32 (Serial / U0RXD U0TXD) est utilisé pour la connexion
  // avec le PC.
  Serial.begin(9600);
  //minitel = new Minitel(Serial2, 21,20);
  minitel.init(Serial2, 21, 20);

Sauf que maintenant j'ai des erreurs que je n'avais pas avant:

d:\donnees\dev\ARDUINO2\sketch\libraries\Minitel1B_Pico_Hard/Minitel1B_Pico_Hard.h:380:15: warning: non-static reference 'SerialUART& Minitel::mySerial' in class without a constructor [-Wuninitialized]
  380 |   SerialUART& mySerial;
      |               ^~~~~~~~
D:\donnees\dev\ARDUINO2\sketch\PICO2\MINITEL\Demo\Demo.ino:39:9: error: use of deleted function 'Minitel::Minitel()'
   39 | Minitel minitel;
      |         ^~~~~~~
d:\donnees\dev\ARDUINO2\sketch\libraries\Minitel1B_Pico_Hard/Minitel1B_Pico_Hard.h:268:7: note: 'Minitel::Minitel()' is implicitly deleted because the default definition would be ill-formed:
  268 | class Minitel
      |       ^~~~~~~
d:\donnees\dev\ARDUINO2\sketch\libraries\Minitel1B_Pico_Hard/Minitel1B_Pico_Hard.h:268:7: error: uninitialized reference member in 'class Minitel'
d:\donnees\dev\ARDUINO2\sketch\libraries\Minitel1B_Pico_Hard/Minitel1B_Pico_Hard.h:380:15: note: 'SerialUART& Minitel::mySerial' should be initialized
  380 |   SerialUART& mySerial;
      |               ^~~~~~~~
D:\donnees\dev\ARDUINO2\sketch\PICO2\MINITEL\Demo\Demo.ino:39:9: note: use '-fdiagnostics-all-candidates' to display considered candidates
   39 | Minitel minitel;
      |         ^~~~~~~

Une idée ?

Mets les sources en entier.

il y a 1300 lignes ce n'est pas possible, mais je peut creer un zip,
cette classe fonctionne tres bien avec declaration en pointeur sur pico, sur esp32 sans pointeur sa fonctionne.

j'ai l'impression qu'il faut un constructeur vide, j'ai essayé toutes les possiblités.

C'est une librairie adapté au pico:
Minitel1B_Pico_Hard.h (18.1 KB)
Minitel1B_Pico_Hard.cpp (47.8 KB)
Demo.ino (7.7 KB)

J'ai testé la librarie dans un ino sans rien, ca compil:

#include <Arduino.h>

#include <Minitel1B_Pico_Hard.h>  // Voir https://github.com/eserandour/Minitel1B_Hard

void setup() {
  // put your setup code here, to run once:

}

void loop() {
  // put your main code here, to run repeatedly:

}

Le problème vient de

Minitel minitel;

et de minitel.init(Serial2, 21, 20);

il n'aime pas la déclaration de
Minitel minitel;

J'ai essayé Minitel minitel();

de mette un constructeur

Minitel() = delete;
Minitel() { }

Ca ne change rien.

Si je fais avec un pointeur ca fonctionne impeccable
Minitel *minitel;

dans le setup
minitel = new Minitel(Serial2, 21, 20);

en ces là je doit utiliser un contructeur et non plus init(Serial, 21 , 20);

J'ai du oublié une chose mais je ne sais pas quoi.

En fait l'erreur c'est cela:

error: use of deleted function 'Minitel::Minitel()
Minitel minitel;

Tous les exemples que j'ai pu voir utilise des constructeurs avec parametres, difficile de trouver un code d'une classe sans constructeur avec un exemple, comment la déclarer et l'initialiser.

Du coup j'ai laissé le mode avec pointeur.

Je ne saurai jamais pourquoi on ne peut pas instancier et declarer une classe sans constructeur et appeler une fonction membre qui initialise d'autres variables membres.

Il y a aussi un problème avec SerialUART& qui bloc sans pointeur de classe. Avec, ca fonctionne bien.

Il est vrai aussi que j'ai toujours utilisé des classes avec constructeurs, je n'avais jamais testé de classe sans constructeur.

Ce problème je l'ai que sur PICO, sur esp32, aucun problème. surement le compilateur et le link pour pico qui pose problème.

Merci.

C'est vraiment très bizarre. Normalement il n'y a aucun problème à instancier une class sans constructeur.

Je pense que c'est propre au pico, pour esp32 ca fonctionne bien.

C'est tout simple, si aucun constructeur n'est déclaré le compilateur en crée un, quand on instancie la classe on appelle ce constructeur dit par défaut car il ne comporte aucun argument.

C'est une erreur d'initialiser les variables membres ailleurs que dans le constructeur car c'est son rôle.

Dans le fichier joint les deux constructeurs sont commentés

class Minitel
{
public:
  //Minitel(SerialUART& serial);
  //Minitel(SerialUART& serial, pin_size_t rx, pin_size_t tx);