Est-ce qu'un struct peut etre utilisé dans un .ino

Bonjour,

Pour être plus précis concernant mon titre,
J'ai créé une libraire avec donc un fichier .h et .cpp.

Dans mon fichier .h j'ai ceci

 struct Config_radio {
    char nwkskey[100];
    char appskey[100];
    char devaddr[11];
  };

Puis, dans la partie public (extrait)

class Foxuino{
   public:
     Config_radio config_radio;
}

Puis dans mon fichier .cpp, je travaille avec ceci est des valerus sont données à

config_radio.nwksley
config_radio.appskey
config_radio.devaddr

Dans mon fichier .ino, au debut de setup(), j'ai une ligne:

Foxuino Si(mprint,logger);

Donc je peux facilement utiliser des fonctions que j'ai écris dans ma librairie, comme

Si.sprintln("coucou");

A la fin de mon setup, j'ai besoin des clé nwskey, appskey et devaddr, et à ce stade, elles ont des valeurs.

Donc je pensesais simplement faire ceci

Serial.println(Si.config_radio.nwkskey);
Serial.println(Si.config_radio.appskey);
Serial.println(Si.config_radio.devaddr);

Ben voilà, j'ai ce message d'erreur, lors de la compilation:

error: 'nwkskey' was not declared in this scope

Donc si ca marche pour une fonction, est-ce que ca ne marcherai pas pour un struct????

Si non, comment pourrais-je récupérer une valeur sauvée dans un struct de ma librairie, pour l'exploiter dans mon fichier .ino??

Merci pour vos lumières!!

Une bonne fois pour toute : arduino n'existe pas, ce qui existe c'est du C donc les lois du C/C** s'appliquent.

Ce qui se passe c'est que ta structure n'est pas visible de n'importe quel endroit du programme.
C'est exactement comme un int ou un float.

Voici un exemple qui devrait vous permettre de structurer correctement votre code:

création d’une classe maClasse


fichier maClasse.h

#ifndef MACLASSE_H
#define MACLASSE_H
#include <Arduino.h>
#define _MACLASSE_max_etiquette 20

struct maStructure
{
  int valeur;
  char etiquette[_MACLASSE_max_etiquette];
};

class maClasse
{
  public:
    maStructure contenuPublic;
    maClasse();
    maClasse(int v1, const char* e1, int v2, const char* e2);

    int valeurPrivee() const {
      return contenuPrive.valeur;
    }
    const char* etiquettePrivee() const {
      return contenuPrive.etiquette;
    }
  private:
    maStructure contenuPrive;
};
#endif

fichier maClasse.cpp

#include "maClasse.h"

maClasse::maClasse()
{
  contenuPublic.valeur = 10;
  contenuPrive.valeur = 100;
  strcpy(contenuPublic.etiquette, "public");
  strcpy(contenuPrive.etiquette, "prive");
}


maClasse::maClasse(int v1, const char* e1, int v2, const char* e2)
{
  contenuPublic.valeur = v1;
  contenuPrive.valeur = v2;
  strncpy(contenuPublic.etiquette, e1, _MACLASSE_max_etiquette);
  contenuPublic.etiquette[_MACLASSE_max_etiquette - 1] = '\0'; // au cas ou trop long

  strncpy(contenuPrive.etiquette, e2, _MACLASSE_max_etiquette);
  contenuPrive.etiquette[_MACLASSE_max_etiquette - 1] = '\0'; // au cas ou trop long
}

Enfin un sketch (.ino) test.ino


fichier test.ino

#include "maClasse.h"

maClasse c1;
maClasse c2(32, "c2 public", 64, "c2 prive");

void setup() {
  Serial.begin(115200);
  Serial.println(F("\n--- C1 ---"));
  Serial.println(c1.contenuPublic.valeur);
  Serial.println(c1.valeurPrivee());
  Serial.println(c1.contenuPublic.etiquette);
  Serial.println(c1.etiquettePrivee());

  Serial.println(F("\n--- C2 ---"));
  Serial.println(c2.contenuPublic.valeur);
  Serial.println(c2.valeurPrivee());
  Serial.println(c2.contenuPublic.etiquette);
  Serial.println(c2.etiquettePrivee());

  c1.contenuPublic.valeur = 20;
  strcpy(c1.contenuPublic.etiquette, "etiquette c1");
  Serial.println(F("\n--- C1 MODIF ---"));
  Serial.println(c1.contenuPublic.valeur);
  Serial.println(c1.valeurPrivee());
  Serial.println(c1.contenuPublic.etiquette);
  Serial.println(c1.etiquettePrivee());
}

void loop() {}

si vous faites tourner le programme, vous devriez voir dans la console série (à 115200 bauds)

[color=purple]
--- C1 ---
10
100
public
prive

--- C2 ---
32
64
c2 public
c2 prive

--- C1 MODIF ---
20
100
etiquette c1
prive
[/color]

Le code devrait se lire assez simplement. Donc on accède bien directement aux éléments d’une structure publique, indirectement (par une méthode) à ceux d’une structure privée et tout fonctionne normalement

Si ce que vous avez fait ne ressemble pas à cela et que vous avez un soucis, faut poster tout votre code (ou faire un exemple).

D'accord, mais alors comment exploiter cette valeur proprement dans mon fichier.ino
Dois-je créer une fonction pour cela?

char nwkskey[16];

Si.getNwskey(nwkskey);

Foxuino:getNwkskey(const char * nwkey){
nwsley=config_radio.nwkskey;
}

Si oui, et si tu as le temps de lire d'avantage ce post, j'aurais un autre problème de conversion. Et si vous pouvez encore m'éclairecir, ca serait vraiment top.

La valeur de nwkskey est stokée soit dans une mémoire non volatile (EEPROM) ou dans un fichier au format JSON. (l'utilisateur entre cette valeur dans le fichier JSON et le programme le sauve dans l'EEPROM puis l'efface du fichier. Etant donné que je n'ai pas encore l'EEPROM, je lis que le fichier)

Ma librairire LMIC, requiere cette valeur aisni et c'est que je souhaite remplacer:

// Je defini la valeur de ma clé (Network session key)
static const PROGMEM u1_t NWKSKEY[16] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };

Puis plus bas

uint8_t nwkskey[sizeof(NWKSKEY)];
memcpy_P(nwkskey, NWKSKEY, sizeof(NWKSKEY));

et je pensais faire ceci

uint8_t nwkskey[sizeof(NWKSKEY)];
memcpy_P(nwkskey, Si.config_radio.nwkskey, sizeof(Si.config_radio.nwkskey));

Je suis conscient qu'il doit avoir une incoherence dans le type et la taille de la variable.

Ce que j'aimerais résoudre maintenant:

  1. C'est comment récuperer la valeur de ma struct (config_radio.nwkskey) dans mon fichier.ino
  2. Et même si je aurais du d'abord penser à ceci :slight_smile: , comment adapter correctement ma struct pour que j'ai pas de problème a donner la valeur de config_radio.nwkskey à nwkskey

Par exemple si

uint8_t nwkskey[sizeof(NWKSKEY)];

est un uint8_t, ma struct ne devrait pas etre de type char, mais des uint8_t

struct Config_radio {
    uint8_t nwkskey[16];
    uint8_t appskey[16];
    uint32_t devaddr;
  };

Le problème est que si je fais ceci (dans fichier.h

struct Config_radio {
    uint8_t test[16];
  };

et qu'ensuite, je fais ceci (dans fichier.cpp):

config_radio.test = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };

il me géere ce message:

error: assigning to an array from an initializer list

Je suis conscient que pour cette partie je nage, d'autant plus que l'exemple d'atribution de la vaaleur est un
static const PROGMEM u1_t

static const PROGMEM u1_t NWKSKEY[16] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };

Concernant l'u1_t, le forum the TTN m'informe que u1_t est l'équivalence de uint8_t

Si jusqu'à présent j'a fais l'exercie avec des char, c'est parce que je n'arrivais pas solutionner cet problème, et je voulais déjà pouvoir le faire avec des char.

Donc vraiment, si vous pourviez me donner un coup de pousse pour le deuxième problème et le premier qui est le sujet principale de post, ca serait super cool.

Milles mercis pour vos lumières et désoloé de partir dans tous les sens :slight_smile: :slight_smile: :slight_smile: !!!

Merci J-M-L,
J'avais pas lu ton post avant de mettre ma dernière réponse. Je vais le lire

sinon dans le code que vous avez posté ci dessus c'est quoi le type u1_t dansstatic const PROGMEM u1_t NWKSKEY[16] = { ... }; (--> vaut mieux utiliser uint8_t qui est standard)

Merci JML,

c'est quoi le type u1_t

Ben je ne le savais pas non-plus, mais le forum TTN m'indique que c'est du uint8_t

Est-ce que j'ai bien compris? je ne sais pas...

En fait, je vais résumé ma problématique afin de bien adapter mon code avec votre exemple, qui est très intéressant.

Déroulement
Dans my carte SD, j'ai un fichier JSON qui contient les clés de TTN (LoRaWAN). Il se trouve sous ce format

{
    "nwkskey": "{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }",
    "appskey": "{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }",
    "devaddr": "0x00000000"
}

L'utilisateur va l'éditer et le corriger pour mettre ses propres clés.

Le micro-controleur var lire ce fichier et sauver les clés dans l'EEPROM, puis écraser ce fichier avec les valeurs par défaut (0x00,0x00,0x00,etc), de manière à ce que la clé ne reste pas dans le carte SD.

Puis, à la fin de steup() on passe la valeur à

Config_radio.nwkskey

(pour le moment, il est public, mais je le passe plus tard en privé)

L'exécution de se code se passe dans mon fichier.cpp et dans la fonction sd_init_configFile()

Initialement, la valeur de nwkskey est définie dans mon fichier.ino, de la sorte

static const PROGMEM u1_t NWKSKEY[16] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };

puis cette valeur est exploitée dans (fichier.ino)

uint8_t nwkskey[sizeof(NWKSKEY)];
memcpy_P(nwkskey, NWKSKEY, sizeof(NWKSKEY));

(Il y a deux autres clé comme appskey et devaddr)

Sauf erreur, il faudrait donc je passe ma valeur "venant" de mon fichier.cpp ici
(un truc du genre qui sera corrigé selon votre exemple)

uint8_t nwkskey[sizeof(Si.config_radio.nwkskey)];
memcpy_P(nwkskey, Si.config_radio.nwkskey, sizeof(Si.config_radio.nwkskey));

Workaround
Donc, si je reprends vos derniers messages.

Dans mon fichier.h je crée un struct (elle doit être privée, enfin je pense que c'est mieux)

struct Config_radio {
   uint8_t test[16];
    uint8_t nwkskey[16];
    uint8_t appskey[16];
    uint32_t devaddr;
  };

(J'ai rajouté test temporairement)

Puis dans mon fichier.h, j'ajoute ceci à ma class
(J'ai pour habitude de mettre des _ pour les éléments privés)

class Foxuino{

        public:
           Foxuino(bool debug, bool logger);

        protected:
 

 private:
           Config_radio _config_radio;
}

(Est-ce que j'ai vraiment besoin d'une étiquette?)

Je n'ai pas bien compris pourquoi vous utilisez deux constructeurs.

maClasse(int v1, const char* e1, int v2, const char* e2);

C'est très intéressant de faire ainsi,mais dans mon cas, en ai-je besoin, si fichier.cpp lit la valeur de la carte SD ou de l'EEPROM et n'attend plus cette valeur de fichier.ino?

Ensuite, si je replonge dans votre exemple, je pourrais encore écrire ceci

class Foxuino{

        public:
           Foxuino(bool debug, bool logger);

           uint8_t valeurPriveeNwkskey() const {
              return _config_radio.nwkskey;
          };
          uint8_t valeurPriveeAppskey() const {
              return _config_radio.appskey;
          }
           uint32_t valeurPriveeDevaddr() const {
              return _config_radio.devaddr;
          }


        protected:
 

 private:
           Config_radio _config_radio;
}

Si maintenant dans mon fichier.cpp, je définis les valeurs de nwkskey, appskey et devaddr,
(je ne peux pas le faire dans le constructeur, j'ai une fonction sd_init_configFile() qui va initier les fichiers de configuration. Ces valeurs viennent aussi dans la carte SD ou de l'EEPROM

_config_radio.nwkskey = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }
_config_radio.devaddr = 0x00000000;

Là, je sais qu'il y a déjà un problème, que je n'ai pas encore résolu

error: assigning to an array from an initializer list

Admettons que ce problème n'existe pas :slight_smile: , je pourrais récupérer cette valeur dans mon fichier.ino ainsi

Serial.prinln(Si.valeurPriveeNwkskey)

soit

uint8_t nwkskey[sizeof(Si.valeurPriveeNwkskey)];
memcpy_P(nwkskey, Si.valeurPriveeNwkskey, sizeof(Si.valeurPriveeNwkskey));


uint8_t appskey[sizeof(Si.valeurPriveeAppskey)];
memcpy_P(appskey, Si.valeurPriveeAppskey, sizeof(Si.valeurPriveeAppskey));

LMIC_setSession (0x1, Si.valeurPriveeDevaddr, nwkskey, appskey);

Si.sprintln("Voilà c'est fait",2); // Ceci fonctionne très bien. Cette fonctionne affiche dans le terminal et log dans la carte SD

Est-ce que mon interprétation a un bon sens?
Ai-je été plus explicite?
Avez-vous eu la patience de tout lire :slight_smile: :slight_smile:

Miles mercis pour votre support et bon dimanche:)

vous avez bcp de questions d'un coup :slight_smile:

le constructeur avec des paramètres c'était pour vous monter comment on peut instancier avec des valeurs initiales qui ne sont pas celles par défaut quand vous devez dupliquer une chaîne de caractère. Vous pouvez bien sûr le virer si vous n'en avez pas besoin. Idem pour l'étiquette, c'était pour l'exemple.

ma question de base serait: pourquoi avez vous besoin d'une classe Foxuino? vous ne semblez pas avoir de fonctions sur cette classe et vous voulez accéder directement aux éléments --> donc une structure de base suffirait

Vous auriez trois exemplaires de cette structure

Dans le setup() vous regardez si la carte SD contient un fichier de param, si oui vous lisez le fichier JSON sur SD, vous vous servez du contenu pour initialiser les 3 structures, vous écrivez les 3 structures en EEPROM/SPIFFS et vous effacez le fichier de la carte SD.

ce ne serait pas plus simple ainsi ?

Notez aussi que si vous voulez allouer du contenu octet par octet avec un memcpy() dans une structure et vous assurer que le compilateur a organisé la structure comme vous l'avez déclarée et sans trous, il faut déclarer la structure en struct [color=green]__attribute__ ((packed))[/color]

Bonjour J-M-L

vous avez bcp de questions d'un coup

Oui en effet :slight_smile: ca m'embarrasse un peu et j'aurais du commencer par le dernier message.

le constructeur avec des paramètres c'était pour vous monter comment on peut instancier avec des valeurs initiales qui ne sont pas celles par défaut quand vous devez dupliquer une chaîne de caractère. Vous pouvez bien sûr le virer si vous n'en avez pas besoin. Idem pour l'étiquette, c'était pour l'exemple.

D'accord.

ma question de base serait: pourquoi avez vous besoin d'une classe Foxuino?

En fait je n'ai mis que ce qui traite mon problème, mais ma classe et bien plus grande que cela

Ma classe sans les corrections liés à cette discussion

class Foxuino{
 protected:
 

 private:
 //#ifdef LOGGER
 SdFat _sd;
 //#endif
 bool _print;
 bool _logger;
 //bool _oled;
 bool _isSdReady;
 int _carddetect;
 int _chipselect;
 char _sd_pathLog[SD_PATHSIZE];
 char _sd_pathConfig[SD_PATHSIZE];
 char _logFile[SD_PATHSIZE+FILESIZE]; 

 const char * _config_file = "/config.txt";
 const char * _config_radio_file = "/config_radio.txt";
 const char * _config_wifi_file = "/config_wifi.txt";
 const char * _config_sensors_file = "/config_sensors.txt";
 const char * _config_irrigation_file = "/config_irrigation.txt";

 bool _sd_init();
 
 void _sd_showCwd();
 bool _sd_checkCard();
 void _listFiles(const char * folder);
 bool _sd_writeln(char * fileName, char const * text);
 bool _sd_write(const char * fileName, char const * text);
 bool _sd_write(char * fileName, const __FlashStringHelper * text);
 bool _sd_writeln(char * fileName, const __FlashStringHelper * text);
 bool _sd_write(const char * fileName, const __FlashStringHelper * text, bool ln);
 bool _sd_write(const char * fileName, char const * text, bool ln);
 int _save_Config(const char * filename);
 int _save_Config(const char * filename, bool init);
 int _save_Config_radio(const char * filename);
 int _save_Config_radio(const char * filename, bool init);
 int _save_Config_wifi(const char * filename);
 int _save_Config_wifi(const char * filename, bool init);
 int _save_Config_irrigation(const char * filename);
 int _save_Config_irrigation(const char * filename, bool init);
 int _save_Config_sensors(const char * filename);
 int _save_Config_sensors(const char * filename, bool init);
 
 int _load_Config(const char * filename);
 int _load_Config_radio(const char * filename);
 int _load_Config_wifi(const char * filename);
 int _load_Config_irrigation(const char * filename);
 int _load_Config_sensors(const char * filename);

 Eeprom _eeprom;
 int _eeprom_index_block;
 void _writeEEPROM(int deviceaddress, unsigned int eeaddress, char * data);
 void _readEEPROM(int deviceaddress, unsigned int eeaddress, unsigned char * data, unsigned int num_chars);
 

 public:
 //Foxuino();
 Foxuino(bool debug, bool logger);
 bool begin();
 Config config;
 Config_radio config_radio;
 Config_wifi config_wifi;
 Config_sensors config_sensors;
 Config_irrigation config_irrigation;

 int sd_init_logFile(int16_t y, int16_t m, int16_t d, int16_t h, int16_t mn, int16_t s);
 int sd_init_configFile();
 bool sd_writeln(char const * text);
 bool sd_write(char const * text);
 bool sd_write(int16_t text);

 void sprint(int message, int base, int logToSd);
 void sprint(int message, int logToSd);
 void sprint(uint32_t message, int logToSd);
 void sprint(int32_t message, int logToSd);
 void sprint(int16_t message, int logToSd);
 void sprint(uint16_t message, int logToSd);
 void sprint(uint8_t message, int logToSd);
 
 //void sprint(long message, int logToSd);
 
 void sprint(int8_t message, int logToSd);
 void sprint(const __FlashStringHelper * message, int logToSd);
 void sprint(char const * message, int logToSd);
 void sprintln(double message, int logToSd);
 //void sprint(float message, int logToSd);
 //void sprintln(float message, int logToSd);
 void sprint(double message, int logToSd);
 void sprintln(int message, int base, int logToSd);
 void sprintln(int message, int logToSd);
 void sprintln(uint32_t message, int logToSd);
 void sprintln(int32_t message, int logToSd);
 void sprintln(int16_t message, int logToSd);
 void sprintln(uint16_t message, int logToSd);
 void sprintln(uint8_t message, int logToSd);
 
 //void sprintln(long message, int logToSd);

 void sprintln(char * message, int logToSd);
 void sprintln(const __FlashStringHelper * message, int logToSd);
 void sprintln(char const * message, int logToSd);
 void printFloat(float value, int places);
 void convertFloatToChar(float source, char * destination, int nbDec, int destinationSize);
 void lcdTx(int char_position, char * text, int clear_line); 

 void ledOn(byte lPin);
 void ledOff(byte lPin);
 void ledBlink(byte lPin, int nBlink, int msec);

 };

Les fonctions

int _load_Config_radio(const char * filename);
int _save_Config_radio(const char * filename);
int _save_Config_radio(const char * filename, bool init);

sont (entre autres) les fonctions qui vont lire et écrire, au format JSON, dans mon fichier JSON.

Quand par exemple, load_Config_radio() lit le contenu de /config_radio.txt (ou .json), la valeur de de nwkskey est sauvé dans config_radio.nwkskey (plus tard dans _config_radio.nwkskey, puis que je la passerai e privé).

..et _config_radio.nwkskey, sera utilisé dans mon fichier.iono, selon vos suggestions précédentes

uint8_t valeurPriveeNwkskey() const {
              return _config_radio.nwkskey;
          };

Le but de ma class, ou de ma libraire est de pouvoir l'utiliser dans des applications différentes :slight_smile:

Ce qui me préoccupe maintenant, c'est résoudre ceci

_config_radio.nwkskey = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }
_config_radio.devaddr = 0x00000000;

sans avoir le message d'erreur

error: assigning to an array from an initializer list

Ca me semble plus cohérent de solutionner ceci avant de tester et adapter mon code avec vous précédentes propositions, si mon résonnement et compréhension vont dans le bon sens :slight_smile: :slight_smile: :slight_smile:

J'aimerais juste encore préciser, il me semble important que l'utilisateur puisse modifier ces clé sours ce format, dans la clé SD

{
    "nwkskey": "{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }",
    "appskey": "{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }",
    "devaddr": "0x00000000"
}

soit cette chaine de caractere

{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }

c'est ainsi qu'on la récupère depuis la console TTN. Ca doit etre assez compliqué pour un agriculteur d'interpreter un fichier JSON, donc s'il peut se contanter de faire un copier/coller de cette chaine

{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }

ca serait tip top :slight_smile: :slight_smile: :slight_smile:

Merciii

Pour résoude mon premier problème, j’essaye ceci

struct Config_radio {
  	char c_nwkskey[100];
    uint8_t nwkskey[16];
    char c_appskey[100];
    uint8_t appskey[16];
    char c_devaddr[11];
    uint32_t devaddr;
  };


private:
 Config_radio _config_radio;

Je lis mon fichiser json et j’affiche le resultat

sprint(F("\tnwkskey: "),2);
sprintln(_config_radio.c_nwkskey,2);

Juqu’a là, ca fonctionne bien

Maintenant, je cherche à convertir cette string en uint8_t
Donc je sépare les crochets, espaces et virgules et je met dans buf, les valeurs qui m’intéresse.
Je bug à la conversion

sprint(F("\tnwkskey: "),2);
          sprintln(_config_radio.c_nwkskey,2);

          Serial.print(F("strlen:"));
          Serial.println(strlen(_config_radio.c_nwkskey));
          Serial.print(F("Sizeof:"));
          Serial.println(sizeof(_config_radio.c_nwkskey));

          char buf[3];
          int y = 0;
          
          for(int i=0; i< strlen(_config_radio.c_nwkskey); i++){
            if(_config_radio.c_nwkskey[i] != '{' && _config_radio.c_nwkskey[i] != '}' && _config_radio.c_nwkskey[i] != ' ' && _config_radio.c_nwkskey[i] != ',')
            {
              buf[y]=_config_radio.c_nwkskey[i];
              y++;
              buf[y]='\0';
            }
            else
            {

              // Il faudra ici encore convertir les {}, espace en uint8_t. Le but etant de retpruve ceci
              // l'équivalencd de
              // static const PROGMEM u1_t NWKSKEY[16] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
              // au final dans _conf_radio.nwkskey


              if(strlen(buf)>0)
              {
                // Ici je m'occupe que des 0x00, et je les affiche
                Serial.print(F("buf:"));
                Serial.println(buf); //ca marche

                // Mais parcontre ici ca bug
                // Il faudrait que _config_radio.nwkskey[0] prenne la valeru du premier 0x00
                // et ainsi de suite. J'ai toujours des problèmes de conversion :) 
                uint8_t * ptr = _config_radio.c_nwkskey;
                for(int u =0; u < 3; u++)
                {
                  itoa(buf, (char *) ptr, 3); //Ca bug là!!
                  ptr += strlen((char *) ptr);
                }
                *ptr = 0; // Close
                
                Serial.print(F("ui:"));
                Serial.println((char*)_config_radio.nwkskey);
              }

              y=0;
              memset(buf,'\0',sizeof(buf));
            }
          }

Est-ce qu’il n’y a pas plus simple?

sprint(F("\tnwkskey: "),2);
sprintln(_config_radio.c_nwkskey,2);

c'est quoi sprint() ou sprintln() ? ça veut dire quoi le ,2 ?

alors sprint() ou sprintln() c'est une fonction à moi que j'ai mis dans ma class

sprint("toto",0) // J'affiche dans le terminal = Serial.print()
sprint("toto",1) // je log le texte dans mon fichier event.log, par exemple
sprint("toto",2) // je fais les deux

idem pour sprintln() qui équivaut à Serial.println() :slight_smile:

J'utilise que des Serial.print() dans ces fonctions

Dans le cas ci-dessus, j'utilise en effet des

Serial.print(F("strlen:"));

mais je les supprimerai. C'est tempo mais idem à sprint((F("strlen"),0)

OK

est-ce que ce petit bout de code vous aide?

char nwkskey[] = "0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0xA0, 0xB0, 0xC0, 0xD0, 0xE0, 0xF0, 0xFF";

void analyserKey(const char * key)
{
  char * ptr;
  char buffer[100];
  const char* separateur = ",";

  strncpy(buffer, key, 100); // on le duplique pour ne pas toucher à key
  buffer[99] = '\0';
  long valeur;

  ptr = strtok(buffer, separateur); // http://www.cplusplus.com/reference/cstring/strtok/
  while (ptr) {
    valeur = strtol(ptr, NULL, 16); // http://www.cplusplus.com/reference/cstdlib/strtol/
    Serial.print(F("0x")); Serial.println(valeur, HEX);
    ptr = strtok(NULL, separateur);
  }
}

void setup() {
  Serial.begin(115200);
  analyserKey(nwkskey);
}

void loop() {}

Merci J-M-L
Oui ca va m'aider, bien sûre.

Je suppose que valeur (long valeur) et dans mon cas

_config_radio.nwkskey

PS: Attention j'ai changé mes type

struct Config_radio {
  	char c_nwkskey[100];
    uint8_t nwkskey[16];
    char c_appskey[100];
    uint8_t appskey[16];
    char c_devaddr[11];
    uint32_t devaddr;
  };

Est-ce que ca fonctionne aussi si
long valeur devient unit8_t valeur

ou alors

 while (ptr) {
    _config_radio.nwkskey = strtol(ptr, NULL, 16); // http://www.cplusplus.com/reference/cstdlib/strtol/
    Serial.print(F("0x")); Serial.println(_config_radio.nwkskey, HEX);
    ptr = strtok(NULL, separateur);
  }

Pour rappel,

_config_radio.nwkskey = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };

doit avoir le même contenu que

static const PROGMEM u1_t NWKSKEY[16] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };

(Peut-être sans le static ou PROGMEM)

En tout cas, merci pour tes suggestions
(Je vais m'arreter un moment, j'ai la tête qui explose :slight_smile: )

la fonction strtol() retourne un long (int32_t donc sur un UNO). Si vous aviez à lire 0x12345678 elle saurait le faire et bien sûr ça ne rentrerait pas dans votre tableau.

Mais si vous savez que vous ne lisez que des données sur 8 bits 0xZZ, alors pas de soucis, ça va rentrer dans votre tableau de uint8_t. Par acquis de conscience vous pourriez tester si valeur lue est plus grande que 255 avant de la mettre dans le tableau (elle sera tronquée de toutes façons) auquel cas ça voudrait dire que le fichier est buggy.

je ne comprends pas trop le business de

static const PROGMEM u1_t NWKSKEY[16] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };

.. en gros vous mettez plein de zero en mémoire flash et vous ne pourrez pas les modifier... ça sert à quoi?

… en gros vous mettez plein de zero en mémoire flash et vous ne pourrez pas les modifier… ça sert à quoi?

Non ne fait ca c’est pour ne pas afficher ma clé :slight_smile:
Mais c’est s faut que ca. Dans ma carte SD j’enregistre bien que des 0x00.
Si la valeeur est changée, le microcontrolleur met à jour l’EEPROM et remets les valeurs à 0x00 sur la carte SD.
Ainsi les clés ne peuvent pas être prise si on vol le module…

Je vais essayé la proposition

Ben en fait, il n'aime pas trop le strol

struct Config_radio {
  	char c_nwkskey[100];
    uint8_t nwkskey[16];
    char c_appskey[100];
    uint8_t appskey[16];
    char c_devaddr[11];
    uint32_t devaddr;
sprint(F("\tnwkskey: "),2);
          sprintln(_config_radio.c_nwkskey,2); // Affiche: { 0x00, 0x00, 0x00, ..., 0x00 }

          Serial.print(F("strlen:"));
          Serial.println(strlen(_config_radio.c_nwkskey));
          Serial.print(F("Sizeof:"));
          Serial.println(sizeof(_config_radio.c_nwkskey));

          char * ptr;
          char buffer[100];
          const char* separateur = ",";
          strncpy(buffer, _config_radio.c_nwkskey, 100); // copie et  préserv
          buffer[99] = '\0';
          
          ptr = strtok(buffer, separateur); // http://www.cplusplus.com/reference/cstring/strtok/
          while (ptr) {
            _config_radio.nwkskey = strtol(ptr, NULL, 16); // http://www.cplusplus.com/reference/cstdlib/strtol/
            Serial.print(F("0x")); 
            Serial.println((char*)_config_radio.nwkskey);
            ptr = strtok(NULL, separateur);
          }

          Serial.println(F("Resutat final:"));
          Serial.println((char*)_config_radio.nwkskey);
// Devraos afficher: : { 0x00, 0x00, 0x00, ..., 0x00 }

En fait au niveau du strtol, il m'indique un problème de type :o

error: incompatible types in assignment of 'long int' to 'uint8_t [16] {aka unsigned char [16]}'

J'ai aussi essyé avec aio

J'ai aussi remplacé
Serial.println(_config_radio.nwkskey,HEX);
par
Serial.println((char*)_config_radio.nwkskey);

car mon compiler n'aimait pas ceci aussi.

Au passage je suis sur un SAMD21 (= Arduino Zero)

euh nwkskey c’est un tableau de 16 octets, donc il faut des indices - il faut faire un truc du genre

int i = 0;
 while (ptr && i < 16) {
    _config_radio.nwkskey[i++] = (uint8_t) strtol(ptr, NULL, 16); // http://www.cplusplus.com/reference/cstdlib/strtol/
    Serial.print(F("0x")); Serial.println(_config_radio.nwkskey, HEX);
    ptr = strtok(NULL, separateur);
  }

mais ça range chaque valeur sous forme d’un nombre dans les octets du tableau. c’est pas une chaîne de caractères donc Serial.println((char*)_config_radio.nwkskey); ne va pas afficher

{ 0x00, 0x00, 0x00, ..., 0x00 }

pour cela il faut reparcourir le tableau et imprimer bout par bout

Serial.print(F("{ "))
for(int i=0; i<16; i++) {
  Serial.print(F("0x"));
  Serial.print(_config_radio.nwkskey[i], HEX);
  if (i != 15) Serial.print(F(", ")); // pas de virgule à la fin
}
Serial.print(F(" }"));

J’ai retrouvé un code que j’avais utilisé et avec ca, j’arrive a avoir quelque chose, … mais plante comme-même (rire)

uint8_t * ptr = _config_radio.nwkskey;
for (int i=0; i < strlen(_config_radio.c_nwkskey); i++){
  *ptr = _config_radio.c_nwkskey[i];
   ptr += strlen((char *) ptr);
}
*ptr = 0; // Close

          Serial.println((char*)ptr);
          
          Serial.println((char*)_config_radio.nwkskey);

ce qui m’affiche ceci. mais le programme plante

wkskey: { 0xD4, 0xDA, 0x87, 0xD8, 0xCF, 0x00, 0x00, 0x00, 0x77, 0x9C, 0x85, 0x52, 0x4B, 0xEA, 0x94, 0x76 }
strlen:98
Sizeof:100

{ 0xD4, 0xDA, 0x{ 0x4B, 0xB4, 0x74, 0xFE, 0x8B, 0x01, 0x68, 0x11, 0x2F, 0x64, 0x07, 0xA6, 0xE3, 0x87, 0xD9, 0x38 }87, 0xD8, 0xCF, 0x0x260112DA00, 0x⸮q0⸮q0⸮q,⸮q ⸮q0x00, 0x77, 0x9C, 0x85, 0x52, 0x4B, 0xEA, 0x94, 0x76 }

Est-ce que l’approche est intéressante? Il doit avoir un dans la boucle …