IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Arduino Discussion :

ESP32 et BLE


Sujet :

Arduino

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre Expert Avatar de edgarjacobs
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mai 2011
    Messages
    784
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 65
    Localisation : Belgique

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Mai 2011
    Messages : 784
    Par défaut
    actuellement le logiciel prévoit à terme 9 adresses possibles mais comment puis-je faire à l'aide d'un fichier "config.txt" par ex
    pour initialiser ces adresses au fur et à mesure du raccordements des PC
    en gros si je mets une nouvelle PC , comment puis-je faire pour la faire reconnaitre de façon automatique par le logiciel
    Ça, sur micro-contrôleur, c'est totalement en-dehors de mes compétences. Ce que je peux te dire, c'est que ça va changer la physionnomie de ton programme, car Button buttons[9] va devenir Button *buttons, et après avoir lu (sur une carte sd je suppose) le nombre de boutons, tu vas devoir faire un malloc(). Maintenant, je réagis en tant que programmeur C sur pc, il se peut que je me plante complètement. Edit: et dites-le moi svp, je continue à apprendre. Merci.

  2. #2
    Expert confirmé

    Homme Profil pro
    mad scientist :)
    Inscrit en
    Septembre 2019
    Messages
    2 908
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : mad scientist :)

    Informations forums :
    Inscription : Septembre 2019
    Messages : 2 908
    Par défaut
    oui c'est une règle générale du C++
    on ne peut utiliser que quelque chose qui a été déclarée avant sinon le compilateur ne comprend pas ce que l'on veut faire

  3. #3
    Expert confirmé

    Homme Profil pro
    mad scientist :)
    Inscrit en
    Septembre 2019
    Messages
    2 908
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : mad scientist :)

    Informations forums :
    Inscription : Septembre 2019
    Messages : 2 908
    Par défaut
    il suffisait sans doute de mettre le tableau de structures en RTC_DATA_ATTR

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    // Structure pour représenter un bouton
    struct Button {
      int x, y;
      bool state;
    };
     
    RTC_DATA_ATTR Button buttons[9]; // 9 boutons

  4. #4
    Membre éprouvé
    Inscrit en
    Juillet 2004
    Messages
    966
    Détails du profil
    Informations forums :
    Inscription : Juillet 2004
    Messages : 966
    Par défaut
    ah oui , effectivement je n'y avais pas pensé

    la seule contrainte est bien de déclarer la structure avant
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    // Structure pour représenter un bouton *************
    struct Button {
      int x, y;
      bool state;
    };
    puis de faire appel à :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    RTC_DATA_ATTR Button buttons[9]; // 9 boutons
    sinon plantage à la compilation

  5. #5
    Expert confirmé

    Homme Profil pro
    mad scientist :)
    Inscrit en
    Septembre 2019
    Messages
    2 908
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : mad scientist :)

    Informations forums :
    Inscription : Septembre 2019
    Messages : 2 908
    Par défaut
    À moins de sauver dans le fichier à chaque modification d’état, la valeur que vous avez dans le fichier, ne va jamais changer

  6. #6
    Membre éprouvé
    Inscrit en
    Juillet 2004
    Messages
    966
    Détails du profil
    Informations forums :
    Inscription : Juillet 2004
    Messages : 966
    Par défaut
    J'ai modifié comme suit :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
     
    RTC_DATA_ATTR uint8_t etat[] = {0,0,0,0,0,0,0,0,0};
    ....
    int buttonX = 20;
      int buttonY = 20;
      for (int i = 0; i < 9; ++i)
      {
        buttons[i].x = buttonX;
        buttons[i].y = buttonY;
        //buttons[i].state = false;
    	buttons[i].state = etat[i]; // <=================================
     
     
        // Affichage des boutons
        drawButton(buttonX, buttonY, buttons[i].state);
     
        buttonX += BUTTON_WIDTH + BUTTON_MARGIN;
        if (buttonX + BUTTON_WIDTH > tft.width()) {
          buttonX = 20;
          buttonY += BUTTON_HEIGHT + BUTTON_MARGIN;
        }
      }
    puis

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    void loop()
    {
      currentTime=millis();
     
    	  // Vérifie si l'écran tactile a été touché et imprime les informations X, Y et la pression (Z) sur l'écran TFT et le moniteur série.
    	  if (touchscreen.tirqTouched() && touchscreen.touched())
    	  {
    		previousTime=currentTime;  
    		// Get Touchscreen points
    		TS_Point p = touchscreen.getPoint();
    		// Calibrate Touchscreen points with map function to the correct width and height
    		touchX = map(p.x, 200, 3700, 1, SCREEN_WIDTH);
    		touchY = map(p.y, 240, 3800, 1, SCREEN_HEIGHT);
    		touchZ = p.z;
    
    		//printTouchToSerial(touchX, touchY, touchZ);
    
    		for (int i = 0; i < 9; ++i)
    		{
    		  if (touchX >= buttons[i].x && touchX <= buttons[i].x + BUTTON_WIDTH &&
    			  touchY >= buttons[i].y && touchY <= buttons[i].y + BUTTON_HEIGHT)
    		  {
    			// Si un bouton est touché, inverse son état et met à jour l'affichage
    			buttons[i].state = !buttons[i].state;
    			drawButton(buttons[i].x, buttons[i].y, buttons[i].state);
    			if (buttons[i].state == 1) {
    			  Serial.print("Btn "); Serial.print(i + 1); Serial.println(" enfoncé");
    			  snprintf(myData.a, sizeof myData.a, "PC%02d=> ON", i + 1);
    			  myData.b =  true;
    			  esp_err_t result = esp_now_send(clients[i].adresse, (uint8_t *)&myData, sizeof(myData));
    			  if (result == ESP_OK) {
    				Serial.print("PC"); Serial.print(i + 1); Serial.println(" Envoyé avec succès");
    				etat[i] = 1; <================================================
    			  } else {
    				Serial.print("Erreur d'envoi des données PC"); Serial.print(i + 1);
    			  }
    			}
    
    			if (buttons[i].state == 0)
    			{
    			  Serial.print("Btn "); Serial.print(i + 1); Serial.println(" relaché");
    			  snprintf(myData.a, sizeof myData.a, "PC%02d=> OFF", i + 1);
    			  myData.b =  false;
    			  esp_err_t result = esp_now_send(clients[i].adresse, (uint8_t *)&myData, sizeof(myData));
    			  if (result == ESP_OK) {
    				Serial.print("PC"); Serial.print(i + 1); Serial.println(" Envoyé avec succès");
    				etat[i] = 0;  // <=================================================
    			  } else {
    				Serial.print("Erreur d'envoi des données PC"); Serial.print(i + 1);
    			  }
    			}
    		  }
    		  //break;
    		  delay(200);
    		}
    	  }
    	   if((currentTime-previousTime)>10000){  
    	   //Go to sleep now
             Serial.println("Je vais m'endormir maintenant");
             delay(1000);
             esp_deep_sleep_start();  
    	   }  
    }
    et çà fonctionne , j'ai bien une mise en mémoire des états de chaque boutons

  7. #7
    Expert confirmé

    Homme Profil pro
    mad scientist :)
    Inscrit en
    Septembre 2019
    Messages
    2 908
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : mad scientist :)

    Informations forums :
    Inscription : Septembre 2019
    Messages : 2 908
    Par défaut
    si c'est sur un ESP32 vous pourriez stocker le fichier de configuration en mémoire flash en utilisant LittleFS ou SPIFF

    il faudra bien sûr dans ce cas rajouter des fonctions de lecture du fichier dans le setup pour la configuration

  8. #8
    Membre éprouvé
    Inscrit en
    Juillet 2004
    Messages
    966
    Détails du profil
    Informations forums :
    Inscription : Juillet 2004
    Messages : 966
    Par défaut
    J'ai tenté de faire çà à partir d'un fichier "config.txt"

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    // Adresses MAC
     
    #adresse1;{0xb4, 0xe6, 0x2d, 0x78, 0x83, 0x54};
    #adresse2;{0xb4, 0xe6, 0x2d, 0x78, 0x83, 0x54};
    #adresse3;{0xb4, 0xe6, 0x2d, 0x78, 0x83, 0x54};
    #adresse4;{0xb4, 0xe6, 0x2d, 0x78, 0x83, 0x54};
    #adresse5;{0xb4, 0xe6, 0x2d, 0x78, 0x83, 0x54};
    #adresse6;{0xb4, 0xe6, 0x2d, 0x78, 0x83, 0x54};
    #adresse7;{0xb4, 0xe6, 0x2d, 0x78, 0x83, 0x54};
    #adresse8;{0xb4, 0xe6, 0x2d, 0x78, 0x83, 0x54};
    #adresse9;{0xb4, 0xe6, 0x2d, 0x78, 0x83, 0x54};
    avec une structure de lecture comme :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    uint8_t broadcastAddress[][1] = {
    	&adresse1,		// adr mac1
    	&adresse2,		// adr mac2
    	&adresse3,    // adr mac3
            &adresse4,    // adr mac4
            &adresse5,    // adr mac5
            &adresse6,    // adr mac6
            &adresse7,    // adr mac7
    	&adresse8, 	  // adr mac8
            &adresse9,		// adr mac9
    };
    mais le compilateur ne veut pas :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    Compilation error: 'adresse1' was not declared in this scope
    en outre dans la déclaration de SPIFFS.h et FS.h

    le compilateur cherche :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
     
     if(!SPIFFS.begin(true)){
        Serial.println("Une erreur s'est produite lors du montage de SPIFFS");
        return;
      } 
     
      File file = SPIFFS.open("/config.txt");
     
      if(!file){
        Serial.println("Échec de l'ouverture du fichier en lecture");
        return;
      }
     
      Serial.println("Contenu du fichier:");
      while(file.available()){
          Serial.write(file.read());
      }
      file.close();
    mais au final
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
     error: 'file' was not declared in this scope
    Faut-il téléverser préalablement le fichier "config.txt" pour vérifier le croquis ?

  9. #9
    Expert confirmé

    Homme Profil pro
    mad scientist :)
    Inscrit en
    Septembre 2019
    Messages
    2 908
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : mad scientist :)

    Informations forums :
    Inscription : Septembre 2019
    Messages : 2 908
    Par défaut
    l'écran est alimenté via GPIO021
    une pin n'est généralement pas une bonne source de courant ! voulez vous dire que c'est un pin "enable" et qu'il y a un VCC par ailleurs ?

    est-ce que votre module dispose bien d'un vbatPin qui fait la mesure ?

  10. #10
    Membre éprouvé
    Inscrit en
    Juillet 2004
    Messages
    966
    Détails du profil
    Informations forums :
    Inscription : Juillet 2004
    Messages : 966
    Par défaut
    une pin n'est généralement pas une bonne source de courant ! voulez vous dire que c'est un pin "enable" et qu'il y a un VCC par ailleurs ?
    oui pardon , mauvaise formulation , il s'agit bien de GPIO021 où est raccordée la LED mais l'écran lui est alimenté en 3.3v à partir de l'ESP32
    est-ce que votre module dispose bien d'un vbatPin qui fait la mesure ?
    Oui , une entrée lui est dédiée GPIO35

    je calcule vBat de cette façon :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    void Calcul_vBat(){
        int cmpt = 8;
        int vBatOld = 0 ; 
        do {
           cmpt--;
           valeurBrute  = analogRead(vbatPin); // tension échantillonnée brute
           vBatOld = valeurBrute;
        } while((abs(valeurBrute-vBatOld) > DELTA) && (cmpt > 0));
        vBat = 1.40*(valeurBrute/4095.0)*3.3; // modification changement carte uPesy Vbat Brute = 3804 pour 100%
        progress = ((vBat-3.2)*100);
    }
    Images attachées Images attachées  

  11. #11
    Expert confirmé

    Homme Profil pro
    mad scientist :)
    Inscrit en
    Septembre 2019
    Messages
    2 908
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : mad scientist :)

    Informations forums :
    Inscription : Septembre 2019
    Messages : 2 908
    Par défaut
    pas besoin charger config.txt avant de compiler, la vérification du code se fait sur le respect du C++

    pouvez vous poster votre code complet (un petit programme) qui lirait ce fichier de config ? (qui est bien compliqué vous devriez simplement séparer les champs par un espace ou une virgule)

  12. #12
    Membre éprouvé
    Inscrit en
    Juillet 2004
    Messages
    966
    Détails du profil
    Informations forums :
    Inscription : Juillet 2004
    Messages : 966
    Par défaut
    Voici le croquis complet :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
     
    // EMETTEUR uPesy ESP32 Wroom DevKit
    #include <SPI.h>
    #include <TFT_eSPI.h>
    #include <XPT2046_Touchscreen.h> // https : //github. com/PaulStoffregen/XPT2046_Touchscreen
    #include <esp_now.h>
    #include <WiFi.h>
    #include "FS.h"
    #include "SPIFFS.h"
     
    TFT_eSPI tft = TFT_eSPI();
     
    // Touchscreen pins
    #define XPT2046_IRQ 36   // T_IRQ
    #define XPT2046_MOSI 32  // T_DIN
    #define XPT2046_MISO 39  // T_OUT
    #define XPT2046_CLK 25   // T_CLK
    #define XPT2046_CS 33    // T_CS
     
    SPIClass touchscreenSPI = SPIClass(VSPI);
    XPT2046_Touchscreen touchscreen(XPT2046_CS, XPT2046_IRQ);
     
    #define SCREEN_WIDTH 320
    #define SCREEN_HEIGHT 240
    #define FONT_SIZE 2
     
    // definition des boutons
    #define BUTTON_WIDTH  80
    #define BUTTON_HEIGHT 60
    #define BUTTON_MARGIN 10
     
    // Structure pour représenter un bouton
    struct Button {
      int x, y;
      bool state;
    };
     
    Button buttons[9]; // 9 boutons
     
    // Coordonnées de l'écran tactile : (x, y) et pression (z)
    int x, y, z;
     
    // Imprimer les informations de l'écran tactile concernant X, Y et la pression (Z) sur le moniteur série
    void printTouchToSerial(int touchX, int touchY, int touchZ) {
      Serial.print("X = ");
      Serial.print(touchX);
      Serial.print(" | Y = ");
      Serial.print(touchY);
      Serial.print(" | Pressure = ");
      Serial.print(touchZ);
      Serial.println();
    }
     
    /******************************************************/
     
    //******************** Adresse Mac 
     
    uint8_t broadcastAddress[][1] = {
    	&adresse1,		// adr mac1
    	&adresse2,		// adr mac2
    	&adresse3,    // adr mac3
      &adresse4,    // adr mac4
      &adresse5,    // adr mac5
      &adresse6,    // adr mac6
      &adresse7,    // adr mac7
    	&adresse8, 	  // adr mac8
      &adresse9,		// adr mac9
    };
     
    // ************** la structure du récepteur
    typedef struct struct_message {
      char a[32];
      bool b;
    } struct_message;
    // Create a struct_message called myData
    struct_message myData;
    esp_now_peer_info_t peerInfo;
    // *****************************rappel lorsque les données sont envoyées
    void OnDataSent(const uint8_t *mac_addr, esp_now_send_status_t status) {
      Serial.print("\r\nÉtat de l'envoi du dernier paquet:\t");
      Serial.println(status == ESP_NOW_SEND_SUCCESS ? "Succès" : "Échec");
    }
     
    int touchX, touchY, touchZ , i;
     
    //************************************************
    // SETUP
    //************************************************
    void setup()
    {
      Serial.begin(115200);
     
      if(!SPIFFS.begin(true)){
        Serial.println("Une erreur s'est produite lors du montage de SPIFFS");
        return;
      } 
     
      File file = SPIFFS.open("/config.txt");
     
      if(!file){
        Serial.println("Échec de l'ouverture du fichier en lecture");
        return;
      }
     
      Serial.println("Contenu du fichier:");
      while(file.available()){
          Serial.write(file.read());
      }
      file.close();
     
      // Set device as a Wi-Fi Station
      WiFi.mode(WIFI_STA);
      // Init ESP-NOW
      if (esp_now_init() != ESP_OK) {
        Serial.println("Erreur d'initialisation de l'ESP-NOW");
        return;
      }
      // Une fois que ESPNow est Init avec succès, nous nous inscrirons pour l'envoi du CB .
      // obtenir l'état du paquet transmis.
      esp_now_register_send_cb(OnDataSent);
      // Enregistrer un pair
      memcpy(peerInfo.peer_addr, broadcastAddress, 1);
      peerInfo.channel = 0;  
      peerInfo.encrypt = false;
      // Ajouter un pair        
      if (esp_now_add_peer(&peerInfo) != ESP_OK){
        Serial.println("Échec de l'ajout d'un pair");
        return;
      }
      // Start the SPI for the touchscreen and init the touchscreen
      touchscreenSPI.begin(XPT2046_CLK, XPT2046_MISO, XPT2046_MOSI, XPT2046_CS);
      touchscreen.begin(touchscreenSPI);
      // Set the Touchscreen rotation in landscape mode
      // Note: in some displays, the touchscreen might be upside down, so you might need to set the rotation to 3: touchscreen.setRotation(3);
      touchscreen.setRotation(3);
     
      // Start the tft display
      tft.init();
      // Set the TFT display rotation in landscape mode
      tft.setRotation(1);
     
      // Clear the screen before writing to it
      tft.fillScreen(TFT_BLACK);
     
      // Initialisation des positions des boutons
      int buttonX = 20;
      int buttonY = 20;
      for (int i = 0; i < 9; ++i) 
      {
        buttons[i].x = buttonX;
        buttons[i].y = buttonY;
        buttons[i].state = false;
     
        // Affichage des boutons
        drawButton(buttonX, buttonY, buttons[i].state);
     
        buttonX += BUTTON_WIDTH + BUTTON_MARGIN;
        if (buttonX + BUTTON_WIDTH > tft.width()) {
          buttonX = 20;
          buttonY += BUTTON_HEIGHT + BUTTON_MARGIN;
        }
      }
     
    }
     
    //************************************************
    // LOOP
    //************************************************
    void loop()
    {
     
      // Checks if Touchscreen was touched, and prints X, Y and Pressure (Z) info on the TFT display and Serial Monitor
      if (touchscreen.tirqTouched() && touchscreen.touched()) 
      {
        // Get Touchscreen points
        TS_Point p = touchscreen.getPoint();
        // Calibrate Touchscreen points with map function to the correct width and height
        touchX = map(p.x, 200, 3700, 1, SCREEN_WIDTH);
        touchY = map(p.y, 240, 3800, 1, SCREEN_HEIGHT);
        touchZ = p.z;
     
        //printTouchToSerial(touchX, touchY, touchZ);
     
         for (int i = 0; i < 9; ++i)
         {
            if (touchX >= buttons[i].x && touchX <= buttons[i].x + BUTTON_WIDTH &&
                touchY >= buttons[i].y && touchY <= buttons[i].y + BUTTON_HEIGHT) 
            {
              // Si un bouton est touché, inverse son état et met à jour l'affichage
              buttons[i].state = !buttons[i].state;
              drawButton(buttons[i].x, buttons[i].y, buttons[i].state);
              if (buttons[i].state == 1)
              {
                Serial.print("Btn "); Serial.print(i+1); Serial.println(" enfoncé");
                snprintf(myData.a, sizeof myData.a, "PC%02d=> ON", i+1);
                myData.b =  true;
                esp_err_t result = esp_now_send(broadcastAddress[i], (uint8_t *) &myData, sizeof(myData));
                if (result == ESP_OK) {
                    Serial.print("PC0");Serial.print(i+1); Serial.println(" Envoyé avec succès");
                }else {
                    Serial.print("Erreur d'envoi des données PC0");Serial.print(i+1);
                } 
              } 
              if (buttons[i].state == 0)
              {
                Serial.print("Btn "); Serial.print(i+1); Serial.println(" relaché");
                snprintf(myData.a, sizeof myData.a, "PC%02d=> OFF", i+1);
                myData.b =  false;
                esp_err_t result = esp_now_send(broadcastAddress[i], (uint8_t *) &myData, sizeof(myData));
                if (result == ESP_OK) {
                    Serial.print("PC0");Serial.print(i+1); Serial.println(" Envoyé avec succès");
                }else {
                    Serial.print("Erreur d'envoi des données PC0");Serial.print(i+1);
                } 
              } 
            }  
        //break;
        delay(200);
        }     
      }
    }
     
    // Dessine un bouton à une position donnée avec un état donné
    void drawButton(int x, int y, bool state) {
      uint16_t color = state ? TFT_RED : TFT_GREEN;
      tft.fillRect(x, y, BUTTON_WIDTH, BUTTON_HEIGHT, color);
      tft.drawRect(x, y, BUTTON_WIDTH, BUTTON_HEIGHT, TFT_WHITE);
     
    }

  13. #13
    Expert confirmé

    Homme Profil pro
    mad scientist :)
    Inscrit en
    Septembre 2019
    Messages
    2 908
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : mad scientist :)

    Informations forums :
    Inscription : Septembre 2019
    Messages : 2 908
    Par défaut
    quand on explore de nouvelles choses, le mieux c'est de faire d'abord un code dédié et quand ça fonctionne et qu'on a bien compris, on l'intègre dans le reste du code.

    Simplifions le fichier config.txt avec ce format

    NOM suivi de 6 octets en notation hexa

    disons que vos PC ont des noms de capitales et que le fichier est stocké en UTF8 (format que sait afficher un Arduino dans la console série)

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    Paris 0xb4 0xe6 0x2d 0x78 0x83 0x54
    Londres 0xb5 0xe6 0x2d 0x78 0x83 0x54
    Berlin 0xb6 0xe6 0x2d 0x78 0x83 0x54
    Rome 0xb7 0xe6 0x2d 0x78 0x83 0x54
    Madrid 0xb8 0xe6 0x2d 0x78 0x83 0x54
    Oslo 0xb9 0xe6 0x2d 0x78 0x83 0x54
    Varsovie 0xba 0xe6 0x2d 0x78 0x83 0x54
    Prague 0xbb 0xe6 0x2d 0x78 0x83 0x54
    Amsterdam 0xbc 0xe6 0x2d 0x78 0x83 0x54
    pour stocker cela en mémoire on aura besoin d'une structure qui contiendra le nom

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    const byte tailleMaxNom = 16; // y compris le caractère null final
    struct ClientPC {
      char nom[tailleMaxNom];
      byte  adresse[6];
    };
    et on aura besoin d'un tableau pour ranger ce que l'on lit avec un nombre maximum prédéterminé maximum de clients (c'est plus simple que de construire dynamiquement le tableau avec de l'allocation mémoire) et une autre variable qui dira combien réellement on en a utilisé
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    const size_t nbMaxClients = 20;     // nombre maximum de clients
    ClientPC clients[nbMaxClients]; 
    size_t nbClientsPC = 0;            // le nombre de clients lu dans le fichier de config
    ici j'alloue un tableau de 20 clients max et je dis que pour le moment ce tableau contient 0 entrées valides (on n'a pas encore lu le fichier de config).

    Pour lire le fichier de configuration, le plus simple c'est de lire une ligne dans un buffer mémoire, ça se fait avec
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    fichierConfig.readBytesUntil('\n', ...
    et pour faire l'analyse on peut utiliser sscanf() qui permet d'extraire des valeurs d'une chaîne de caractère avec %s et un octet en hexadécimal avec %hhx.

    Il y aura une petite subtilité pour lire le nom du client PC pour ne pas déborder la mémoire allouée (tailleMaxNom - 1 pour conserver 1 caractère pour le nul final) on n'utilisera pas directement %s qui est le format standard pour lire une chaîne de caractères jusqu'au prochain espace mais il faut utiliser %15s pour dire qu'on a au max 15 caractères.

    Le souci est que ce 15 qui correspond à (tailleMaxNom - 1) est variable et on ne peut pas coller 15 en dur dans le sscanf() donc on fabrique la chaîne qui définit le format grace à snprintf() ce qui nous permet d'injecter le 15 au bon endroit

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
      char format[64]; // pour bâtir dynamiquement le format en tenant compte de la longueur max du nom (reco de Kernighan et Pike dans "The Practice of Programming")
      snprintf(format, sizeof format, "%%%ds %%hhx %%hhx %%hhx %%hhx %%hhx %%hhx", tailleMaxNom - 1); // lire une chaine de taille max tailleMaxNom - 1 suivie de 6 octets en hexa
    (on met le % en double pour insérer un caractère % dans la chaîne, car % est un caractère réservé dans le format)

    voilà donc une fois cela bien compris et défini, il ne reste qu'à écrire un petit bout de code qui lit une ligne, fait le scanf() et rempli la structure puis passe à l'index suivant


    voici à quoi ça pourrait ressembler
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
     
    #include <SPIFFS.h>
     
    const size_t tailleMaxNom = 16;     // y compris le caractère nul final
     
    struct ClientPC {
      char nom[tailleMaxNom];           // le nom du client PC
      uint8_t adresse[6];               // les 6 octets de son adresse
    };
     
    const size_t nbMaxClients = 20;     // nombre maximum de clients
    ClientPC clients[nbMaxClients]; 
    size_t nbClientsPC = 0;            // le nombre de clients lu dans le fichier de config
     
     
    void setup() {
      Serial.begin(115200);
     
      if (!SPIFFS.begin(true)) {
        Serial.println("Une erreur s'est produite lors du montage de SPIFFS...");
        return;
      }
     
      File fichierConfig = SPIFFS.open("/config.txt", FILE_READ);
      if (!fichierConfig) {
        Serial.println("Impossible d'ouvrir le fichier en lecture");
        return;
      }
     
     
      char bufferLigne[100]; // Buffer pour stocker chaque ligne
      char format[64]; // pour bâtir dynamiquement le format en tenant compte de la longueur max du nom (reco de Kernighan et Pike dans "The Practice of Programming")
      snprintf(format, sizeof format, "%%%ds %%hhx %%hhx %%hhx %%hhx %%hhx %%hhx", tailleMaxNom - 1); // lire une chaine de taille max tailleMaxNom - 1 suivie de 6 octets en hexa
     
      nbClientsPC = 0;
      while (fichierConfig.available() && nbClientsPC < nbMaxClients) {   // tant qu'on peut lire quelque chose et qu'on a de la place pour stocker
        memset(bufferLigne, '\0', sizeof bufferLigne); // Effacer le buffer
        fichierConfig.readBytesUntil('\n', bufferLigne, sizeof bufferLigne); // Lire la ligne dans le buffer
        memset(clients[nbClientsPC].nom, '\0', sizeof clients[nbClientsPC].nom); // on efface le nom pour être tranquille
        int nbChampsLus = sscanf(bufferLigne, format,
                                 clients[nbClientsPC].nom,
                                 &clients[nbClientsPC].adresse[0], &clients[nbClientsPC].adresse[1],
                                 &clients[nbClientsPC].adresse[2], &clients[nbClientsPC].adresse[3],
                                 &clients[nbClientsPC].adresse[4], &clients[nbClientsPC].adresse[5]);
     
        if (nbChampsLus == 7) {
          // la lecture des 7 champs (le nom et 8 octets sous forme hexadécimale) s'est bien passée
          nbClientsPC++;
        } else {
          // on arrête de lire là
          break;
        }
      }
      fichierConfig.close();
     
      // Affichage des adresses lues depuis le fichier
      for (size_t i = 0; i < nbClientsPC; i++) {
        Serial.printf("%3zu %-*s : ", i+1, tailleMaxNom - 1, clients[i].nom); // l'index sur 3 caractères, le nom sur tailleMaxNom - 1 cadrée à gauche
        for (int j = 0; j < 6; j++) Serial.printf("0x%02X ", clients[i].adresse[j]);
        Serial.println();
      }
    }
     
    void loop() {}
    vous copiez cela dans un sketch que vous sauvez
    dans le répertoire du sketch vous créez un répertoire data (écrit comme cela exactement)
    dans ce répertoire vous mettez le fichier de config
    config.txt

    vous configurez l'IDE pour votre ESP32 et utilisez l'utilitaire qui charge ce qu'il y a dans data dans la partition SPIFF de votre carte

    vous compilez et chargez le code et ouvrez la console série à 115200 bauds

    si tout s'est bien passé vous verrez s'afficher

    1 Paris : 0xB4 0xE6 0x2D 0x78 0x83 0x54
    2 Londres : 0xB5 0xE6 0x2D 0x78 0x83 0x54
    3 Berlin : 0xB6 0xE6 0x2D 0x78 0x83 0x54
    4 Rome : 0xB7 0xE6 0x2D 0x78 0x83 0x54
    5 Madrid : 0xB8 0xE6 0x2D 0x78 0x83 0x54
    6 Oslo : 0xB9 0xE6 0x2D 0x78 0x83 0x54
    7 Varsovie : 0xBA 0xE6 0x2D 0x78 0x83 0x54
    8 Prague : 0xBB 0xE6 0x2D 0x78 0x83 0x54
    9 Amsterdam : 0xBC 0xE6 0x2D 0x78 0x83 0x54


    ce qui veut dire qu'on bien lu le fichier et rempli les 9 premières structures avec les infos du fichier de configuration.


    voilà - une fois que vous comprenez bien tout ce que fait le code, vous pourrez l'intégrer dans votre projet.

  14. #14
    Membre éprouvé
    Inscrit en
    Juillet 2004
    Messages
    966
    Détails du profil
    Informations forums :
    Inscription : Juillet 2004
    Messages : 966
    Par défaut
    Bonjour Jay M

    quand on explore de nouvelles choses, le mieux c'est de faire d'abord un code dédié et quand ça fonctionne et qu'on a bien compris, on l'intègre dans le reste du code.
    c'est noté , j'avais pris pourtant un tuto mais j'ai du oublier quelque chose

    j'ai quelques questions si vous le permettez :

    1) le fichier "fichierConfig" est dimensionné nul part semble-t--il et pourtant il ne plante pas le compilateur , dans mon exemple précédent, j'avais un fichier nommé 'file' et
    çà bloquait le compilateur par :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    error: 'file' was not declared in this scope
    pourquoi ?

    2) vous considérez la bonne réception du fichier à la 7ieme ligne
    pourquoi pas dès la seconde par ex ?

    3)J'ai eu des difficultés sur Arduino IDE 2.3.2 car je me suis aperçu ( un peu tardivement) que ne n'avait pas la possibilité d'uploader des fichiers SPIFFS à partir du menu
    alors que je l'ai bien avec la version Arduino 1.8.19 ?

    4)( voir image) J'ai fait une modification dans le fichier config.txt à la 5ieme ligne pour voir si le prog prenait les changements et visiblement çà fonctionne par contre
    j'ai une erreur 112 dont je ne connais pas la signification

    je vais maintenant essayer d’intégrer tout ceci dans mon prg

    merci encore
    pascal
    Images attachées Images attachées  

  15. #15
    Membre éprouvé
    Inscrit en
    Juillet 2004
    Messages
    966
    Détails du profil
    Informations forums :
    Inscription : Juillet 2004
    Messages : 966
    Par défaut
    j'ai intégré la modification du fichier "config.txt"
    dans le croquis final
    mais naturellement la compilation ne se passe pas comme prévue

    initialement j'avais çà pour transmettre les adresses MAC
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
     
    /******************************************************/
    /*
    uint8_t broadcastAddress[][6] = {
    	{0xb4, 0xe6, 0x2d, 0x78, 0x83, 0x54},		// adr mac1
    	{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF},		// adr mac2
    	{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF},              // adr mac3
            {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF},              // adr mac4
            {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF},              // adr mac5
            {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF},              // adr mac6
            {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF},              // adr mac7
    	{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF},		// adr mac8
            {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF},		// adr mac9
    };
    */
    maintenant j'ai çà :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    struct ClientPC {
      char nom[tailleMaxNom];           // le nom du client PC
      uint8_t adresse[6];               // les 6 octets de son adresse
    };
    j'ai remplacé le tableau broadcastAddress[][] par clients[].adresse[] mais sans succès...
    j'ai une erreur :


    D:\5- ELECTRONIQUE\SonOFF\Emetteur\E_V20240515a\E_V20240515a.ino: In function 'void loop()':
    E_V20240515a:236:154: error: invalid conversion from 'int' to 'const uint8_t*' {aka 'const unsigned char*'} [-fpermissive]
    esp_err_t result = esp_now_send(clients[i].adresse[0]&clients[i].adresse[1]&clients[i].adresse[2]&clients[i].adresse[3]&clients[i].adresse[4]&clients[i].adresse[5], (uint8_t *) &myData, sizeof(myData));
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~

    E_V20240515a:248:154: error: invalid conversion from 'int' to 'const uint8_t*' {aka 'const unsigned char*'} [-fpermissive]
    esp_err_t result = esp_now_send(clients[i].adresse[0]&clients[i].adresse[1]&clients[i].adresse[2]&clients[i].adresse[3]&clients[i].adresse[4]&clients[i].adresse[5], (uint8_t *) &myData, sizeof(myData));
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~
    In file included from D:\5- ELECTRONIQUE\SonOFF\Emetteur\E_V20240515a\E_V20240515a.ino:7:
    C:\Users\Utilisateur\AppData\Local\Arduino15\packages\esp32\hardware\esp32\2.0.15/tools/sdk/esp32/include/esp_wifi/include/esp_now.h:189:39: note: initializing argument 1 of 'esp_err_t esp_now_send(const uint8_t*, const uint8_t*, size_t)'
    esp_err_t esp_now_send(const uint8_t *peer_addr, const uint8_t *data, size_t len);
    ~~~~~~~~~~~~~~~^~~~~~~~~

    exit status 1
    invalid conversion from 'int' to 'const uint8_t*' {aka 'const unsigned char*'} [-fpermissive]
    ci-dessous le code actuel

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
    231
    232
    233
    234
    235
    236
    237
    238
    239
    240
    241
    242
    243
    244
    245
    246
    247
    248
    249
    250
    251
    252
    253
    254
    255
    256
    257
    258
    259
    260
    261
    262
    263
    264
    265
    266
    267
    268
    269
    270
     
    // EMETTEUR uPesy ESP32 Wroom DevKit //
     
    #include <SPIFFS.h>
    #include <SPI.h>
    #include <TFT_eSPI.h>
    #include <XPT2046_Touchscreen.h> // https : //github. com/PaulStoffregen/XPT2046_Touchscreen
    #include <esp_now.h>
    #include <WiFi.h>
     
     
    TFT_eSPI tft = TFT_eSPI();
     
    // Touchscreen pins
    #define XPT2046_IRQ 36   // T_IRQ
    #define XPT2046_MOSI 32  // T_DIN
    #define XPT2046_MISO 39  // T_OUT
    #define XPT2046_CLK 25   // T_CLK
    #define XPT2046_CS 33    // T_CS
     
    SPIClass touchscreenSPI = SPIClass(VSPI);
    XPT2046_Touchscreen touchscreen(XPT2046_CS, XPT2046_IRQ);
     
    #define SCREEN_WIDTH 320
    #define SCREEN_HEIGHT 240
    #define FONT_SIZE 2
     
    // definition des boutons
    #define BUTTON_WIDTH  80
    #define BUTTON_HEIGHT 60
    #define BUTTON_MARGIN 10
     
    // Structure pour représenter un bouton
    struct Button {
      int x, y;
      bool state;
    };
     
    Button buttons[9]; // 9 boutons
     
    // Coordonnées de l'écran tactile : (x, y) et pression (z)
    int x, y, z;
     
    // Imprimer les informations de l'écran tactile concernant X, Y et la pression (Z) sur le moniteur série
    void printTouchToSerial(int touchX, int touchY, int touchZ) {
      Serial.print("X = ");
      Serial.print(touchX);
      Serial.print(" | Y = ");
      Serial.print(touchY);
      Serial.print(" | Pressure = ");
      Serial.print(touchZ);
      Serial.println();
    }
     
    /******************************************************/
    /*
    uint8_t broadcastAddress[][6] = {
    	{0xb4, 0xe6, 0x2d, 0x78, 0x83, 0x54},		// adr mac1
    	{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF},		// adr mac2
    	{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF},   // adr mac3
      {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF},   // adr mac4
      {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF},   // adr mac5
      {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF},   // adr mac6
      {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF},   // adr mac7
    	{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF},		// adr mac8
      {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF},		// adr mac9
     
    };
    */
     
    // *** Structure Fichier Config.txt ********************************
    const size_t tailleMaxNom = 16;     // y compris le caractère nul final
    struct ClientPC {
      char nom[tailleMaxNom];           // le nom du client PC
      uint8_t adresse[6];               // les 6 octets de son adresse
    };
     
    const size_t nbMaxClients = 20;     // nombre maximum de clients
    ClientPC clients[nbMaxClients]; 
    size_t nbClientsPC = 0;            // le nombre de clients lu dans le fichier de config
     
    //******************************************************************* 
     
    // ***** Structure du récepteur *************************************
    typedef struct struct_message {
      char a[32]; // ex PC1 
      bool b;     // Etat = 0 ou 1
    } struct_message;
    // Créer une struct_message appelée myData
    struct_message myData;
    esp_now_peer_info_t peerInfo;
    void OnDataSent(const uint8_t *mac_addr, esp_now_send_status_t status) {
      Serial.print("\r\nÉtat de l'envoi du dernier paquet:\t");
      Serial.println(status == ESP_NOW_SEND_SUCCESS ? "Succès" : "Échec");
    }
    //*********************************************************************
     
    int touchX, touchY, touchZ , i;
     
     
    //************************************************
    // SETUP
    //************************************************
    void setup()
    {
      Serial.begin(115200);
     
      if(!SPIFFS.begin(true)){
        Serial.println("Une erreur s'est produite lors du montage de SPIFFS");
        return;
      } 
     
      File fichierConfig = SPIFFS.open("/config.txt", FILE_READ);
      if (!fichierConfig) {
        Serial.println("Impossible d'ouvrir le fichier en lecture");
        return;
      }
     
      char bufferLigne[100]; // Buffer pour stocker chaque ligne
      char format[64]; // pour bâtir dynamiquement le format en tenant compte de la longueur max du nom (reco de Kernighan et Pike dans "The Practice of Programming")
      snprintf(format, sizeof format, "%%%ds %%hhx %%hhx %%hhx %%hhx %%hhx %%hhx", tailleMaxNom - 1); // lire une chaine de taille max tailleMaxNom - 1 suivie de 6 octets en hexa
     
      nbClientsPC = 0;
      while (fichierConfig.available() && nbClientsPC < nbMaxClients) {   // tant qu'on peut lire quelque chose et qu'on a de la place pour stocker
        memset(bufferLigne, '\0', sizeof bufferLigne); // Effacer le buffer
        fichierConfig.readBytesUntil('\n', bufferLigne, sizeof bufferLigne); // Lire la ligne dans le buffer
        memset(clients[nbClientsPC].nom, '\0', sizeof clients[nbClientsPC].nom); // on efface le nom pour être tranquille
        int nbChampsLus = sscanf(bufferLigne, format,
                                 clients[nbClientsPC].nom,
                                 &clients[nbClientsPC].adresse[0], &clients[nbClientsPC].adresse[1],
                                 &clients[nbClientsPC].adresse[2], &clients[nbClientsPC].adresse[3],
                                 &clients[nbClientsPC].adresse[4], &clients[nbClientsPC].adresse[5]);
     
        if (nbChampsLus == 7) {
          // la lecture des 7 champs (le nom et 8 octets sous forme hexadécimale) s'est bien passée
          nbClientsPC++;
        } else {
          // on arrête de lire là
          break;
        }
      }
      fichierConfig.close();
     
     
       // Affichage des adresses lues depuis le fichier
      for (size_t i = 0; i < nbClientsPC; i++) {
        Serial.printf("%3zu %-*s : ", i+1, tailleMaxNom - 1, clients[i].nom); // l'index sur 3 caractères, le nom sur tailleMaxNom - 1 cadrée à gauche
        for (int j = 0; j < 6; j++) Serial.printf("0x%02X ", clients[i].adresse[j]);
        Serial.println();
      }
     
      // Set device as a Wi-Fi Station
      WiFi.mode(WIFI_STA);
      // Init ESP-NOW
      if (esp_now_init() != ESP_OK) {
        Serial.println("Erreur d'initialisation de l'ESP-NOW");
        return;
      }
      // Une fois que ESPNow est Init avec succès, nous nous inscrirons pour l'envoi du CB .
      // obtenir l'état du paquet transmis.
      esp_now_register_send_cb(OnDataSent);
      // Enregistrer un pair
      //memcpy(peerInfo.peer_addr, broadcastAddress, 1);
      memcpy(peerInfo.peer_addr, clients , 6);
      peerInfo.channel = 0;  
      peerInfo.encrypt = false;
      // Ajouter un pair        
      if (esp_now_add_peer(&peerInfo) != ESP_OK){
        Serial.println("Échec de l'ajout d'un pair");
        return;
      }
      // Start the SPI for the touchscreen and init the touchscreen
      touchscreenSPI.begin(XPT2046_CLK, XPT2046_MISO, XPT2046_MOSI, XPT2046_CS);
      touchscreen.begin(touchscreenSPI);
      // Set the Touchscreen rotation in landscape mode
      // Note: in some displays, the touchscreen might be upside down, so you might need to set the rotation to 3: touchscreen.setRotation(3);
      touchscreen.setRotation(3);
     
      // Start the tft display
      tft.init();
      // Set the TFT display rotation in landscape mode
      tft.setRotation(1);
     
      // Clear the screen before writing to it
      tft.fillScreen(TFT_BLACK);
     
      // Initialisation des positions des boutons
      int buttonX = 20;
      int buttonY = 20;
      for (int i = 0; i < 9; ++i) 
      {
        buttons[i].x = buttonX;
        buttons[i].y = buttonY;
        buttons[i].state = false;
     
        // Affichage des boutons
        drawButton(buttonX, buttonY, buttons[i].state);
     
        buttonX += BUTTON_WIDTH + BUTTON_MARGIN;
        if (buttonX + BUTTON_WIDTH > tft.width()) {
          buttonX = 20;
          buttonY += BUTTON_HEIGHT + BUTTON_MARGIN;
        }
      }
     
    }
     
    //************************************************
    // LOOP
    //************************************************
    void loop()
    {
     
      // Checks if Touchscreen was touched, and prints X, Y and Pressure (Z) info on the TFT display and Serial Monitor
      if (touchscreen.tirqTouched() && touchscreen.touched()) 
      {
        // Get Touchscreen points
        TS_Point p = touchscreen.getPoint();
        // Calibrate Touchscreen points with map function to the correct width and height
        touchX = map(p.x, 200, 3700, 1, SCREEN_WIDTH);
        touchY = map(p.y, 240, 3800, 1, SCREEN_HEIGHT);
        touchZ = p.z;
     
        //printTouchToSerial(touchX, touchY, touchZ);
     
         for (int i = 0; i < 9; ++i)
         {
            if (touchX >= buttons[i].x && touchX <= buttons[i].x + BUTTON_WIDTH &&
                touchY >= buttons[i].y && touchY <= buttons[i].y + BUTTON_HEIGHT) 
            {
              // Si un bouton est touché, inverse son état et met à jour l'affichage
              buttons[i].state = !buttons[i].state;
              drawButton(buttons[i].x, buttons[i].y, buttons[i].state);
              if (buttons[i].state == 1){
                Serial.print("Btn "); Serial.print(i+1); Serial.println(" enfoncé");
                snprintf(myData.a, sizeof myData.a, "PC%02d=> ON", i+1);
                myData.b =  true;
                esp_err_t result = esp_now_send(clients[i].adresse[0]&clients[i].adresse[1]&clients[i].adresse[2]&clients[i].adresse[3]&clients[i].adresse[4]&clients[i].adresse[5], (uint8_t *) &myData, sizeof(myData)); //<=======================
                if (result == ESP_OK) {
                    Serial.print("PC");Serial.print(i+1); Serial.println(" Envoyé avec succès");
                }else {
                    Serial.print("Erreur d'envoi des données PC");Serial.print(i+1);
                } 
              } 
              if (buttons[i].state == 0)
              {
                Serial.print("Btn "); Serial.print(i+1); Serial.println(" relaché");
                snprintf(myData.a, sizeof myData.a, "PC%02d=> OFF", i+1);
                myData.b =  false;
                esp_err_t result = esp_now_send(clients[i].adresse[0]&clients[i].adresse[1]&clients[i].adresse[2]&clients[i].adresse[3]&clients[i].adresse[4]&clients[i].adresse[5], (uint8_t *) &myData, sizeof(myData));  // <=======================
                if (result == ESP_OK) {
                    Serial.print("PC");Serial.print(i+1); Serial.println(" Envoyé avec succès");
                }else {
                    Serial.print("Erreur d'envoi des données PC");Serial.print(i+1);
                } 
              } 
            }  
        //break;
        delay(200);
        }     
      }
    }
     
    // Dessine un bouton à une position donnée avec un état donné
    void drawButton(int x, int y, bool state) {
      uint16_t color = state ? TFT_RED : TFT_GREEN;
      tft.fillRect(x, y, BUTTON_WIDTH, BUTTON_HEIGHT, color);
      tft.drawRect(x, y, BUTTON_WIDTH, BUTTON_HEIGHT, TFT_WHITE);
     
    }

  16. #16
    Expert confirmé

    Homme Profil pro
    mad scientist :)
    Inscrit en
    Septembre 2019
    Messages
    2 908
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : mad scientist :)

    Informations forums :
    Inscription : Septembre 2019
    Messages : 2 908
    Par défaut
    Citation Envoyé par cobra38 Voir le message
    1) le fichier "fichierConfig" est dimensionné nul part semble-t--il et pourtant il ne plante pas le compilateur , dans mon exemple précédent, j'avais un fichier nommé 'file' et çà bloquait le compilateur par :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    error: 'file' was not declared in this scope
    pourquoi ?
    le compilateur n'a pas besoin de connaître la taille du fichier, juste qu'il faut une variable qui va permettre d'accéder au fichier. Dans votre code précédent, je pense qu'il y avait des erreurs dans la compilation avant ce message sur file, il faut toujours traiter les premières erreurs en premier car souvent le compilateur ensuite est "perdu" et les erreurs peuvent ne pas être pertinentes.

    Citation Envoyé par cobra38 Voir le message
    2) vous considérez la bonne réception du fichier à la 7ieme ligne
    pourquoi pas dès la seconde par ex ?
    je suppose que vous faites référence à
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
        if (nbChampsLus == 7) {
    ce n'est pas le nombre de lignes, mais le nombre d'éléments décodés dans une ligne car on attend 7 valeurs - le nom et les 6 octets. si la fonction sscanf() n'a pas réussi à lires ces 7 champs ça veut dire que la ligne ne contenait pas quelque chose de compatible et j'arrête donc là la lecture.

    Citation Envoyé par cobra38 Voir le message
    3)J'ai eu des difficultés sur Arduino IDE 2.3.2 car je me suis aperçu ( un peu tardivement) que ne n'avait pas la possibilité d'uploader des fichiers SPIFFS à partir du menu
    alors que je l'ai bien avec la version Arduino 1.8.19 ?
    C'est maintenant dispo pour l'IDE 2.x en littlefs cf https://github.com/earlephilhower/ar...ases/tag/1.1.6

    Citation Envoyé par cobra38 Voir le message
    4)( voir image) J'ai fait une modification dans le fichier config.txt à la 5ieme ligne pour voir si le prog prenait les changements et visiblement çà fonctionne par contre
    j'ai une erreur 112 dont je ne connais pas la signification
    Je ne sais pas ce qu'est cette erreur. il semble que ce soit lié à la flash, peut-être un secteur qui n'est pas bon...

    -----

    Pour l'autre question
    j'ai remplacé le tableau broadcastAddress[][] par clients[].adresse[] mais sans succès...
    pour copier les 6 bits d'adresse du client à l'index i dans peerInfo.peer_addr il faut faire
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    memcpy(peerInfo.peer_addr, clients[i].adresse , 6);

  17. #17
    Expert confirmé

    Homme Profil pro
    mad scientist :)
    Inscrit en
    Septembre 2019
    Messages
    2 908
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : mad scientist :)

    Informations forums :
    Inscription : Septembre 2019
    Messages : 2 908
    Par défaut
    Je reviens vers vous dans l’après midi pour vos questions - suis en déplacement

  18. #18
    Membre éprouvé
    Inscrit en
    Juillet 2004
    Messages
    966
    Détails du profil
    Informations forums :
    Inscription : Juillet 2004
    Messages : 966
    Par défaut
    pour progresser
    j'ai "essayé" de procéder à quelques modifications

    j'ai rajouté une variable :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    char broadcastAddress[18];
    ensuite j'ai modifié le croquis comme suit :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
    if (buttons[i].state == 1){
                Serial.print("Btn "); Serial.print(i+1); Serial.println(" enfoncé");
                snprintf(myData.a, sizeof myData.a, "PC%02d=> ON", i+1);
                myData.b =  true;
                snprintf(broadcastAddress, sizeof(broadcastAddress), "%02x:%02x:%02x:%02x:%02x:%02x",
                         clients[i].adresse[0],clients[i].adresse[1],clients[i].adresse[2],clients[i].adresse[3],clients[i].adresse[4],clients[i].adresse[5]);
                Serial.print("Packet envoyé à: "); Serial.println(broadcastAddress);         
                esp_err_t result = esp_now_send( broadcastAddress,(uint8_t *)&myData, sizeof(myData));  // <========= Erreur ici 
                if (result == ESP_OK) {
                    Serial.print("PC");Serial.print(i+1); Serial.println(" Envoyé avec succès");
                }else {
                    Serial.print("Erreur d'envoi des données PC");Serial.print(i+1);
                }
    pour mémoire le fichierConfig est :
    Adresse1 0xb4 0xe6 0x2d 0x78 0x83 0x54
    Adresse2 0xb5 0xe6 0x2d 0x78 0x83 0x54
    Adresse3 0xb6 0xe6 0x2d 0x78 0x83 0x54
    Adresse4 0xb7 0xe6 0x2d 0x78 0x83 0x54
    Adresse5 0xb8 0xe6 0x2d 0x78 0x83 0x54
    Adresse6 0xb9 0xe6 0x2d 0x78 0x83 0x54
    Adresse7 0xba 0xe6 0x2d 0x78 0x83 0x54
    Adresse8 0xbb 0xe6 0x2d 0x78 0x83 0x54
    Adresse9 0xbc 0xe6 0x2d 0x78 0x83 0x54

    Je me heurte toujours à la même erreur

    invalid conversion from 'char*' to 'uint8_t' {aka 'unsigned char'} [-fpermissive]
    Si je définie :
    => char broadcastAddress[18]; => j'arrive à lire la ligne : snprintf(broadcastAddress,.....)
    mais je ne peux pas envoyer les données
    => uint8_t broadcastAddress[18] => je ne peux plus lire la ligne snprintf(broadcastAddress,.....)

  19. #19
    Membre éprouvé
    Inscrit en
    Juillet 2004
    Messages
    966
    Détails du profil
    Informations forums :
    Inscription : Juillet 2004
    Messages : 966
    Par défaut
    merci mille fois Jay M

    mais je patauge sérieux
    j'ai toujours la même erreur à la compilation

    invalid conversion from 'uint8_t*' {aka 'unsigned char*'} to 'size_t' {aka 'unsigned int'} [-fpermissive]
    J'ai modifié comme suit la ligne pour prendre en compte les x adresses MAC fonction du nb de Clients éxistants:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
     for (size_t i = 0; i < nbClientsPC; i++) {
       memcpy(peerInfo.peer_addr, clients[i].adresse , 6);
      }
    ensuite dans la partie "envoi" après chaque appui du bouton, j'ai mis ceci pour tenir compte des 6 adresses MAC:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
     esp_err_t result = esp_now_send(&clients[i].adresse[0],&clients[i].adresse[1],&clients[i].adresse[2],&clients[i].adresse[3],&clients[i].adresse[4],&clients[i].adresse[5],(uint8_t *)&myData, sizeof(myData));
    mais j'ai toujours le même problème à la compilation
    mais par contre si je mets ceci
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    esp_err_t result = esp_now_send( clients[i].adresse,(uint8_t *)&myData, sizeof(myData));
    Le croquis se compile mais :
    Btn 1 enfoncé
    15:47:26.474 -> Erreur d'envoi des données PC1

  20. #20
    Expert confirmé

    Homme Profil pro
    mad scientist :)
    Inscrit en
    Septembre 2019
    Messages
    2 908
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : mad scientist :)

    Informations forums :
    Inscription : Septembre 2019
    Messages : 2 908
    Par défaut
    la fonction
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    esp_now_send( broadcastAddress,(uint8_t *)&myData, sizeof(myData));  // <========= Erreur ici
    attend un pointeur sur un tableau de 6 octets comme premier paramètre, pas une chaîne de texte

    pourquoi voulez vous construire cela avec un snprintf() ?

    la tableau clients contient tout ce qu'il faut déjà

    si vous voulez envoyer à l'adresse du client i il faut donner le tableau des 6 octets comme premier paramètre.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    esp_now_send(clients[i].adresse, (uint8_t *)&myData, sizeof myData);

Discussions similaires

  1. Mesh Network via BLE
    Par matthieuboubou dans le forum Projets
    Réponses: 0
    Dernier message: 21/04/2015, 14h10
  2. [WD18] Bluetooth 4.0 et BLE
    Par ihih45 dans le forum WinDev
    Réponses: 4
    Dernier message: 21/04/2015, 13h40
  3. Reconnaissance des grains de blés coupés
    Par arken dans le forum Traitement d'images
    Réponses: 5
    Dernier message: 08/04/2011, 11h04
  4. Comment sauvegarder bles sources des procedures stockées?
    Par tonton67 dans le forum Développement
    Réponses: 2
    Dernier message: 24/02/2009, 08h53
  5. cas des grains de blé
    Par Maxence45 dans le forum Excel
    Réponses: 13
    Dernier message: 07/11/2007, 19h46

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo