Uventede negative verdier fra abs () funksjon inline med analogRead

Ved prøvetaking fra A0 med et 0-5V signal på en arduino micro med koden under får jeg noen negative verdier.

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

Verdier:

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

Når du kjører (tilsynelatende) matematisk ekvivalent kode nedenfor får jeg utelukkende positive verdier.

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

Jeg tror ikke dette er et heltalloverløp som i dette innlegget fordi når jeg bytter til long sensor = 0 får jeg de samme negative resultatene.

Hva skjer her?

Svar

abs() er definert i Arduino.h som en makro:

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

En makro evalueres ikke på samme måte som en funksjon.

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

Denne uttalelsen utvides ved kompileringstid til:

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

Nå «feilen» er lett å forstå. Den analoge pinnen leses to ganger. «Feilen» kan unngås ved å legge til følgende linje først i skissen din:

#undef abs 

Dette fjerner makroen abs() og standard biblioteksfunksjon blir brukt i stedet.

Skål!

Kommentarer

  • Feilen er abs() makroen i Arduino.h
  • Takk for det klare svaret. Jeg ante ikke at makroer til og med eksisterte i Arduino-verdenen. Jeg fant et innlegg fra 2011 som diskuterte dette og en kort liste over andre makroer. Kjenner du til en endelig liste? Er det bare mer " Arduinoesque " og bedre praksis for å unngå flere oppgaver i en linje og holde seg til en operasjon per linje?
  • Nei, det er ikke mer arduinoesque å bare bruke en operasjon i en oppgave. Noen ganger gjøres dette for å gjøre det lettere å lese. Problemet ditt med makroer trenger ikke å gjøre mye med Arduino. Det handler mer generelt om hvordan makroer vurderes av kompilatoren. Kompilatoren erstatter makroen med det som står i ' s definisjon (og legger inn argumentet). Det er ikke en funksjon. Og dette er ikke Arduino-spesifikt, men avhenger av kompilatoren. Du kan også bruke makroer når du programmerer med andre kompilatorer. Makroer kan være nyttige, men du må bruke dem med forsiktighet.
  • @chrisl, det er allerede en abs og labs funksjon. Arduino abs makroen er en latterlig bommert av arduino. Aaron Ciuffo, klikk på lenken til Arduino.h i svaret av Mikael Patel, der ser du de andre makroene. En annen ting er å ikke bruke en variabel med navnet " B1 ".

Legg igjen en kommentar

Din e-postadresse vil ikke bli publisert. Obligatoriske felt er merket med *