Pages: [1]   Go Down
Author Topic: étourderie  (Read 633 times)
0 Members and 1 Guest are viewing this topic.
Corsica
Offline Offline
Jr. Member
**
Karma: 0
Posts: 82
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Bonjour,
Je butte sur un problème ridicule:
Code:
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?  smiley-slim
Le résultat sur la console me sidère un peu:

Quote
-291;-1;-956
-194;-1;-980
-95;-1;-995
4;0;-999
104;0;-994
202;0;-979
299;0;-954

 smiley-eek
Comprends pas!
 
Logged

France
Offline Offline
God Member
*****
Karma: 4
Posts: 972
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

en écrivant
Code:
  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 Offline
Jr. Member
**
Karma: 0
Posts: 82
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Code:
#define pi 3.1416
#define inc 0.1
float Theta;
Logged

Corsica
Offline Offline
Jr. Member
**
Karma: 0
Posts: 82
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
  long sinus = sin(Theta)*1000.0;
  long cosinus = cos(Theta)*1000.0;
euh... non.

il vaut peut être mieux ne pas utiliser sfprintf?
Code:
  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 Offline
God Member
*****
Karma: 4
Posts: 972
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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  :
Code:
     
      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 Offline
Jr. Member
**
Karma: 0
Posts: 82
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
Si trame[] n'a d'autre utilité que l'affichage
Non, trame me sert ensuite:
Code:
  n = FileLogger::append("data.csv",(byte*) trame,n);
(je récupère ensuite le csv avec un tableur, par exemple...)
Quote
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 smiley-cool
Logged

France
Offline Offline
Faraday Member
**
Karma: 55
Posts: 5347
Arduino Hacker
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Bonjour,

sprintf (et presque 99.9% des fonctions de la libc) est prise en charge par le compilateur/l'ide arduino.

Pour cette ligne :
Code:
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 :
Code:
int n = (trame,"%ld;%ld;%ld",cosinus,sinus,cosinus);
« Last Edit: August 14, 2011, 03:23:13 am by skywodd » Logged

Des news, des tuto et plein de bonne chose sur http://skyduino.wordpress.com !

Corsica
Offline Offline
Jr. Member
**
Karma: 0
Posts: 82
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Bonjour Skywodd,

Quote
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 smiley-eek-blue
Avant d'écrire
Code:
  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 ? smiley-roll
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ù! smiley-mr-green

Merci et bon dimanche.




Logged

Offline Offline
Full Member
***
Karma: 0
Posts: 224
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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 Offline
Jr. Member
**
Karma: 0
Posts: 82
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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 Offline
Full Member
***
Karma: 0
Posts: 224
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Le compilateur lève juste un warning, mais comme l'IDE Arduino compile avec l'option -w tu ne l'as pas vu :
Quote
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 Offline
Jr. Member
**
Karma: 0
Posts: 82
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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

Quote
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 Offline
Full Member
***
Karma: 0
Posts: 224
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
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]...

Quote
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


Pages: [1]   Go Up
Jump to: