Corsica
Offline
Jr. Member
Karma: 0
Posts: 82
|
 |
« on: August 13, 2011, 04:39:51 am » |
Bonjour, Je butte sur un problème ridicule: void loop(void) { Theta = Theta + inc; if (Theta >= 2*pi) { Theta = -2*pi;} long sinus = sin(Theta)*1000; long cosinus = cos(Theta)*1000; char trame[12]; int n = sprintf (trame,"%d;%d;%d",cosinus,sinus,cosinus); Serial.println(trame); delay(50); } C'est pas compliqué, hein?  Le résultat sur la console me sidère un peu: -291;-1;-956 -194;-1;-980 -95;-1;-995 4;0;-999 104;0;-994 202;0;-979 299;0;-954
 Comprends pas!
|
|
|
|
|
Logged
|
|
|
|
|
France
Offline
God Member
Karma: 2
Posts: 905
|
 |
« Reply #1 on: August 13, 2011, 04:53:35 am » |
en écrivant long sinus = sin(Theta)*1000.0; long cosinus = cos(Theta)*1000.0; peut être. Comment sont déclarées Theta et inc ?
|
|
|
|
|
Logged
|
|
|
|
|
Corsica
Offline
Jr. Member
Karma: 0
Posts: 82
|
 |
« Reply #2 on: August 13, 2011, 04:58:41 am » |
#define pi 3.1416 #define inc 0.1 float Theta;
|
|
|
|
|
Logged
|
|
|
|
|
Corsica
Offline
Jr. Member
Karma: 0
Posts: 82
|
 |
« Reply #3 on: August 13, 2011, 09:12:34 am » |
long sinus = sin(Theta)*1000.0; long cosinus = cos(Theta)*1000.0; euh... non. il vaut peut être mieux ne pas utiliser sfprintf? int n = sprintf (trame,"%d;%d;%d",cosinus,sinus,cosinus); renvoie -291;-1;-956 (par ex.). c'est à dire cosinus, -1 et sinus. Je m'attendais à: -291;-956;-291! c'est un prodige, non?
|
|
|
|
|
Logged
|
|
|
|
|
France
Offline
God Member
Karma: 2
Posts: 905
|
 |
« Reply #4 on: August 13, 2011, 11:10:08 am » |
pas sûr que sprintf() soit pris en charge sous Arduino... et si oui il y a probablement des limites !! Si trame[] n'a d'autre utilité que l'affichage on peut faire de manière plus 'arduinesque', dans le style : double sinus = sin(Theta)*1000; double cosinus = cos(Theta)*1000;
Serial.print(Theta,DEC); Serial.print('\t'); Serial.print(long(sinus),DEC); Serial.print('\t'); Serial.println(long(cosinus),DEC);
|
|
|
|
|
Logged
|
|
|
|
|
Corsica
Offline
Jr. Member
Karma: 0
Posts: 82
|
 |
« Reply #5 on: August 13, 2011, 01:13:17 pm » |
Si trame[] n'a d'autre utilité que l'affichage Non, trame me sert ensuite: n = FileLogger::append("data.csv",(byte*) trame,n); (je récupère ensuite le csv avec un tableur, par exemple...) pas sûr que sprintf() soit pris en charge sous Arduino... et si oui il y a probablement des limites !! y a-t-il un moyen pour savoir: - quelles fonctions sont prises en charge sous Ardino? (Mon Sketch compile!)
- quelles sont les probables limites (faut-il tâtonner?)
merci pour vos lumières 
|
|
|
|
|
Logged
|
|
|
|
|
France
Online
Faraday Member
Karma: 36
Posts: 4336
Arduino Hacker
|
 |
« Reply #6 on: August 13, 2011, 03:51:42 pm » |
Bonjour, sprintf (et presque 99.9% des fonctions de la libc) est prise en charge par le compilateur/l'ide arduino. Pour cette ligne : int n = (trame,"%d;%d;%d",cosinus,sinus,cosinus);
Dans n ce trouve le nombre de caractères de trame (ou 0 si la fonction plante), ok pas de probléme. Mais là ou je pense que cela bug c'est l'utilisation de %d ! Pour un long ça devrait être un %ld !? Tente : int n = (trame,"%ld;%ld;%ld",cosinus,sinus,cosinus);
|
|
|
|
« Last Edit: August 14, 2011, 03:23:13 am by skywodd »
|
Logged
|
|
|
|
|
Corsica
Offline
Jr. Member
Karma: 0
Posts: 82
|
 |
« Reply #7 on: August 14, 2011, 02:03:43 am » |
Bonjour Skywodd, Tente : int n = (trame,"%ld;%ld;%ld",cosinus,sinus,cosinus);
le résultat est encore plus troublant: 19595264;-62521344;19660799 - On ne devrait rien avoir au dessus de 1000
- Les deux valeurs affichées du même "cosinus" sont encore différentes
Avant d'écrire long sinus = sin(Theta)*1000; long cosinus = cos(Theta)*1000; j'avais voulu utiliser des float avec l'option /3f et je n'avais obtenu que des ?  si sprintf est prise en charge par le compilateur, elle ne fonctionne pas ici comme comme à mon habitude, ou bien j'ai fait une grosse bêtise (d'où le titre),et je ne vois pas où!  Merci et bon dimanche.
|
|
|
|
|
Logged
|
|
|
|
|
Offline
Full Member
Karma: 0
Posts: 218
|
 |
« Reply #8 on: August 14, 2011, 03:02:40 am » |
Salut,
La taille du tableau "trame" n'est pas suffisante, dans le pire des cas la chaîne dépasse les 12 caractères. Il faut donc dimensionner correctement le tableau. Ensuite l'utilisation de sprintf ne prenant pas en compte la taille, la mémoire est corrompue. Pour plus de sécurité, il faut privilégier l'utilisation de snprintf.
Enfin comme l'écrit Skywodd, il est préférable d'utiliser des %ld pour formater les valeurs...
++
|
|
|
|
|
Logged
|
|
|
|
|
Corsica
Offline
Jr. Member
Karma: 0
Posts: 82
|
 |
« Reply #9 on: August 14, 2011, 08:29:36 am » |
C'est ma faute,
À force de bidouiller j'avais accumulé les bugs. Vous avez raison, c'est bien Long et %d qui étaient incompatibles. Ce qui m'a surpris, c'est de ne pas m'être fait jeter par le compilateur.
Merci beaucoup,
|
|
|
|
|
Logged
|
|
|
|
|
Offline
Full Member
Karma: 0
Posts: 218
|
 |
« Reply #10 on: August 15, 2011, 02:48:48 am » |
Le compilateur lève juste un warning, mais comme l'IDE Arduino compile avec l'option -w tu ne l'as pas vu : format '%d' expects type 'int', but argument 4 has type 'long int' PS : n'oublie pas d'ajuster la taille de ton tableau...
|
|
|
|
|
Logged
|
|
|
|
|
Corsica
Offline
Jr. Member
Karma: 0
Posts: 82
|
 |
« Reply #11 on: August 15, 2011, 04:56:28 am » |
La taille du tableau "trame" n'est pas suffisante, dans le pire des cas la chaîne dépasse les 12 caractères cos(Theta)*1000 entier ne peut pas faire plus que 5 caractères (-1000) *3 =15 + 2';' = 17 caractères. Dans ce cas, Trame[16] devrait suffire, ou je me trompe? Le compilateur lève juste un warning, mais comme l'IDE Arduino compile avec l'option -w tu ne l'as pas vu : On peut changer cette option, où bien il faut compiler avec gcc?
|
|
|
|
|
Logged
|
|
|
|
|
Offline
Full Member
Karma: 0
Posts: 218
|
 |
« Reply #12 on: August 15, 2011, 01:47:16 pm » |
La taille du tableau "trame" n'est pas suffisante, dans le pire des cas la chaîne dépasse les 12 caractères cos(Theta)*1000 entier ne peut pas faire plus que 5 caractères (-1000) *3 =15 + 2';' = 17 caractères. Dans ce cas, Trame[16] devrait suffire, ou je me trompe? Là tu n'accordes que 16 octets. Hors tu peux avoir au maximum 17 octets + le caractère de fin de chaîne '\0'. Donc il te faut Trame[18]... Le compilateur lève juste un warning, mais comme l'IDE Arduino compile avec l'option -w tu ne l'as pas vu : On peut changer cette option, où bien il faut compiler avec gcc? Je ne sais pas si on peut changer les flags de compilation tout en conservant l'IDE Arduino, en tout cas je n'ai pas trouvé...
|
|
|
|
|
Logged
|
|
|
|
|
|