avez vous besoin que le fichier sur la carte SD soit lisible par un humain ?
Oui le fichier de config doit être lisible et modifiable facilement. Il est volontairement modifiable que sur PC.
le Sw_x peut être modifié pour être mieux exploiter par le code. SW_1 peut devenir simplement 1
Ce fichier de config n'est lu qu'une fois durant le setup, c est entre autre pour cela que il était en RAM (en plus du fait que je ne sais pas faire autrement).
je dois être capable de comparer ces 64 num de SW et l'état associé à ce switch case (qui est dans une autre CLASS)
switch (Switch_case_data) *// le Switch_case_data ici est le sw qui est enfoncé parmi les 64 qui sont sur la matrice externe, cette fonction marche parfaitement bien.*
{
case 1: *// je pensais rajouter avec "&&" la condition de la SD correspond au SW_1*
*// ici exploiter la commande 0, 1 2 ou 3* si la condition "case 1 && xx " est bien respectée.
Serial.println(F(" SWITCH CASE #1 ***" ));
break;
case 2:
Serial.println(F(" SWITCH CASE #2 ***" ));
break;
le tableau n 'a pas besoin d'être enregistré sur la SD,
je ne peux pas le voir depuis mon iPhone simplement
mettez les fichier ici séparés, avec les balises de code, ce sera plus simple
--
si les switch dans le fichier sont rangés dans l'ordre, pourquoi avoir le N° du switch ? sur la ligne 1 on a le switch 1, sur la ligne 2 on a le switch 2 etc.. ➜ pas besoin de cette information supplémentaire, si ??
Je vais mettre le code dans l aprem. Si j ai besoin de savoir quel sw afin de l identifier rapidement si on a besoin de changer la sortie en 0 1 2 ou 3.. apres il y a t il besoin de faire remonter l info du num de sw..
Je dois juste pouvoit mettre en face du switch case la valeur de la sortie 0 1 2 3 pour led 64 lignes du switch case
Tenez je vous ai écrit un exemple de code sans classes
dans le setup() on ouvre le fichier de config qui s'appelle config.txt et on l'analyse en remplissant le tableau dont je parlais précédemment (qui est donc assez économe en place mémoire).
s'il n'y a pas eu d'erreur, vous avez dans ce tableau, rangé par ordre du fichier les N° des switch et leur valeur (on pourrait aussi ranger la valeur directement dans le tableau à l'indice du switch en question, auquel cas on n'aurait pas besoin de la structure, juste un tableau des états. Je ne sais pas ce que vous voulez faire exactement )
J'ai utilisé la bibliothèque sdFat qui est mieux que SD (même auteur mais beaucoup plus à jour que SD et plus performante). Je lis la ligne dans le fichier grace à fgets() et j'analyse son contenu grace à sscanf()
le code
/* ============================================
code is placed under the MIT license
Copyright (c) 2024 J-M-L
For the Arduino Forum : https://forum.arduino.cc/u/j-m-l
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
===============================================
*/
#include <SdFat.h>
#define VITESSE_SPI SD_SCK_MHZ(4)
#define PIN_CS 10
const byte tailleBuffer = 50;
SdFat carteSd;
File fichierConfig;
enum : uint8_t {AUCUNE_COMMANDE = 0, COMMANDE1 = 1, COMMANDE2 = 2, COMMANDE3 = 3};
struct CommandeSwitch {
uint8_t idSwitch : 6; // le numéro du switch de 0 à 63
uint8_t commande : 2; // la commande de 0 à 3
};
const byte nombreMaxSwitches = 64;
CommandeSwitch lesSwitches[nombreMaxSwitches];
byte nombreDeSwitches = 0;
void setup() {
Serial.begin(115200);
if (!carteSd.begin(PIN_CS, VITESSE_SPI)) {
if (carteSd.card()->errorCode()) {
Serial.println("Échec de l'initialisation de la carte SD.");
} else if (carteSd.vol()->fatType() == 0) {
Serial.println("Partition FAT16/FAT32 non valide introuvable.");
} else {
Serial.println("Type d'erreur indéterminé");
}
while (true) yield();
}
fichierConfig = carteSd.open("config.txt", FILE_READ);
if (!fichierConfig) {
Serial.println("Erreur d'ouverture du fichier config.txt.");
while (true) yield();
}
char buffer[tailleBuffer];
int idSwitch;
int valeurCommande;
bool erreur = false;
while (fichierConfig.fgets(buffer, tailleBuffer)) {
char *debut = buffer;
while (isspace(*debut)) debut++; // Ignorer les espaces initiaux
if (*debut == '\0' || *debut == '#') continue; // la ligne était vide ou commentaire
if (sscanf(buffer, " SW %d = %d", &idSwitch, &valeurCommande) == 2) {
if (idSwitch > 0 && idSwitch <= nombreMaxSwitches && valeurCommande >= AUCUNE_COMMANDE + 1 && valeurCommande <= COMMANDE3 + 1) {
if (nombreDeSwitches >= nombreMaxSwitches) {
Serial.println("Trop d'entrées dnas le fichier config. Arrêt du traitement.");
erreur = true;
break;
}
lesSwitches[nombreDeSwitches].idSwitch = idSwitch - 1;
lesSwitches[nombreDeSwitches].commande = valeurCommande - 1;
nombreDeSwitches++;
} else {
Serial.println("Valeur de commande ou numéro de switch invalide. Arrêt du traitement.");
erreur = true;
break;
}
} else {
Serial.println("Erreur de format dans le fichier. Arrêt du traitement.");
erreur = true;
break;
}
}
fichierConfig.close();
if (erreur) {
while (true) yield();
}
for (byte i = 0; i < nombreDeSwitches; i++) {
Serial.print("switch N° "); Serial.print(lesSwitches[i].idSwitch + 1);
Serial.print(" a pour valeur "); Serial.println(lesSwitches[i].commande + 1);
}
}
void loop() {}
à mon avis ce serait plus simple de ranger les switch à leur index dans le tableau et ne plus s'ennuyer à noter le N° (à moins que vous puissiez avoir un sous ensemble des switch dans le fichier de config et pas dans un ordre particulier)
les switch sont rangés dans un ordre différent dans le tableau pour le moment.
Ne pensez vous pas que ce soit plus logique de dire que le premier switch (N° 0) est dans la case 0 du tableau, le switch 1 dans la seconde case etc et que ce soit toujours comme cela ?
au lieu d'avoir
enum : uint8_t {AUCUNE_COMMANDE = 0, COMMANDE1 = 1, COMMANDE2 = 2, COMMANDE3 = 3};
struct CommandeSwitch {
uint8_t idSwitch : 6; // le numéro du switch de 0 à 63
uint8_t commande : 2; // la commande de 0 à 3
};
const byte nombreMaxSwitches = 64;
CommandeSwitch lesSwitches[nombreMaxSwitches];
je suis très conscient de cela et là, je n'ai pas trop le choix , car en fait il existe une matrice extérieure qui est numérotée de SW 1 à SW 64 qui est détectée par l 'arduino.
Devant comparer ce switch enfoncé avec la config de la SD, par expérience, il va y a voir des erreurs si on dit que 0 de la SD correspond à 1 dans l'autre CLASS. que 60 à 61 ...
et malgré cela, il faudrait en toute logique commencer à "0".
après comme le dit votre expérience cela sera plus simple... partons sur 0 à 63... et à moi de faire attention lors du paramétrage de la SD.. qui au final elle sera mise à jour 2/3 fois lors de la mise en route du système et après jamais.
Gérer 1 de décalage entre la numérotation « officielle » et les indices du tableau n’est pas compliqué (vous voyez dans le code du test d’ailleurs que je fais déjà ce décalage)
vous pouvez alors mettre les éléments dans l'ordre que vous voulez dans le fichier de config, ils seront triés comme il faut dans le tableau avec une entrée par switch. La numérotation dans votre fichier de config commence à 1, mais dans le code, le tableau commence à 0.
les détails
/* ============================================
code is placed under the MIT license
Copyright (c) 2024 J-M-L
For the Arduino Forum : https://forum.arduino.cc/u/j-m-l
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
===============================================
*/
#include <SdFat.h>
#define VITESSE_SPI SD_SCK_MHZ(4)
#define PIN_CS 10
const byte tailleBuffer = 50;
SdFat carteSd;
File fichierConfig;
enum : uint8_t {COMMANDE1 = 1, COMMANDE2 = 2, COMMANDE3 = 3, COMMANDE4 = 4, NON_UTILISE = 255};
const byte nombreMaxSwitches = 64;
uint8_t etatDesSwitches[nombreMaxSwitches];
void setup() {
for (byte i = 0; i < nombreMaxSwitches; i++) etatDesSwitches[i] = NON_UTILISE;
Serial.begin(115200);
if (!carteSd.begin(PIN_CS, VITESSE_SPI)) {
if (carteSd.card()->errorCode()) {
Serial.println("Échec de l'initialisation de la carte SD.");
} else if (carteSd.vol()->fatType() == 0) {
Serial.println("Partition FAT16/FAT32 non valide introuvable.");
} else {
Serial.println("Type d'erreur indéterminé");
}
while (true) yield();
}
fichierConfig = carteSd.open("config.txt", FILE_READ);
if (!fichierConfig) {
Serial.println("Erreur d'ouverture du fichier config.txt.");
while (true) yield();
}
char buffer[tailleBuffer];
int idSwitch;
int valeurCommande;
bool erreur = false;
while (fichierConfig.fgets(buffer, tailleBuffer)) {
char *debut = buffer;
while (isspace(*debut)) debut++; // Ignorer les espaces initiaux
if (*debut == '\0' || *debut == '#') continue; // la ligne était vide ou commentaire
if (sscanf(buffer, " SW %d = %d", &idSwitch, &valeurCommande) == 2) {
if (idSwitch > 0 && idSwitch <= nombreMaxSwitches && valeurCommande >= COMMANDE1 && valeurCommande <= COMMANDE4) {
etatDesSwitches[idSwitch - 1] = valeurCommande ;
} else {
Serial.println("Valeur de commande ou numéro de switch invalide. Arrêt du traitement.");
erreur = true;
break;
}
} else {
Serial.println("Erreur de format dans le fichier. Arrêt du traitement.");
erreur = true;
break;
}
}
fichierConfig.close();
if (erreur) {
while (true) yield();
}
for (byte i = 0; i < nombreMaxSwitches; i++) {
Serial.print("switch N° "); Serial.print(i + 1);
switch (etatDesSwitches[i]) {
case COMMANDE1: Serial.println(" => commande #1"); break;
case COMMANDE2: Serial.println(" => commande #2"); break;
case COMMANDE3: Serial.println(" => commande #3"); break;
case COMMANDE4: Serial.println(" => commande #4"); break;
case NON_UTILISE: Serial.println(" => non utilisé"); break;
}
}
}
void loop() {}