Tableau de Pointeur de fonction (error: invalid conversion from 'const char*' to

Bonjour

Je essayé de coder une petite fonction pour diriger le debug dans rien, Serial moniter ou un PuTTY Telnet avec un bout de code.

  // 0 > None_debugging
  // 1 > Serial_debugging
  // 2 > Telnet_debugging

int debugging_set = 1;

void Serial_debugging(char debugging) {
  Serial.println(debugging);
}
void Telnet_debugging(char debugging ) {
  TelnetStream2.println(debugging);
}
void None_debugging(char debugging) {
}

typedef void (*do_debugging) (char);
do_debugging do_debuggingArray [] =
{
  None_debugging,
  Serial_debugging,
  Telnet_debugging
};

void setup() {
// Il manque Wifi - Serial - TelnetStream2 ...... mais le problème il est pas là
}

void loop() {
  do_debuggingArray[debugging_set]("World hello");
}

Mais j'ai une erreur de compilation

do_debug:29:43: error: invalid conversion from 'const char*' to 'char' [-fpermissive]

   do_debuggingArray[debugging_set]("World hello");

Il manque Wifi - Serial - TelnetStream2 ...... mais le problème il est pas là

Où est le problème ??

Merci

do_debuggingArray[debugging_set] est un un tableau de caractères. Même si cela ressemble au nom d'une fonction, ce n'est pas une fonction. En fait une fonction est une adresse, et pour que l'on puisse programmer, on lui donne un nom. Lequel disparait lors de la compilation. Je dirais que tu est en train de faire
"Serial_debugging"("World hello"); au lieu de Serial_debugging("World hello");

Ce n'est pas possible en C++.

Voir le topic
https://forum.arduino.cc/index.php?topic=688118.0

Bonjour,

Ce que tu passes comme paramètre à tes fonctions c'est des chaines de caractères (char *) et non des char

Il faut déclarer tes fonctions avec un paramètre const char *

void Serial_debugging(const char* debugging)

idem pour le typedef

typedef void (*do_debugging) (const char *);

Hello

Une autre solution en vrai c++ arduino

class output : public Print {
  public :
    Print *p;
    output() : p(NULL){}
    void set(Print &p) {this->p = &p;}
    size_t write(uint8_t c) {return p==NULL ? 0 : p->write(c);}
};
output debug;

void setup()
{
  Serial.begin(115200);
  debug.set(Serial);
  //ou bien debug.set(TelnetStream2);
  //ou bien rien du tout et dans ce cas les debug.print resteront exécutés mais n'enverront rien nulle part
  debug.println("et voila");
}

void loop()
{
}

Ou alors à l'ancienne en bon vieux C et des macros

Print *p = NULL;
#define PRINT(x) (p!=NULL ? p->print(x) : 0)
#define PRINTLN(x) (p!=NULL ? p->println(x) : 0)

void setup()
{
  Serial.begin(115200);
  p = &Serial;
  //ou bien p = &TelnetStream2;
  //ou bien rien du tout et dans ce cas les PRINT ne feront quasi rien
  PRINT("et voila");
}

void loop()
{
}

Ou encore si tu veux envoyer systématiquement aux deux sorties en parallèle

//...définir TelnetStream2

class doublePrint : public Print {
  size_t write(uint8_t c) {return Serial.write(c) + TelnetStream2.write(c);}
};
doublePrint debug;

void setup()
{
  Serial.begin(115200);
  debug.println("et voila");
}

void loop()
{
}

Fais ton choix camarade :slight_smile:

Autre option : mon terminal Wifi

@kamill

Je progresse mais après je voudrais mettre le code dans une fonction

#include "credentials.h" // credentials.h include
#include "papy_wifi_proc.h"
#include "do_debugging.h"

void setup() {

  //------------------------------------------------Serial
  Serial.begin(115200);
  while (!Serial) {} // phase développement
  Serial.println("");
  Serial.println("Booting + Serial");

  delay(500);
  do_debuggingArray[debugging_set]("");
  do_debuggingArray[debugging_set]("Booting + Serial");

//-----------------------------------------------GPIO
//----------------------------------------------LittleFS
//-----------------------------------------------WIFI
 papy_wifi_proc();
//-----------------------------------------------OTA
//-----------------------------------------------SERVER

delay(500);
do_debuggingArray[debugging_set]("");
do_debuggingArray[debugging_set]("Booting + Serial");
}

void loop() {
  do_debuggingArray[debugging_set]("hello");
  delay(5000);
  
}
#include <TelnetStream2.h>


const int debugging_set = myDebugging_set 

void Serial_debugging(char* debugging) {
  Serial.println(debugging);
}
void Telnet_debugging(char* debugging ) {
  TelnetStream2.println(debugging);
}
void None_debugging(char* debugging) {
}

typedef void (*do_debugging) (char *);
do_debugging do_debuggingArray [] =
{
  None_debugging,
  Serial_debugging,
  Telnet_debugging
};
#include <WiFi.h>
#include <WiFiClient.h>
#include <DNSServer.h>

DNSServer dnsServer;

const char* ssid = mySSID;
const char* password = myPASSWORD;
const char* WiFi_hostname = myHostname;

//Static IP address configuration
IPAddress staticIP(192, 168, 1, 81); //ESP8266 static ip
IPAddress gateway(192, 168, 1, 1); //IP Address of your WiFi Router (Gateway)
IPAddress subnet(255, 255, 255, 0); //Subnet mask
IPAddress dns(192, 168, 1, 1); //DNS

void papy_wifi_proc() {
  WiFi.setAutoConnect(false);
  WiFi.disconnect(); //Prevent connecting to wifi based on previous configuration
  delay(500);
  do_debuggingArray[debugging_set]("Disconnect");

    WiFi.mode(WIFI_STA); //WiFi mode station (connect to wifi router only)

  // This part of code will try create static IP address
  if (!WiFi.config(staticIP, gateway, subnet, dns, dns))
  {
    do_debuggingArray[debugging_set]("STA Failed to configure");
  }
  WiFi.begin(ssid, password);

  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print("!");
  }

  do_debuggingArray[debugging_set]("");
  Serial.print("Hostname to ");
  do_debuggingArray[debugging_set](WiFi_hostname);

  do_debuggingArray[debugging_set]("");
  Serial.print("Connected to ");
  do_debuggingArray[debugging_set](ssid);
  Serial.print("IP address: ");
  do_debuggingArray[debugging_set](WiFi.localIP());
  if (WiFi.setHostname(WiFi_hostname)) {
    Serial.printf("\nHostname set!\n");
  } else {
    Serial.printf("\nHostname NOT set!\n");
  }
}

Quand la fonctions do_debuggingArray[debugging_set]("Booting + Serial"); dans le main tous se passe bien !!
Je definis une fonctions papy_wifi_proc();

Dans papy_wifi_proc la fonctions do_debuggingArraydebugging_set; signale une erreur

sketch\papy_wifi_proc.h: In function 'void papy_wifi_proc()':

papy_wifi_proc.h:23:3: error: 'do_debuggingArray' was not declared in this scope

   do_debuggingArray[debugging_set]("Disconnect");

@bricoleau
je vais essayer avec c++ arduino

Si j'ai bien compris tu te sert des .h pour mettre du code, ce qui n'est pas dans l'utilisation normale des .h qui ne doivent contenir que des déclarations et des définitions de type, mais c'est possible de le faire (la preuve c'est que tu le fais).

Dans tous les cas il faut que le tableau de fonction soit connu du compilateur au moment de l'appel.
Tu devrais inverser les includes et faire

#include "credentials.h" // credentials.h include
#include "do_debugging.h"
#include "papy_wifi_proc.h"

Remarque: appeler partout la fonction par le tableau avec un index c'est très lourd. Tu aurais mieux fait de définir une fonction void do_debugging(char *)

bricoleau

Avec

#include "credentials.h" // credentials.h include
#include "papy_wifi_proc.h"

Print *p = NULL;
#define PRINT(x) (p!=NULL ? p->print(x) : 0)
#define PRINTLN(x) (p!=NULL ? p->println(x) : 0)

void setup() {

  //------------------------------------------------Serial
  p = &Serial;
  //ou bien p = &TelnetStream2;
  //ou bien rien du tout et dans ce cas les PRINT ne feront quasi rieSerial.begin(115200);
  while (!Serial) {} // phase développement
  Serial.println("");
  Serial.println("Booting + Serial");

  delay(500);
  PRINT("");
  PRINT("Booting + Serial");

  //-----------------------------------------------GPIO
  //----------------------------------------------LittleFS
  //-----------------------------------------------WIFI
  papy_wifi_proc();
  //-----------------------------------------------OTA
  //-----------------------------------------------SERVER

  delay(500);
  PRINT("");
  PRINT("Booting + Serial");
}

void loop() {
  PRINT("hello");
  delay(5000);

}
#include <WiFi.h>
#include <WiFiClient.h>
#include <DNSServer.h>

DNSServer dnsServer;

const char* ssid = mySSID;
const char* password = myPASSWORD;
const char* WiFi_hostname = myHostname;

//Static IP address configuration
IPAddress staticIP(192, 168, 1, 81); //ESP8266 static ip
IPAddress gateway(192, 168, 1, 1); //IP Address of your WiFi Router (Gateway)
IPAddress subnet(255, 255, 255, 0); //Subnet mask
IPAddress dns(192, 168, 1, 1); //DNS

void papy_wifi_proc() {
  WiFi.setAutoConnect(false);
  WiFi.disconnect(); //Prevent connecting to wifi based on previous configuration
  delay(500);
  PRINT("Disconnect");

    WiFi.mode(WIFI_STA); //WiFi mode station (connect to wifi router only)

  // This part of code will try create static IP address
  if (!WiFi.config(staticIP, gateway, subnet, dns, dns))
  {
    PRINT("STA Failed to configure");
  }
  WiFi.begin(ssid, password);

  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    PRINT("!");
  }

  PRINT("");
  PRINT("Hostname to ");
  PRINT(WiFi_hostname);

  PRINT("");
  PRINT("Connected to ");
  PRINT(ssid);
  PRINT("IP address: ");
  PRINT(WiFi.localIP());
  if (WiFi.setHostname(WiFi_hostname)) {
    PRINT("\nHostname set!\n");
  } else {
    PRINT("\nHostname NOT set!\n");
  }
}

c'est comme si

Print *p = NULL;
#define PRINT(x) (p!=NULL ? p->print(x) : 0)
#define PRINTLN(x) (p!=NULL ? p->println(x) : 0)

n'est pas déclarer !!!

Merci

Exact.
Tu utilises mal la notion de fichier .h, d'où le problème rencontré.

Dans ton fichier .ino, imagine que tu remplaces la ligne #include par le contenu intégral du fichier papy_wifi_proc.h
Tu te retrouverais avec du code qui utilise des macros PRINT et une variable globale p qui sont définies plus loin.
Forcément cela ne compile pas.

Si tu veux le faire marcher, je pense qu'il faudrait coder

#include "credentials.h" // credentials.h include

Print *p = NULL;
#define PRINT(x) (p!=NULL ? p->print(x) : 0)
#define PRINTLN(x) (p!=NULL ? p->println(x) : 0)

#include "papy_wifi_proc.h"
...

Mais un fichier .h n'est pas censé contenir un tel code.
Un fichier .h est un header de bibliothèque

kamill

kamill:
Remarque: appeler partout la fonction par le tableau avec un index c'est très lourd. Tu aurais mieux fait de définir une fonction void do_debugging(char *)

Avant tout merci

Préalablement je utilise des .h (credentials.h, ...)

#define mySSID "WiFi SSID"; // WiFi SSID
#define myPASSWORD "WiFi PASSWORD"; // WiFi PASSWORD
#define myHostname  "do_debug"; // hostname

// 0 > None_debugging
// 1 > Serial_debugging
// 2 > Telnet_debugging
#define myDebugging_set  "1";

Si je use .cpp pour les déclararer les #define les variables sont pas là.

Quel bon usage conseilles tu?
Pour un int comme

const myDebugging_set= myDebugging_set;

#define myDebugging_set "1"; c'est bon??

je suis bloqué avec trop problèmes de compilation !!!

#include "credentials.h" // credentials.h include
#include "do_debugging.cpp"
#include "papy_wifi_proc.cpp"


void setup() {

  //------------------------------------------------Serial
  Serial.begin(115200);
  while (!Serial) {} // phase développement
  Serial.println("");
  Serial.println("Booting + Serial");

  delay(500);
  do_debugging("");
  do_debugging("Booting + Serial");

  //-----------------------------------------------GPIO
  //----------------------------------------------LittleFS
  //-----------------------------------------------WIFI
  papy_wifi_proc();
  //-----------------------------------------------OTA
  //-----------------------------------------------SERVER


  delay(500);
  do_debugging("");
  do_debugging("Booting + Serial");
}

void loop() {
  do_debugging("hello");
  delay(5000);

}
#include <TelnetStream2.h>

const int debugging_set = myDebugging_set;

void do_debugging(char *text) {
  swich (debugging_set) {
  case 0:
    break;
  case 1:
    Serial.println(debugging_set);
    break;
  case 2:
    TelnetStream2.println(debugging_set);
    break;
  }
}
#include <WiFi.h>
#include <WiFiClient.h>
#include <DNSServer.h>

DNSServer dnsServer;

const char* ssid = mySSID;
const char* password = myPASSWORD;
const char* WiFi_hostname = myHostname;

//Static IP address configuration
IPAddress staticIP(192, 168, 1, 81); //ESP8266 static ip
IPAddress gateway(192, 168, 1, 1); //IP Address of your WiFi Router (Gateway)
IPAddress subnet(255, 255, 255, 0); //Subnet mask
IPAddress dns(192, 168, 1, 1); //DNS

void papy_wifi_proc() {
  WiFi.setAutoConnect(false);
  WiFi.disconnect(); //Prevent connecting to wifi based on previous configuration
  delay(500);
  do_debugging("Disconnect");

    WiFi.mode(WIFI_STA); //WiFi mode station (connect to wifi router only)

  // This part of code will try create static IP address
  if (!WiFi.config(staticIP, gateway, subnet, dns, dns))
  {
    do_debugging("STA Failed to configure");
  }
  WiFi.begin(ssid, password);

  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    do_debugging("!");
  }

  do_debugging("");
  do_debugging("Hostname to ");
  do_debugging(WiFi_hostname);

  do_debugging("");
  do_debugging("Connected to ");
  do_debugging(ssid);
  do_debugging("IP address: ");
  do_debugging(WiFi.localIP());
  if (WiFi.setHostname(WiFi_hostname)) {
    do_debugging("\nHostname set!\n");
  } else {
    do_debugging("\nHostname NOT set!\n");
  }
}
do_debugging.cpp:5:27: error: 'myDebugging_set' was not declared in this scope

 const int debugging_set = myDebugging_set;

                           ^

sketch\do_debugging.cpp: In function 'void do_debugging(char*)':

do_debugging.cpp:8:23: error: 'swich' was not declared in this scope

   swich (debugging_set) {

                       ^

papy_wifi_proc.cpp:8:20: error: 'mySSID' was not declared in this scope

 const char* ssid = mySSID;

                    ^

papy_wifi_proc.cpp:9:24: error: 'myPASSWORD' was not declared in this scope

 const char* password = myPASSWORD;

                        ^

papy_wifi_proc.cpp:10:29: error: 'myHostname' was not declared in this scope

 const char* WiFi_hostname = myHostname;

                             ^

sketch\papy_wifi_proc.cpp: In function 'void papy_wifi_proc()':

papy_wifi_proc.cpp:22:28: error: 'do_debugging' was not declared in this scope

   do_debugging("Disconnect");

                            ^
..........

boom aïe aïe aïe

Merci

bricoleau

maintenant je suis là mais

#include "credentials.h" // credentials.h include

class output : public Print {
  public :
    Print *p;
    output() : p(NULL){}
    void set(Print &p) {this->p = &p;}
    size_t write(uint8_t c) {return p==NULL ? 0 : p->write(c);}
};
output debug;

#include "papy_wifi_proc.cpp"

void setup() {

  //------------------------------------------------Serial
  debug.set(Serial);
  //ou bien debug.set(TelnetStream2);
  //ou bien rien du tout et dans ce cas les debug.debug resteront exécutés mais n'enverront rien nulle part
  debug.debugln("et voila");
  while (!Serial) {} // phase développement
  Serial.debugln("");
  Serial.debugln("Booting + Serial");

  delay(500);
  debug("");
  debug("Booting + Serial");

  //-----------------------------------------------GPIO
  //----------------------------------------------LittleFS
  //-----------------------------------------------WIFI
  papy_wifi_proc();
  //-----------------------------------------------OTA
  //-----------------------------------------------SERVER

  delay(500);
  debug("");
  debug("Booting + Serial");
}

void loop() {
  debug("hello");
  delay(5000);

}
//
//  credentials.h
//

#define mySSID "WiFi SSID"
#define myPASSWORD "WiFi PASSWORD"
#define myHostname  "do_debug" // hostname

// 0 > None_debugging
// 1 > Serial_debugging
// 2 > Telnet_debugging
#define myDebugging_set 1
#include <WiFi.h>
#include <WiFiClient.h>
#include <DNSServer.h>

DNSServer dnsServer;

const char* ssid = mySSID;
const char* password = myPASSWORD;
const char* WiFi_hostname = myHostname;

//Static IP address configuration
IPAddress staticIP(192, 168, 1, 81); //ESP8266 static ip
IPAddress gateway(192, 168, 1, 1); //IP Address of your WiFi Router (Gateway)
IPAddress subnet(255, 255, 255, 0); //Subnet mask
IPAddress dns(192, 168, 1, 1); //DNS

void papy_wifi_proc() {
  WiFi.setAutoConnect(false);
  WiFi.disconnect(); //Prevent connecting to wifi based on previous configuration
  delay(500);
  debug("Disconnect");

    WiFi.mode(WIFI_STA); //WiFi mode station (connect to wifi router only)

  // This part of code will try create static IP address
  if (!WiFi.config(staticIP, gateway, subnet, dns, dns))
  {
    debug("STA Failed to configure");
  }
  WiFi.begin(ssid, password);

  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    debug("!");
  }

  debug("");
  debug("Hostname to ");
  debug(WiFi_hostname);

  debug("");
  debug("Connected to ");
  debug(ssid);
  debug("IP address: ");
  debug(WiFi.localIP());
  if (WiFi.setHostname(WiFi_hostname)) {
    debug("\nHostname set!\n");
  } else {
    debug("\nHostname NOT set!\n");
  }
}

j'ai vu que quand les variables sont utilisable dans toutes les parties du programme !!

pourquoi je et dès erreur de programmation ??

papy_wifi_proc.cpp:9:20: error: 'mySSID' was not declared in this scope

 const char* ssid = mySSID;

                    ^

papy_wifi_proc.cpp:10:24: error: 'myPASSWORD' was not declared in this scope

 const char* password = myPASSWORD;

                        ^

papy_wifi_proc.cpp:11:29: error: 'myHostname' was not declared in this scope

 const char* WiFi_hostname = myHostname;

                             ^

sketch\papy_wifi_proc.cpp: In function 'void papy_wifi_proc()':

papy_wifi_proc.cpp:23:21: error: 'debug' was not declared in this scope

   debug("Disconnect");

                     ^

In file included from D:\Data Jeanne\Arduino\do_debug_3_1\do_debug_3_1.ino:13:0:

sketch\papy_wifi_proc.cpp: In function 'void papy_wifi_proc()':

papy_wifi_proc.cpp:23:21: error: no match for call to '(output) (const char [11])'

   debug("Disconnect");

                     ^

papy_wifi_proc.cpp:30:36: error: no match for call to '(output) (const char [24])'

     debug("STA Failed to configure");

                                    ^

papy_wifi_proc.cpp:36:14: error: no match for call to '(output) (const char [2])'

     debug("!");

              ^

papy_wifi_proc.cpp:39:11: error: no match for call to '(output) (const char [1])'

   debug("");

           ^

papy_wifi_proc.cpp:40:23: error: no match for call to '(output) (const char [13])'

   debug("Hostname to ");

                       ^

papy_wifi_proc.cpp:41:22: error: no match for call to '(output) (const char*&)'

   debug(WiFi_hostname);

                      ^

papy_wifi_proc.cpp:43:11: error: no match for call to '(output) (const char [1])'

   debug("");

           ^

papy_wifi_proc.cpp:44:24: error: no match for call to '(output) (const char [14])'

   debug("Connected to ");

                        ^

papy_wifi_proc.cpp:45:13: error: no match for call to '(output) (const char*&)'

   debug(ssid);

             ^

papy_wifi_proc.cpp:46:23: error: no match for call to '(output) (const char [13])'

   debug("IP address: ");

                       ^

papy_wifi_proc.cpp:47:23: error: no match for call to '(output) (IPAddress)'

   debug(WiFi.localIP());

                       ^

papy_wifi_proc.cpp:49:30: error: no match for call to '(output) (const char [16])'

     debug("\nHostname set!\n");

                              ^

papy_wifi_proc.cpp:51:34: error: no match for call to '(output) (const char [20])'

     debug("\nHostname NOT set!\n");

                                  ^

D:\Data Jeanne\Arduino\do_debug_3_1\do_debug_3_1.ino: In function 'void setup()':

do_debug_3_1:21:9: error: 'class output' has no member named 'debugln'

   debug.debugln("et voila");

         ^

do_debug_3_1:23:10: error: 'class HardwareSerial' has no member named 'debugln'

   Serial.debugln("");

          ^

do_debug_3_1:24:10: error: 'class HardwareSerial' has no member named 'debugln'

   Serial.debugln("Booting + Serial");

          ^

do_debug_3_1:27:11: error: no match for call to '(output) (const char [1])'

   debug("");

           ^

do_debug_3_1:28:27: error: no match for call to '(output) (const char [17])'

   debug("Booting + Serial");

                           ^

do_debug_3_1:38:11: error: no match for call to '(output) (const char [1])'

   debug("");

           ^

do_debug_3_1:39:27: error: no match for call to '(output) (const char [17])'

   debug("Booting + Serial");

                           ^

D:\Data Jeanne\Arduino\do_debug_3_1\do_debug_3_1.ino: In function 'void loop()':

do_debug_3_1:43:16: error: no match for call to '(output) (const char [6])'

   debug("hello");

                ^

Multiple libraries were found for "WiFi.h"
 Used: C:\Users\rserr\AppData\Local\Arduino15\packages\esp32\hardware\esp32\1.0.4\libraries\WiFi
 Not used: C:\Program Files (x86)\Arduino\libraries\WiFi
exit status 1
'mySSID' was not declared in this scope

merci

Il faut que les variables ou constantes soient définies ou déclarées avant d'être utilisées soient dans le fichier soit dans un .h donc il faut que myDebugging_set soit défini dans do_debugging.cpp
Idem pour mySSID, myPASSWORD ... qui doivent être définis dans papy_wifi_proc.cpp donc credentials.h doit être inclus dans ce fichier.

Les .cpp ne doivent pas être inclus dans le .ino. Il seront compilés séparément dans l'ide, simplement car ils sont dans le répertoire de travail.