Erreur compilation bibli Keypad, Je ne comprends pas...

Bonjour,
Je suis confronté à un problème que je n'arrive pas à comprendre...
IDE 1.8.8, support ESP8266 installé, j'ai déjà réalisé plusieurs programmes sans problème

Code 1 :

//#include <Keypad.h>
#include <ESP8266WiFi.h>

void setup() {}

void loop() {}

Ca compile...

Code 2 :

#include <Keypad.h>
//#include <ESP8266WiFi.h>

void setup() {}

void loop() {}

Ca compile...

Code 3 :

#include <ESP8266WiFi.h>
#include <Keypad.h>


void setup() {}

void loop() {}

Ca compile...

Code 4 :

#include <Keypad.h>
#include <ESP8266WiFi.h>

void setup() {}

void loop() {}

Ca compile plus !!!

Erreurs :

Arduino : 1.8.8 (Windows 7), Carte : "WeMos D1 R1, 80 MHz, Flash, Enabled, 4M (no SPIFFS), v2 Lower Memory, Disabled, None, Only Sketch, 921600"

In file included from sketch\test.ino.cpp:1:0:

C:\Users\FRED\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.5.0-beta2\cores\esp8266/Arduino.h:43:14: error: expected identifier before numeric constant

 #define HIGH 0x1

              ^

D:\Info-tronique\arduino-1.8.8\libraries\Keypad\src/Keypad.h:56:16: note: in expansion of macro 'HIGH'

 #define CLOSED HIGH

                ^

C:\Users\FRED\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.5.0-beta2\libraries\ESP8266WiFi\src/include/wl_definitions.h:73:3: note: in expansion of macro 'CLOSED'

   CLOSED      = 0,

   ^

C:\Users\FRED\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.5.0-beta2\cores\esp8266/Arduino.h:43:14: error: expected '}' before numeric constant

 #define HIGH 0x1

              ^

D:\Info-tronique\arduino-1.8.8\libraries\Keypad\src/Keypad.h:56:16: note: in expansion of macro 'HIGH'

 #define CLOSED HIGH

                ^

C:\Users\FRED\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.5.0-beta2\libraries\ESP8266WiFi\src/include/wl_definitions.h:73:3: note: in expansion of macro 'CLOSED'

   CLOSED      = 0,

   ^

C:\Users\FRED\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.5.0-beta2\cores\esp8266/Arduino.h:43:14: error: expected unqualified-id before numeric constant

 #define HIGH 0x1

              ^

D:\Info-tronique\arduino-1.8.8\libraries\Keypad\src/Keypad.h:56:16: note: in expansion of macro 'HIGH'

 #define CLOSED HIGH

                ^

C:\Users\FRED\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.5.0-beta2\libraries\ESP8266WiFi\src/include/wl_definitions.h:73:3: note: in expansion of macro 'CLOSED'

   CLOSED      = 0,

   ^

In file included from D:\Info-tronique\PROJETS\test\test.ino:2:0:

C:\Users\FRED\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.5.0-beta2\libraries\ESP8266WiFi\src/ESP8266WiFi.h:29:1: error: expected declaration before '}' token

 }

 ^

exit status 1
Erreur de compilation pour la carte WeMos D1 R1

Ce rapport pourrait être plus détaillé avec
l'option "Afficher les résultats détaillés de la compilation"
activée dans Fichier -> Préférences.

J'en arrive à la conclusion que la bibli ESP redéfinit (ou efface) certaines variables déclarées dans Keypad ?

Je t'envoie un exorciste ?

La bib ESP8266Wifi a beaucoup de dépendances :

#include <stdint.h>

extern "C" {
#include "include/wl_definitions.h"
}

#include "IPAddress.h"

#include "ESP8266WiFiType.h"
#include "ESP8266WiFiSTA.h"
#include "ESP8266WiFiAP.h"
#include "ESP8266WiFiScan.h"
#include "ESP8266WiFiGeneric.h"

#include "WiFiClient.h"
#include "WiFiServer.h"
#include "WiFiServerSecure.h"
#include "WiFiClientSecure.h"
#include "BearSSLHelpers.h"
#include "CertStoreBearSSL.h"

et dans wl_definitions.h on trouve :

enum wl_tcp_state {
  CLOSED      = 0,

Par ailleurs, dans Keypad.h, il y a :

#define CLOSED HIGH

alors, évidemment, ça couche pas ensemble tout ça...

Si tu déclares Keypad avant l'autre, le enum devient

HIGH = 0

Merci c'est bien ce que je pensais... J'avoue que j'ai fait les tests à 2h du mat, et que j'ai eu la flemme de pousser les recherches...

Donc l'utilisation des 2 biblis simultanément va clocher, non ? Il faudrait alors modifier une des définitions ?

Je pense qu'il vaudrait mieux chercher une autre bibliothèque pour le keypad, sinon la modifier

mais pourquoi en incluant dans l'autre sens, ça compile ? Pourtant on se retrouve à faire un #define d'un truc (CLOSED) qui est déjà défini comme une variable, ça devrait couiner aussi, non ?

bricofoy:
mais pourquoi en incluant dans l'autre sens, ça compile ? Pourtant on se retrouve à faire un #define d'un truc (CLOSED) qui est déjà défini comme une variable, ça devrait couiner aussi, non ?

D'accord avec toi, c'est bien ça qui me chiffonne...

N'oubliez pas la règle numéro 1 de la programmation : le compilateur a toujours raison...
Règle 2 : En cas de doute, se reporter à la règle numéro 1...

il y a plusieurs points:

  • il faut comprendre qu'un #define est traité syntaxiquement et dans l'ordre d'apparition (récursivement) par le pré processeur pour changer le code source. En gros c'est comme si toutes les fois où votre define apparaît ensuite dans le fichier, vous aviez fait un "rechercher et remplacer" par l'équivalent dans ce fichier.

Une fois que cette phase est effectuée, le compilateur fait son boulot et compile le code.

  • il faut se souvenir que votre programme Arduino est modifié par l'IDE. il injecte d'une part un fichier main.cpp et regroupe tout vos codes dans un même ficher en mettant en premiere ligne un #include <Arduino.h>

  • le fichier main.cpp contient dès sa première ligne l'ordre

#include <Arduino.h>

qui va donc aussi injecter le fichier Arduino.h à cet endroit. ça permet de connaître les spécificités de l'environnement partout dans le code.

#define HIGH 0x1

donc si vous prenez le code suivant

#define CLOSED HIGH
enum : byte {CLOSED = 0, TOTO, TATA} etat = CLOSED;

void setup() {
  Serial.begin(115200);
  Serial.println(CLOSED);
  Serial.println(etat);
}

void loop() {}

comme HIGH va être remplacé textuellement par 0x1 et donc ensuite CLOSED par 0x1 vous obtenez (en simplifiant un peu) le code suivant à compiler

enum : byte {0x1 = 0, TOTO, TATA} etat = 0x1;

void setup() {
  Serial.begin(115200);
  Serial.println(0x1);
  Serial.println(etat);
}

void loop() {}

et bien entendu l'enum est pas correct dans cette partie

enum : byte {[color=red]0x1 = 0[/color], TOTO, TATA} etat = 0x1;

car vous ne pouvez pas affecter une valeur à une valeur. le compilateur va gueuler en disant

[color=orange]expected identifier before numeric constant[/color]

Maintenant si vous prenez le code suivant où on redéfinit CLOSED après l'énumération :

enum : byte {CLOSED = 0, TOTO, TATA} etat = CLOSED;
#define CLOSED HIGH

void setup() {
  Serial.begin(115200);
  Serial.println(CLOSED);
  Serial.println(etat);
}

void loop() {}

Le define étant après l'enum, il n'en a pas modifié l'écriture pendant la phase de pre-processing.

Le define ne joue que dans le Serial.println()

Le pré-processeur va donc remplacer HIGH dans le define de CLOSED par 0x1 (puisque HIGH est défini avant par l'inclusion de Arduino.h que l'IDE a rajouté pour vous) et ensuite dans le print CLOSED sera remplacé par ce 0x1

Donc une fois l'injection de Arduino.h effectuée et le pré-processeur passé on aura le code équivalent à compiler suivant:

enum : byte {CLOSED = 0, TOTO, TATA} etat = CLOSED;

void setup() {
  Serial.begin(115200);
  Serial.println(0x1);
  Serial.println(etat);
}

void loop() {}

ici on voit bien qu'il n'y a plus d'incohérence. et donc ce code va compiler et s'exécuter correctement.

pas de magie noire :slight_smile: - les noms utilisés par les define disparaissent avant la phase de compilation

Perso, j'aime pas les define, je préfère justement les enum et const pour s'assurer que je ne dépends pas de remplacement de texte sauvage et que le compilo peut faire sont boulot de vérification sémantique sur les types.

Donc pour régler le problème, il faudrait modifier le contenu de la bibli Keypad, par exemple en changeant les noms des diverses valeurs définies par des #define afin de les rendre uniques.
Par exemple :

#define OPEN LOW
#define CLOSED HIGH

en

#define OPEN_K LOW
#define CLOSED_K HIGH

et ceci aussi bien dans ces define que dans toutes les occurrences de ces noms dans le code de la bibliothèque.

Dans le cpp :

case IDLE:
			if (button==CLOSED) {

deviendrait (seule occurrence) :

case IDLE:
			if (button==CLOSED_K) {

Je rappelle (gentiment) les propos du modérateur :Règles du forum francophone - #2 by jfs - Français - Arduino Forum

Durcissement de la surveillance du forum.... sans sommation
Les titres à la con style "aidez moi" "urgent" ou autre >>> poubelle
code pas entre les balises >> poubelle
UP >>> poubelle (même si le sujet à plein de réponses, désolé pour ceux qui ont contribué)
Les demandes déguisées n'indiquant pas sujet bac avec texte au kilomètre=>poubelle

Peut tu éditer ton premier message et y mettre un titre qui sera exploitable par le moteur de recherche du forum.
Les explications qui te sont actuellement fournies pourront servir à d'autres alors qu'avec ton titre elles sont définitivement perdues.

Merci.

Extrait du message épinglé "Règle du forum francophone" qui est à lire !

Pour que la recherche soit efficace, utilisez des titres « clairs » et en rapport avec votre question. Les messages avec des titres comme « A l'aide », « Help » ou équivalents ne sont, en général, pas lus ; donc pas de lecture, pas de réponse.

68tjs:
Je rappelle (gentiment) les propos du modérateur :Règles du forum francophone - #2 by jfs - Français - Arduino Forum
Peut tu éditer ton premier message et y mettre un titre qui sera exploitable par le moteur de recherche du forum.
Les explications qui te sont actuellement fournies pourront servir à d'autres alors qu'avec ton titre elles sont définitivement perdues.

Merci.

Extrait du message épinglé "Règle du forum francophone" qui est à lire !

Fait, désolé pour la gaffe.