Pour un projet je dois récupérer une trame de 3 octets dans le port série séparé par un point virgule ex: "11111111;00000000;11111111" j'ai donc trouvé comment récupérer les octets et le séparer le problème c'est qu'ils sont stockés dans une tableau char et je doit les convertir en décimal(je suis obligé c'est dans l'énoncé) mais je n'ai pas trouvé comment faire.
`const int LONGUEUR_STRING_MAX = 100; // taille maxi de l'objet String`
`const int LONGUEUR_ITEM_MAX = 9; // nbr de caractères maxi de l'item`
`const int NBR_ITEMS_MAX = 3; // nbr d'items maxi`
`char delimiter[] = ";"; // délimiteur`
`char *item[NBR_ITEMS_MAX]; // tableau des éléments découpés`
`char text[LONGUEUR_STRING_MAX];`
`void setup() {`
` Serial.begin(115200);`
` String str = "11111111;01010101;00000000";`
`char text[LONGUEUR_STRING_MAX];`
` str.toCharArray(text, sizeof(text)); // copie dans un tableau de char`
`int nbr_items = 0;`
`char* token = strtok(text, delimiter);`
`while (token != nullptr && nbr_items < NBR_ITEMS_MAX)`
` {`
`item[nbr_items++] = token;`
`token = strtok(nullptr, delimiter);`
`}`
`int a = item[0];`
`Serial.println(a);`
`}`
`void loop() {`
`// code principal, en boucle infinie`
`}`
Par exemple item[0] contient 11111111 et le moniteur série renvoie 2200 mais je voudrais qu'il renvoie 255
par exemple avec item[0] = 00011001 on obtiendrait 25
je pense qu'il faudrait transformer le char en binaire puis le binaire en décimale mais je ne trouve pas comment faire
D’une part atoi() nécessite que la chaîne soit terminée par un caractère nul. Il faut donc qu’il y soit - strtok() va le mettre pour vous au moment de segmenter la chaîne donc ça c’est OK mais vous ne voulez pas lire un entier - par exemple 10000000 ça ne tiendra pas sur 2 octets.
Si vous êtes garanti qu’il y a toujours les 8 bits (par exemple 00000011 et pas juste 11 pour dire 3(dec)) alors il suffit de parcourir le tableau jusqu’au séparateur (le ; et le caractère nul de fin de chaîne) ou juste avec une boucle for de 7 à 0 et regarder si c’est 1 ou 0 (pour s’assurer que c’est une entrée correcte) et d’ajouter au cas où c’est 1 la puissance de 2 correspondant à la position (27 pour le premier caractère, puis 26, 25… jusqu’à 20.
@5_cylindres a raison. c'est avec un caractère que vous devez comparer (le code ASCII du symbole 1), pas le nombre 1. Donc on met des simple apostrophe autour du symbole pour dire que l'on veut sa valeur en tant que caractère ASCII
Super merci ça fonctionne mais... j'ai un dernier problème enfin j'espère j'ai fait ce code pour convertir en décimale la trame
void loop() {
for (int t=0; t < 8; t++)
{
if(item[0][t] == '1') // si c'est un 1
{
dec1 = dec1 + pow(2,e); // je multiplie 2 par l'exposant 7 puis 6 puis 5 ect et je l'ajoute au ancienne valeur pour obtenir au final la valeur décimale
e = e - 1;
}
}
Serial.println(dec1);
}
mais je sait pas pourquoi le calcul que fait l'Arduino est pas bon j'ai dec1 = 0 et e =7 mais il trouve 127 au lieu de 128
char saisie[] = "11111111;01010101;00000000"; // 255;85;0
void setup() {
Serial.begin(115200);
char * separateurPtr = strtok(saisie, ";");
while (separateurPtr != nullptr) {
Serial.print("Valeur détectée en binaire : "); Serial.print(separateurPtr);
byte valeur = 0;
for (int i = 0; i < 8; i++) {
if (separateurPtr[i] == '1') valeur += (1u << (7 - i));
}
Serial.print(" -> En numérique "); Serial.println(valeur);
separateurPtr = strtok(nullptr, ";");
}
}
void loop() {}
si tout va bien vous devriez voir
Valeur détectée en binaire : 11111111 -> En numérique 255
Valeur détectée en binaire : 01010101 -> En numérique 85
Valeur détectée en binaire : 00000000 -> En numérique 0
la puissance de 2 est calculée avec la formule barbare (1u << (7 - i)) qui dit de prendre la valeur 1 (en non signée - d'où le u) et de la décaler en binaire de 7 moins i positions vers la gauche, ce qui correspond à aller chercher la bonne puissance de 2. (on fait 7 - i car le premier caractère c'est 27 quand i vaut 0, ensuite 26 quand i vaut 1, puis 25 quand i vaut 2,... ➜ 7 - i donne la bonne valeur pour la puissance)
C'est bon effectivement ça marche super bien et c'est beaucoup plus concis que mon programme. Sachant que mon programme final est aussi assez balaise, c'est parfait. J'ai réussi à l'adapter et tout fonctionne merci à tous pour votre réactivité et votre aide.
maintenant que vous avez compris comment on fait, on va vous dire qu'il existe la fonction strtoul() qui fait ça pour vous
char saisie[] = "11111111;01010101;00000000"; // 255;85;0
void setup() {
Serial.begin(115200);
char * separateurPtr = strtok(saisie, ";");
while (separateurPtr != nullptr) {
byte valeur = strtoul(separateurPtr, nullptr, 2); // 2 c'est pour dire que la chaîne est en base 2, en binaire
Serial.print("Valeur détectée en binaire : "); Serial.print(separateurPtr);
Serial.print(" -> En numérique "); Serial.println(valeur);
separateurPtr = strtok(nullptr, ";");
}
}
void loop() {}
l'avantage de la fonction c'est que ça fonctionne même si vous n'avez pas des 0 en padding au début et qu'il y a un paramètre additionnel (ici j'ai mis un pointeur nul) qui permet aussi de détecter des erreurs d'analyse - si l'utilisateur a rentré quelque chose qui ne convient pas
J'ai vu passer cette fonction dans mes recherches mais je ne me suis pas arrêté plus que ça dessus et je regrette un peu mais au moins j'ai appris pas mal d'autres choses.