Onverwachte negatieve waarden van abs () functie inline met analogRead

Bij het samplen van A0 met een 0-5V signaal op een Arduino micro met de onderstaande code krijg ik wat negatieve waarden.

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

Waarden:

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

Bij het uitvoeren van de (schijnbaar) wiskundige equivalente code hieronder krijg ik uitsluitend positieve waarden.

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

Ik denk niet dat dit een overloop van gehele getallen is zoals in dit bericht omdat wanneer ik overschak naar long sensor = 0 krijg ik dezelfde negatieve resultaten.

Wat is hier aan de hand?

Antwoord

abs() is gedefinieerd in Arduino.h als een macro:

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

Een macro evalueert niet op dezelfde manier als een functie.

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

Deze verklaring wordt tijdens het compileren uitgebreid tot:

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

Nu de “fout” is gemakkelijk te begrijpen. De analoge pin wordt twee keer gelezen. De “fout” kan worden vermeden door de volgende regel als eerste in uw sketch toe te voegen:

#undef abs 

Hiermee wordt de macro abs() en de standaard bibliotheekfunctie worden in plaats daarvan gebruikt.

Proost!

Reacties

  • De fout is de abs() macro in Arduino.h
  • Bedankt voor het duidelijke antwoord. Ik had geen idee dat macros zelfs in de Arduino-wereld bestonden. Ik vond een post uit 2011 waarin dit werd besproken en een korte lijst met andere macros. Kent u een definitieve lijst? Is het gewoon meer " Arduinoesque " en is het beter om meerdere toewijzingen in een regel te vermijden en je aan één bewerking per regel te houden?
  • Nee, het is niet meer Arduinoesque om slechts één bewerking in één toewijzing te gebruiken. Soms wordt dit gedaan om het lezen te vergemakkelijken. Uw probleem met macros hoeft niet veel te doen met Arduino. Het gaat meer in het algemeen over hoe macros worden geëvalueerd door de compiler. De compiler vervangt de macro door wat erin is geschreven ' s definitie (en voert het argument in). Het is geen functie. En dit is niet Arduino-specifiek, maar hangt af van de compiler. U kunt ook macros gebruiken bij het programmeren met andere compilers. Macros kunnen handig zijn, maar u moet ze voorzichtig gebruiken.
  • @chrisl, er is al een abs en labs functie. De arduino abs macro is een belachelijke blunder van arduino. Aaron Ciuffo, klik op de link naar Arduino.h in het antwoord van Mikael Patel, daar zie je de andere macros. Een ander ding is om geen variabele te gebruiken met de naam " B1 ".

Geef een reactie

Het e-mailadres wordt niet gepubliceerd. Vereiste velden zijn gemarkeerd met *