Uventede negative værdier fra abs () funktion inline med analogRead

Når der samples fra A0 med et 0-5V signal på en arduino micro med koden nedenfor får jeg nogle negative værdier.

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

Værdier:

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

Når du kører (tilsyneladende) matematisk tilsvarende kode nedenfor får jeg udelukkende positive værdier.

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

Jeg tror ikke, dette er et heltalsoverløb som i dette indlæg fordi når jeg skifter til long sensor = 0 får jeg de samme negative resultater.

Hvad sker der her?

Svar

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

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

En makro evalueres ikke på samme måde som en funktion.

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

Denne erklæring udvides ved kompileringstid til:

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

Nu “fejlen” er let at forstå. Den analoge pin læses to gange. “Fejlen” kan undgås ved at tilføje følgende linje først i din skitse:

#undef abs 

Dette fjerner makroen abs() og standardbiblioteksfunktionen bruges i stedet.

Skål!

Kommentarer

  • Fejlen er abs() makroen i Arduino.h
  • Tak for det klare svar. Jeg havde ingen idé om, at der endda eksisterede makroer i Arduino-verdenen. Jeg fandt et indlæg fra 2011, der diskuterede dette og en kort liste over andre makroer. Kender du til en endelig liste? Er det bare mere " Arduinoesque " og bedre praksis for at undgå flere opgaver på en linje og holde sig til en operation pr. Linje?
  • Nej, det er ikke mere Arduinoesque at kun bruge en operation i en opgave. Nogle gange gøres dette for at gøre det lettere at læse. Dit problem med makroer behøver ikke at gøre meget med Arduino. Det handler mere generelt om, hvordan makroer evalueres af compileren. Compileren erstatter makroen med det, der står i den ' s definition (og sætter i argumentet). Det er ikke en funktion. Og dette er ikke Arduino-specifikt, men afhænger af compileren. Du kan også bruge makroer, når du programmerer med andre compilere. Makroer kan være nyttige, men du skal bruge dem med forsigtighed.
  • @chrisl, der er allerede en abs og labs funktion. Arduino abs makroen er en latterlig bommert af arduino. Aaron Ciuffo, klik på linket til Arduino.h i svaret af Mikael Patel, der ser du de andre makroer. En anden ting er ikke at bruge en variabel med navnet " B1 ".

Skriv et svar

Din e-mailadresse vil ikke blive publiceret. Krævede felter er markeret med *