Valeurs négatives inattendues de la fonction abs () en ligne avec analogRead

Lors de léchantillonnage à partir de A0 avec un signal 0-5V sur un micro arduino avec le code ci-dessous, jen reçois valeurs négatives.

int sensor = 0; sensor = abs(analogRead(A0) - 512); 

Valeurs:

77 25 -74 -58 46 113 -74 102 -91 -51 -126 47 31 

Lors de lexécution (apparemment) mathématique code équivalent ci-dessous, jobtiens des valeurs exclusivement positives.

int sensor = 0; sensor = analogRead(A0); sensor = sensor - 512; sensor = abs(sensor); 

Je ne pense pas que ce soit un débordement dentier comme dans ce message car lorsque je passe à long sensor = 0, jobtiens les mêmes résultats négatifs.

Que se passe-t-il ici?

Réponse

abs() est défini dans Arduino.h en tant que macro:

 #define abs(x) ((x)>0?(x):-(x)) 

Une macro ne sévalue pas de la même manière quune fonction.

 sensor = abs(analogRead(A0) - 512); 

Cette instruction sera étendue lors de la compilation à:

 sensor = ((analogRead(A0) - 512)>0?(analogRead(A0) - 512):-(analogRead(A0) - 512)); 

Maintenant «lerreur» est facile à comprendre. La broche analogique est lue deux fois. L « erreur » peut être évitée en ajoutant dabord la ligne suivante dans votre croquis:

#undef abs 

Cela supprimera la macro abs() et la fonction de bibliothèque standard seront utilisées à la place.

Cheers!

Commentaires

  • Lerreur est la macro abs() dans Arduino.h
  • Merci pour la réponse claire. Je navais aucune idée que les macros existaient même dans le monde Arduino. Jai trouvé un message de 2011 traitant de cela et dune courte liste dautres macros. Connaissez-vous une liste définitive? Est-ce simplement plus d " Arduinoesque " et une meilleure pratique pour éviter les affectations multiples dans une ligne et sen tenir à une opération par ligne?
  • Non, il nest pas plus Arduinoesque de nutiliser quune seule opération dans une affectation. Parfois, cela est fait pour faciliter la lecture. Votre problème avec les macros na pas grand-chose à voir avec Arduino. Il sagit plus généralement de la manière dont les macros sont évaluées par le compilateur. Le compilateur remplace la macro par ce qui y est écrit ' définition (et met largument). Ce nest pas une fonction. Et ce nest pas spécifique à Arduino, mais dépend du compilateur. Vous pouvez également utiliser des macros lors de la programmation avec dautres compilateurs. Les macros peuvent être utiles, mais vous devez les utiliser avec précaution.
  • @chrisl, il existe déjà un abs et labs fonction. La macro arduino abs est une bévue ridicule darduino. Aaron Ciuffo, cliquez sur le lien vers Arduino.h dans la réponse de Mikael Patel, là vous voyez les autres macros. Une autre chose est de ne pas utiliser une variable avec le nom " B1 ".

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *