Bonsoir à tous et toute,
j'ai un petit projet ou j'ai un programme python qui envoi des données à mon arduino via la voie série. mon soucis réside dans l'extraction des données reçue par la voie série.
si je rentre cette donnée -------> AA 9.5 AB 8.5 AC 3.5 avec mon code ci-dessous le résultat en retour es un y
Hors j'aimerai récupérer les valeurs 9.5 8.5 3.5 afin que ces données me commande des servomoteurs. dans mon exemple il y a que pour 3 Servo mais ca peu être plus. Je comprends pas.
Je ne comprends pas mon erreur ou mes erreurs. Si mon data je lui met la donnée "AA 9.5 AB 8.5 AC 3.5" et que je ne passe pas par la fonction Serial. available alors pas de soucis je retrouve bien mes 3 valeurs.
Quelqu'un peut m'aider ou m'aiguiller?
Merci d'avance
En C/C++ les chaines de caractère doivent se terminer par un \0. Il faut donc ajouter ce 0 à la fin (et agrandir le buffer)
Il vaut mieux aussi agrandir les buffer de réception au cas ou les espaces seraient inclus (ce n'est peut être pas nécessaire)
char data[21];
char AA[6];
char AB[6];
char AC[6];
void setup()
{
Serial.begin(9600);
}
void loop()
{
if(Serial.available()>=20){
for(char i=0; i<20; i = i +1)
{
data[i] = Serial.read();
}
data[20]=0; // fin de chaine
sscanf(data, "AA %s AB %s AC %s" , AA,AB,AC);
Serial.println(atof(AA));
Serial.println(atof(AB));
Serial.println(atof(AC));
}
}
Remarque: tu pourrais utiliser %f pour récupérer les flottants.
Merci beaucoup kamill. Pourquoi met t'on le tableau à 0 la fin de chaine?
J'ai pas compris "tu pourrais utiliser %f pour récupérer les flottants." quels va etre la différence avec les caractères? Peut etre la commande futur des servo moteurs?
Je viens de tester cela fonctionne bien par contre si ma valeur AA à changer et passe de 9.5 a 8.1 et que je la saisie dans le moniteur série et bien en faite la nouvelle valeur 8.1 n'est pas prise en compte et on me réaffiche dans le moniteur 9.5. Logiquement avec la boucle a chaque tour si cela change le résultat doit changer aussi non?
Il n'y a pas de raison que ça réaffiche la valeur précédente.
Par contre ton programme n'est pas très robuste. S'il reste des caractères dans le buffer (par exemple si le moniteur envoie cr lf) ils ne seront pas éliminés et ça va dysfonctionner.
oui c'est beaucoup de découverte pour moi je n'ai jusqu'a présent jamais traiter les chaine de caractère j'y vais a tâtons malheureusement
Par contre c'est toujours la meme chaine que j'envoie juste les valeur qui change.
Je fais mes manipulation sous tinker CAD pas de soucis tout fonctionne mais dès le passage en réelle sur l'IDE et arduino Uno et bien mon premier envoie AA 3.5 AB 5.5 AC 3.5 me renvoie bien 3.50 5.50 3.50 si je renvoie maintenant AA 1.5 AB 5.5 AC 3.5 le résultat renvoie 3.50 5.50 3.50 c'est bizarre et si je vide comme tu la fait avec data la j'obtien 0.00 0.00 3.50
Non il sert à marquer la fin de la chaine.
Si la chaine n'est pas terminée par 0, les fonctions ne savent pas ou il faut s'arrêter de traiter la chaine et on risque de gros disfonctionnements.
Personnellement je n'aime pas beaucoup l'utilisation de sscanf, il y a parfois des effets bizarres (surtout si la chaine n'est pas strictement conforme à ce qu'on attend).
J'utilise souvent strstr ou strtok
Avec strstr ça donne
char data[21];
void setup()
{
Serial.begin(9600);
}
void loop()
{
if(Serial.available()){
int n=Serial.readBytes(data,sizeof data-1);
data[n]=0;
Serial.println(data);
// traite le message reçu de forme AA 9.5 AB 8.5 AC 3.5
float a,b,c;
char *p;
p=strstr(data,"AA");
if (p!=NULL)
{
p+=2;
a=atof(p);
p=strstr(p,"AB");
if (p!=NULL)
{
p+=2;
b=atof(p);
p=strstr(p,"AC");
if (p!=NULL)
c=atof(p+2);
Serial.println(a);
Serial.println(b);
Serial.println(c);
}
}
}
}
effectivement cela fonctionne sans soucis sur l'iDE arduino avec cette façon
je vais décortiquer ton code afin de comprendre le cheminement et les 2 expressions strstr strtok
hello kamill j'ai compris le strstr va chercher la premiere occurence en AA AB ou AC dans l'ordre ou l'on avance depuis le premier caractère c'est bien cela et le p va cherche les 2 chaines qui suive