Go Down

Topic: Paramètres de connection Wifi sur carte sd (Read 603 times) previous topic - next topic

Claude56

Bonjour,

Après avoir fait plusieurs wordclocks (arduino nano +ds3231) et je viens d'en faire une autre qui est connectée (en utilisant un wemos d1 mini).

Je voudrais améliorer ce prototype en permettant un changement facile de routeur wifi, sans avoir besoin de revenir dans le code ni d'utilser l' IDE Arduino pour cela.

J'ai donc ajouté un "shield" wemos sd card qui fonctionne sans problème mais je n'arrive pas à convertir les paramètres de connection lus sur la carte sd en paramètres utilisables par
Code: [Select]
WiFi.begin (ssid, password);

En sachant que lorsque les paramètres sont initialisées à partir du code cela prend cette forme:
Code: [Select]
char *ssid      = "xxxxxx";               // Set you WiFi SSID
char *password  = "yyyyyyyyyyy";


J'ai lu beaucoup de questions identiques à la mienne sur différents forums anglo-saxons mais malheureusement pas de réponse ou pas de réponse qui fonctionne.

Voici comment je récupère les paramètres lus sur la carte sd et comment j'essaie de les utiliser ensuite:
Code: [Select]

  // if the file is available, write to it:
  if (myFile) {
    while (myFile.available()) {
      //Serial.write(myFile.read());
      wifiSSID = myFile.readStringUntil('\n');  // copie la chaine jusqu'au retour chariot
      wifiPass = myFile.readStringUntil('\n');
  Serveur = myFile.readStringUntil('\n');
    }
    myFile.close();
char  wifiSSIDChar[ wifiSSID.length()+1]; // tableau de char de la taille du String ssid+1 (caractère de fin de ligne)
 wifiSSID.toCharArray( wifiSSIDChar, wifiSSID.length()+1);  // récupère le param dans le tableau de char 
  Serial.print("nom wifi ");
  Serial.println(wifiSSID); // affiche le tableau de char

char  wifiPassChar[ wifiPass.length()+1]; // tableau de char de la taille du String ssid+1 (caractère de fin de ligne)
 wifiPass.toCharArray( wifiPassChar, wifiPass.length()+1);  // récupère le param dans le tableau de char 
  Serial.print("nom pass ");
  Serial.println(wifiPass); // affiche le tableau de char

  ssid = wifiSSID;
 password = wifiPass;



Lorsque je compile ce code j'obtient l'erreur suivante : "cannot convert 'String' to 'char' in assignment".


Merci de votre aide








hbachetti

Je crois que la classe String ARDUINO ne possède pas d'opérateur direct d'affectation pour un char *.
Il y a une méthode c_str()

Attention, cette méthode retourne l'adresse d'un buffer qui peut devenir invalide si la String est détruite, par exemple si l'objet String est local, sur la pile donc.

Donc soit tu recopies dans une chaîne, soit l'objet String doit être global ou statique.

 
Linux is like a wigwam: no Windows, no Gates, and an Apache inside ...

Claude56


j'ai fait ceci

Code: [Select]
//char  wifiSSIDChar[ wifiSSID.length()+1]; // tableau de char de la taille du String ssid+1 (caractère de fin de ligne)
// wifiSSID.toCharArray( wifiSSIDChar, wifiSSID.length()+1);  // récupère le param dans le tableau de char 
 // Serial.print("nom wifi ");
  //Serial.println(wifiSSID); // affiche le tableau de char

//char  wifiPassChar[ wifiPass.length()+1]; // tableau de char de la taille du String ssid+1 (caractère de fin de ligne)
 //wifiPass.toCharArray( wifiPassChar, wifiPass.length()+1);  // récupère le param dans le tableau de char 
 // Serial.print("nom pass ");
 // Serial.println(wifiPass); // affiche le tableau de char
// ssid = wifiSSID;
 //password = wifiPass;
 
 ssid = wifiSSID.c_str();
  password=wifiPass.cstr();


mais à la compilation j'ai l'erreur suivante :

invalid conversion from 'const char*' to 'char' [-fpermissive]


J'ai fait une version light de mon code (avec seulement ce qui concerne le wifi et la carte sd)

Code: [Select]
#include <NTPtimeESP.h>
#include <SPI.h> // liaison avec le shield sd card
#include <SD.h> // gestion sd card

#define DEBUG_ON
NTPtime NTPch("pool.ntp.org");   // Choose server pool as required : time.google.com , fr.pool.ntp.org , ch.pool.ntp.org, pool.ntp.org
strDateTime dateTime;

//char *ssid      = "xxxxxx";               // Set you WiFi SSID
//char *password  = "yyyyyyyyyyy";
     
#define PIN           12    //   GPIO12 correspond à la pin D6 DU WEMOS mini D1  . Envoi les datas vers le ruban de leds
#define NUMPIXELS     144     // 144 leds en série



const int chipSelect = D4; // D4 (GPIO2) pin wemos utilisé pour la carte sd
String wifiSSID, wifiPass,Serveur;
char ssid, password ;
   
void setup()
{
  Serial.begin(9600); // Open serial communications and wait for port to open:
  while (!Serial) {
    ; // wait for serial port to connect. Needed for Leonardo only
  }
 
  Serial.print("Initializing SD card...");

  // see if the card is present and can be initialized:
  if (!SD.begin(chipSelect)) {
    Serial.println("Card failed, or not present");
    // don't do anything more:
    return;
  }
  Serial.println("card initialized.");

  // open the file. note that only one file can be open at a time,so you have to close this one before opening another.
  File myFile = SD.open("wifi.txt");

  // if the file is available, write to it:
  if (myFile) {
    while (myFile.available()) {
      //Serial.write(myFile.read());
      wifiSSID = myFile.readStringUntil('\n');  // copie la chaine jusqu'au retour chariot
      wifiPass = myFile.readStringUntil('\n');
  Serveur = myFile.readStringUntil('\n');
    }
    myFile.close();

Serial.print("WiFi SSID: ");
      Serial.println(wifiSSID);
      Serial.print("WiFi Pass: ");
      Serial.println(wifiPass);
  Serial.print("Serveur NTP: ");
      Serial.println(Serveur);
 
//char  wifiSSIDChar[ wifiSSID.length()+1]; // tableau de char de la taille du String ssid+1 (caractère de fin de ligne)
// wifiSSID.toCharArray( wifiSSIDChar, wifiSSID.length()+1);  // récupère le param dans le tableau de char 
 // Serial.print("nom wifi ");
  //Serial.println(wifiSSID); // affiche le tableau de char

//char  wifiPassChar[ wifiPass.length()+1]; // tableau de char de la taille du String ssid+1 (caractère de fin de ligne)
 //wifiPass.toCharArray( wifiPassChar, wifiPass.length()+1);  // récupère le param dans le tableau de char 
 // Serial.print("nom pass ");
 // Serial.println(wifiPass); // affiche le tableau de char
// ssid = wifiSSID;
 //password = wifiPass;
 
 ssid = wifiSSID.c_str();
  password=wifiPass.cstr();
 
 
  Serial.println(wifiSSID, wifiPass); // affiche le tableau de char 
  Serial.println(ssid,password);
}

  Serial.println();
  Serial.println("Boot effectué");
  Serial.println("Connection Wi-Fi en cours ");

  WiFi.mode(WIFI_STA);
  WiFi.begin (ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
    Serial.print(".");
    delay(500);
  }
  Serial.println("WiFi connectée");

} // fin du Setup


void loop()
{
 
} // fin du void loop





hbachetti

Code: [Select]

char ssid, password ;   // pas bon

// si les objets String sont déclarés en local (dans la fonction loop par exemple)

char ssid[30];             // adapter la longueur
char password[50];     // idem

strcpy(ssid, wifiSSID.c_str());
strcpy(password, wifiPass.c_str());
// ou mieux :
strncpy(ssid, wifiSSID.c_str(), 30);
strncpy(password, wifiPass.c_str(), 50);

// ou : si les objets String sont déclarés statiques ou globaux (en dehors des fonctions)

char *ssid;
char *password;

ssid = wifiSSID.c_str();
password=wifiPass.cstr();


Linux is like a wigwam: no Windows, no Gates, and an Apache inside ...

CelticLord

Bonsoir, utilise wifimanager pour changer de wifi sans toucher au code

Claude56

Bonsoir hbachetti , je te remercie de tes réponses mais malheureusement je ne vois pas encore le bout du tunnel :

En déclarant char *ssid et char *password en global j'ai à nouveau  l'erreur "invalid conversion from 'const char*' to 'char*' [-fpermissive]"


et en les déclarant en local dans setup  l'erreur est la suivante: "incompatible types in assignment of 'const char*' to 'char [30]'   "

Est ce que tout cela ne viendrait pas de la librairie SerialESP8266wifi.h qui elle-même est appelée par NTPtime for ESP8266.



Claude56

Bonsoir CelticLord
j'ai essayé de télécharger les premiers fichiers examples de Wifimanager mais à chaque fois j'ai une erreur : Erreur de compilation pour la carte WeMos D1(Retired)

ma carte est une wemos V3.0.0 certes retired chez wemos mais qui jusque là faisait le job. Après je ne sais pas  si ça vient de la carte ou pas.
Demain j'essayerais directement dans mon code pour avoir le coeur net.
Merci.

hbachetti

#7
Mar 29, 2019, 09:54 pm Last Edit: Mar 29, 2019, 10:19 pm by hbachetti
Quote
En déclarant char *ssid et char *password en global j'ai à nouveau  l'erreur "invalid conversion from 'const char*' to 'char*' [-fpermissive]"
et en les déclarant en local dans setup  l'erreur est la suivante: "incompatible types in assignment of 'const char*' to 'char [30]'   "
Poste ton code ...
Linux is like a wigwam: no Windows, no Gates, and an Apache inside ...

Claude56

Voici mon code :
Code: [Select]
#include <NTPtimeESP.h>
#include <SPI.h> // liaison avec le shield sd card
#include <SD.h> // gestion sd card

#define DEBUG_ON
NTPtime NTPch("pool.ntp.org");   // Choose server pool as required : time.google.com , fr.pool.ntp.org , ch.pool.ntp.org, pool.ntp.org
strDateTime dateTime;


#define PIN           12    //   GPIO12 correspond à la pin D6 DU WEMOS mini D1  . Envoi les datas vers le ruban de leds
#define NUMPIXELS     144     // 144 leds en série

const int chipSelect = D4; // D4 (GPIO2) pin wemos utilisé pour la carte sd
String wifiSSID, wifiPass,Serveur;

   
void setup()
{
  Serial.begin(9600); // Open serial communications and wait for port to open:
  while (!Serial) {
    ; // wait for serial port to connect. Needed for Leonardo only
  }
 
  Serial.print("Initializing SD card...");

  // see if the card is present and can be initialized:
  if (!SD.begin(chipSelect)) {
    Serial.println("Card failed, or not present");
    // don't do anything more:
    return;
  }
  Serial.println("card initialized.");

  // open the file. note that only one file can be open at a time,so you have to close this one before opening another.
  File myFile = SD.open("wifi.txt");

  // if the file is available, write to it:
  if (myFile) {
    while (myFile.available()) {
      //Serial.write(myFile.read());
      wifiSSID = myFile.readStringUntil('\n');  // copie la chaine jusqu'au retour chariot
      wifiPass = myFile.readStringUntil('\n');
  Serveur = myFile.readStringUntil('\n');
    }
    myFile.close();

Serial.print("WiFi SSID: ");
      Serial.println(wifiSSID);
      Serial.print("WiFi Pass: ");
      Serial.println(wifiPass);
  Serial.print("Serveur NTP: ");
      Serial.println(Serveur);
 

 char ssid[30];             // adapter la longueur
char password[50];     // idem

strncpy(ssid, wifiSSID.c_str(), 30);
strncpy(password, wifiPass.c_str(), 50);
 
 ssid = wifiSSID.c_str();
  password=wifiPass.cstr();
 
 
  Serial.println(wifiSSID, wifiPass); // affiche le tableau de char 
  Serial.println(ssid,password);
}

  Serial.println();
  Serial.println("Boot effectué");
  Serial.println("Connection Wi-Fi en cours ");

  WiFi.mode(WIFI_STA);
  WiFi.begin (ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
    Serial.print(".");
    delay(500);
  }
  Serial.println("WiFi connectée");

} // fin du Setup


void loop()
{
 
} // fin du void loop

Claude56

Bonjour ,
testé Wifimanager dans mon code . J'ai toujours l'erreur de compilation qui apparemment proviendrais de  Webserver :


ESP8266WebServer.h:81:8: note:   candidate expects 4 arguments, 2 provided

hbachetti

Code: [Select]


  char ssid[30];             // adapter la longueur
  char password[50];     // idem

  strncpy(ssid, wifiSSID.c_str(), 30);
  strncpy(password, wifiPass.c_str(), 50);
 
  ssid = wifiSSID.c_str();               // pas OK
  password=wifiPass.cstr();          // pas OK

  Serial.println(wifiSSID, wifiPass); // println n'accepte pas deux arguments
  Serial.println(ssid,password);

}                                           accolade mal placée



Tu fais les choses en double et la deuxième manière de faire n'est pas bonne.

En fait comme tes variables ssid et password sont utilisées dans le setup et nulle part ailleurs, tu pourrais écrire :

Code: [Select]

char *ssid;
char *password;

ssid = wifiSSID.c_str();
password=wifiPass.cstr();


Linux is like a wigwam: no Windows, no Gates, and an Apache inside ...

Claude56

Bonsoir,

J'ai testé la solution proposée mais j'ai l'erreur :
 invalid conversion from 'const char*' to 'char*' [-fpermissive]

le code utilisé est
Code: [Select]
#include <NTPtimeESP.h>
#include <SPI.h> // liaison avec le shield sd card
#include <SD.h> // gestion sd card

#define DEBUG_ON
NTPtime NTPch("pool.ntp.org");   // Choose server pool as required : time.google.com , fr.pool.ntp.org , ch.pool.ntp.org, pool.ntp.org
strDateTime dateTime;


#define PIN           12    //   GPIO12 correspond à la pin D6 DU WEMOS mini D1  . Envoi les datas vers le ruban de leds
#define NUMPIXELS     144     // 144 leds en série

const int chipSelect = D4; // D4 (GPIO2) pin wemos utilisé pour la carte sd
String wifiSSID, wifiPass,Serveur;


   
void setup()
{
 char *ssid;
char *password;

  Serial.begin(9600); // Open serial communications and wait for port to open:
  while (!Serial) {
    ; // wait for serial port to connect. Needed for Leonardo only
  }
 
  Serial.print("Initializing SD card...");

  // see if the card is present and can be initialized:
  if (!SD.begin(chipSelect)) {
    Serial.println("Card failed, or not present");
    // don't do anything more:
    return;
  }
  Serial.println("card initialized.");

  // open the file. note that only one file can be open at a time,so you have to close this one before opening another.
  File myFile = SD.open("wifi.txt");

  // if the file is available, write to it:
  if (myFile) {
    while (myFile.available()) {
      //Serial.write(myFile.read());
      wifiSSID = myFile.readStringUntil('\n');  // copie la chaine jusqu'au retour chariot
      wifiPass = myFile.readStringUntil('\n');
  Serveur = myFile.readStringUntil('\n');


ssid = wifiSSID.c_str();
password=wifiPass.c_str();
    }
    myFile.close();




        }
        Serial.println("");

  Serial.println();
  Serial.println("Boot effectué");
  Serial.println("Connection Wi-Fi en cours ");

  WiFi.mode(WIFI_STA);
  WiFi.begin(( char)ssid), ( char)pass);
  while (WiFi.status() != WL_CONNECTED) {
    Serial.print(".");
    delay(500);
  }
  Serial.println("WiFi connectée");

} // fin du Setup


void loop()
{
 
} // fin du void loop

hbachetti

Code: [Select]

    const char *ssid;
    const char *password;


Linux is like a wigwam: no Windows, no Gates, and an Apache inside ...

Claude56

Bonjour,

maintenant l'erreur est différente :

cast from 'const char*' to 'char' loses precision [-fpermissive]

hbachetti

Code: [Select]

  WiFi.begin(( char)ssid), ( char)pass); // pourquoi caster en char ???
                                          // et pass n'existe pas

  WiFi.begin(ssid, password); // ok



Comprends-tu la différence entre un char, un char[] et un char * ?

char c;            // un caractère unique
char s[10];      // une chaîne de 10 caractères (normalement le dernier est un terminateur et vaut '\0')
char *p;          // un pointeur sur un caractère ou une chaîne de caractères

p = s;             // ok
p = &c;           // ok

La méthode WIFI.begin attend deux chaînes, pas deux caractères.

Tu as vraiment besoin d'un tuto sur le sujet : http://www.mon-club-elec.fr/pmwiki_reference_arduino/pmwiki.php?n=Main.ChainesCaracteres


Linux is like a wigwam: no Windows, no Gates, and an Apache inside ...

Go Up