Exporter des données d'une sd card dans une autre CLASS

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.

les données de la SD se présentent ainsi

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,

chris

Voila mon code actuel avec le fichier config.txt dans la zip

SD_TEST_CLASS_NEW.zip (4,7 Ko)

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 ??

Bonjour

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() {}

merci impec

je viens de la chargé, j ai : Erreur de format dans le fichier. Arrêt du traitement

le fichier de config est en actuellement en format "UNIX LF"

ne faut il pas le passer en format windows CR + LF ?

a mois que cela soit

1 = 1 au lieu de SW_1 = 1
2 = 3

etc

il suffit d'un '\n' (LF) en fin de ligne donc les 2 formats sont OK. le CR avant ne change rien.

le format c'est SW N° = VALEUR

Il n'y a pas de _ on écrit SW1 et pas SW_1
Les N° de 1 à 64
Les valeurs vont de 1 à 4

avec sscanf on peut sauter les espaces, donc on peut écrire SW1 ou SW 1 ou SW 1 ça ne doit rien changer

sinon un # introduit un commentaire, ça peut être sur une ligne seule ou après la définition d'un switch


pouvez vous poster votre fichier de config utilisé ? (en balise de code)

voici celui d'exemple mis dans la simulation wokwi

# -----------------------------
# FICHIER DE CONFIGURATION
# -----------------------------

# --------- GROUPE 01  --------- 
SW1 = 3
SW2 = 1
SW3 = 2 # un commentaire 
SW4 = 4

# --------- GROUPE 02  --------- 
SW5 = 3
SW6 = 1
SW7 = 4
SW8 = 2
SW9 = 1

# --------- GROUPE 03  --------- 

     SW 10          =       3
SW11 = 4
SW12 = 2
SW13 = 3
SW14 = 1
SW15 = 4
SW16 = 2
SW17 = 3
SW18 = 1
SW19 = 4


SW20 = 2
SW21 = 3
SW22 = 1
SW23 = 4
SW24 = 2
SW25 = 3
SW26 = 1
SW27 = 4
SW28 = 2
SW29 = 3
SW30 = 1
SW31 = 4
SW32 = 2
SW33 = 3
SW34 = 1
SW35 = 4
SW36 = 2
SW37 = 3
SW38 = 1
SW39 = 4
SW40 = 2

ca marche impec, juste un GRAND MERCI

j avais ceci en config.txt que j'ai remplacé par votre fichier

# CONFIGURATION
SW_1 = 3
SW_2 = 1
SW_3 = 2
SW_4 = 4
SW_5 = 3
SW_6 = 1
SW_7 = 4
SW_8 = 2
SW_9 = 1
SW_10 = 3
SW_11 = 4
SW_12 = 2
SW_13 = 3
SW_14 = 1
SW_15 = 4
SW_16 = 2
SW_17 = 3
SW_18 = 1
SW_19 = 4
SW_20 = 2
SW_21 = 3
SW_22 = 1
SW_23 = 4
SW_24 = 2
SW_25 = 3
SW_26 = 1
SW_27 = 4
SW_28 = 2
SW_29 = 3
SW_30 = 1
SW_31 = 4
SW_32 = 2
SW_33 = 3

si vous voulez conserver le underscore, il suffit de changer le format du sscanf en

    if (sscanf(buffer, " SW_ %d = %d", &idSwitch, &valeurCommande) == 2) {

à vous de voir

à 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)

ah non, je vais être obéissant et pas compliquer la vie du code..

le 'SW' peu clairement disparaitre, ce qui au final me simplifiera la vie car seul le numéro de 1 à 64 est important

le SW rend les trucs lisibles

si votre fichier de config était

SW1 = 3
SW2 = 1
SW3 = 2 # un commentaire 
SW4 = 4

ou

SW4 = 4
SW2 = 1
SW1 = 3
SW3 = 2 # un commentaire 

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];

vous n'auriez plus qu'un tableau de switch

const byte nombreMaxSwitches = 64;
uint8_t etatDesSwitches[nombreMaxSwitches];

et pour aller chercher l'état ou la commande du switch 7 (en partant de 0) vous regardez etatDesSwitches[7]

ça permettrait de traiter le code avec des fonctions sur les tableaux plus simplement.

un switch non déclaré dans le fichier de config pourrait avoir la valeur à 255 pour dire "non utilisé" toujours avec le même enum un peu modifié

enum : uint8_t {AUCUNE_COMMANDE = 0, COMMANDE1 = 1, COMMANDE2 = 2, COMMANDE3 = 3, NON_UTILISE = 255};

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.

0 à 63 :+1:

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)

voici ce que j'ai en tête

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() {}

config.txt

# -----------------------------
# FICHIER DE CONFIGURATION
# -----------------------------

# --------- GROUPE 01  --------- 
SW1 = 3
SW2 = 1
SW3 = 2 # un commentaire 
SW4 = 4

# --------- GROUPE 02  --------- 

     SW 10          =       3
SW11 = 4
SW12 = 2
SW13 = 3
SW14 = 1
SW15 = 4
SW16 = 2
SW17 = 3
SW18 = 1
SW19 = 4

# --------- GROUPE 03  --------- 
SW5 = 3
SW6 = 1
SW7 = 4
SW8 = 2
SW9 = 1

# --------- GROUPE 04  --------- 

SW20 = 2
SW21 = 3
SW22 = 1
SW23 = 4
SW24 = 2
SW25 = 3
SW26 = 1
SW27 = 4
SW28 = 2
SW29 = 3
SW30 = 1
SW31 = 4
SW32 = 2
SW33 = 3
SW34 = 1
SW35 = 4
SW36 = 2
SW37 = 3
SW38 = 1
SW39 = 4
SW40 = 2

Excellent.. un grand merci je teste demain et je fais un feedback

:+1::+1::+1:

chris

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.