Merci bien
Je vais essayer de digérer tout çà et je reviens vers vous avec un nouveau croquis
pascal
Merci bien
Je vais essayer de digérer tout çà et je reviens vers vous avec un nouveau croquis
pascal
Bonsoir
Voilà mon croquis modifié à partir de vos conseils:
le logiciel a l'air de "tomber en marche"
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 // 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> 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 PC01 //uint8_t broadcastAddress1[] = {0xb4, 0xe6, 0x2d, 0x78, 0x83, 0x54}; 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 }; // ************** 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); // 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, 6); memcpy(peerInfo.peer_addr, broadcastAddress, 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(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); }![]()
l'appui sur le Btn2 engendre une erreur car pour l'instant je n'ai qu'1 seul ESP01s et donc 1 seule adresse en test
votre avis ?
pascal
Je ne m'y connais pas trop, mais les adresses pour mac2 à mac9 sont toutes {0xff, 0xff, 0xff, 0xff, 0xff, 0xff} ??? Je doute que soit une adresse mac valide. Alors, fatalement, quand tu appuies sur le bouton pour activer mac2, esp_now_send() n'est pas content.
Mais je ne pense pas que le programme "tombe en marche". esp_now_send() a bien fonctionné (pas comme tu l'aurais souhaité, mais ça c'est autre chose), et le programme continue à attendre un appui sur un boutton.
Comme tu n'as qu'un seul esp branché, initialise les adresses de mac2 à mac9 avec celle de mac1. Edit: si tu testes comme cela, active et désactive une mac address avant d'en tester une autre, sinon ça pourrait être le souk.
merci edgarjacobs
je voulais juste faire un essai avec la 1ere adresse , il est vrai que j'aurai pu copier les autres
par contre,
je souhaiterai savoir comment je peux mettre ces adresses de façon auto
Je m'explique :
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
pascal
Ç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.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
merci edgarjacobs
Je crois que je vais revenir à des choses plus "modestes"
si par ex , je mets dans un fichier "data/config.txt" ceci :
comment l'intégrer dans la structure actuelle
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5 #Adresse1; 0xb4, 0xe6, 0x2d, 0x78, 0x83, 0x54; #Adresse2; 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF; .... #Adresse9;0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF;
çà semble plus facile de modifier un fichier .txt que de recompiler à chaque modification d'adresse
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13 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 };
pascal
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
J'ai tenté de faire çà à partir d'un fichier "config.txt"
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 // 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};
mais le compilateur ne veut pas :
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 };
en outre dans la déclaration de SPIFFS.h et FS.h
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2 Compilation error: 'adresse1' was not declared in this scope
le compilateur cherche :
mais au final
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();
Faut-il téléverser préalablement le fichier "config.txt" pour vérifier le croquis ?
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2 error: 'file' was not declared in this scope
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)
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); }
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)
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
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
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
5
6 const byte tailleMaxNom = 16; // y compris le caractère null final struct ClientPC { char nom[tailleMaxNom]; byte adresse[6]; };
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).
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
Pour lire le fichier de configuration, le plus simple c'est de lire une ligne dans un buffer mémoire, ça se fait avec
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.
Code : Sélectionner tout - Visualiser dans une fenêtre à part fichierConfig.readBytesUntil('\n', ...
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
(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)
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
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
vous copiez cela dans un sketch que vous sauvez
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() {}
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.
Bonjour Jay M
c'est noté , j'avais pris pourtant un tuto mais j'ai du oublier quelque chosequand 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.
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 :
pourquoi ?
Code : Sélectionner tout - Visualiser dans une fenêtre à part error: 'file' was not declared in this scope
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
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
maintenant j'ai çà :
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 }; */
j'ai remplacé le tableau broadcastAddress[][] par clients[].adresse[] mais sans succès...
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 une erreur :
ci-dessous le code actuel
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]
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); }
Je reviens vers vous dans l’après midi pour vos questions - suis en déplacement
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.
je suppose que vous faites référence à
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.
Code : Sélectionner tout - Visualiser dans une fenêtre à part if (nbChampsLus == 7) {
C'est maintenant dispo pour l'IDE 2.x en littlefs cf https://github.com/earlephilhower/ar...ases/tag/1.1.6
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
pour copier les 6 bits d'adresse du client à l'index i dans peerInfo.peer_addr il faut fairej'ai remplacé le tableau broadcastAddress[][] par clients[].adresse[] mais sans succès...
Code : Sélectionner tout - Visualiser dans une fenêtre à part memcpy(peerInfo.peer_addr, clients[i].adresse , 6);
pour progresser
j'ai "essayé" de procéder à quelques modifications
j'ai rajouté une variable :
ensuite j'ai modifié le croquis comme suit :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2 char broadcastAddress[18];
pour mémoire le fichierConfig est :
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); }
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
Si je définie :invalid conversion from 'char*' to 'uint8_t' {aka 'unsigned char'} [-fpermissive]
=> 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,.....)
merci mille fois Jay M
mais je patauge sérieux
j'ai toujours la même erreur à la compilation
J'ai modifié comme suit la ligne pour prendre en compte les x adresses MAC fonction du nb de Clients éxistants:invalid conversion from 'uint8_t*' {aka 'unsigned char*'} to 'size_t' {aka 'unsigned int'} [-fpermissive]
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
3
4 for (size_t i = 0; i < nbClientsPC; i++) { memcpy(peerInfo.peer_addr, clients[i].adresse , 6); }
mais j'ai toujours le même problème à la compilation
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 par contre si je mets ceci
Le croquis se compile mais :
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));
Btn 1 enfoncé
15:47:26.474 -> Erreur d'envoi des données PC1
la fonction
attend un pointeur sur un tableau de 6 octets comme premier paramètre, pas une chaîne de texte
Code : Sélectionner tout - Visualiser dans une fenêtre à part esp_now_send( broadcastAddress,(uint8_t *)&myData, sizeof(myData)); // <========= Erreur ici
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);
Je pensais qu'il fallait préalablement formater la chaine "adresse" avant de l'envoyerpourquoi voulez vous construire cela avec un snprintf() ?
car le formatage avec "0x" intervient à l'impression par :
or la chaîne "adresse" ne doit-elle pas obligatoirement posséder "Ox" devant chaque adresse au moment de l'envoi ?
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2 .... Serial.printf("0x%02X ", clients[i].adresse[j]);
ce serait peut-être la cause de mon problème ?
la doc est dispo:
https://docs.espressif.com/projects/...uint8_t6size_t
Send ESPNOW data.
Code : Sélectionner tout - Visualiser dans une fenêtre à part esp_err_t esp_now_send(const uint8_t *peer_addr, const uint8_t *data, size_t len)
Attention
1. If peer_addr is not NULL, send data to the peer whose MAC address matches peer_addr
Attention
2. If peer_addr is NULL, send data to all of the peers that are added to the peer list
Attention
3. The maximum length of data must be less than ESP_NOW_MAX_DATA_LEN
Attention
4. The buffer pointed to by data argument does not need to be valid after esp_now_send returns
Parameters
peer_addr -- peer MAC address
data -- data to send
len -- length of data
Returns
ESP_OK : succeed
ESP_ERR_ESPNOW_NOT_INIT : ESPNOW is not initialized
ESP_ERR_ESPNOW_ARG : invalid argument
ESP_ERR_ESPNOW_INTERNAL : internal error
ESP_ERR_ESPNOW_NO_MEM : out of memory, when this happens, you can delay a while before sending the next data
ESP_ERR_ESPNOW_NOT_FOUND : peer is not found
ESP_ERR_ESPNOW_IF : current Wi-Fi interface doesn't match that of peer
ESP_ERR_ESPNOW_CHAN: current Wi-Fi channel doesn't match that of peer
Partager