Nieoczekiwane wartości ujemne z funkcji abs () wbudowanej w analogRead

Podczas próbkowania z A0 z sygnałem 0-5V na arduino micro z kodem poniżej otrzymuję trochę wartości ujemne.

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

Wartości:

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

Podczas wykonywania (najwyraźniej) matematycznego równoważny kod poniżej otrzymuję wyłącznie wartości dodatnie.

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

Nie sądzę, żeby to było przepełnienie liczb całkowitych, jak w tym poście , ponieważ kiedy przełączam się na long sensor = 0, otrzymuję takie same negatywne wyniki.

Co się tutaj dzieje?

Odpowiedź

abs() jest zdefiniowana w Arduino.h jako makro:

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

Makro nie jest obliczane w ten sam sposób, jak funkcja.

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

Ta instrukcja zostanie rozwinięta w czasie kompilacji do:

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

Teraz „błąd” jest łatwy do zrozumienia. Pin analogowy jest odczytywany dwukrotnie. „Błąd” można uniknąć, dodając najpierw następujący wiersz w szkicu:

#undef abs 

Spowoduje to usunięcie makra abs() i standardowa funkcja biblioteczna zostaną użyte w zamian.

Pozdrawiam!

Komentarze

  • Błąd to abs() makro w Arduino.h
  • Dziękuję za jasną odpowiedź. Nie miałem pojęcia, że makra istnieją nawet w świecie Arduino. Udało mi się znaleźć post z 2011 r., W którym omówiono to i krótką listę innych makr. Czy znasz ostateczną listę? Czy to po prostu więcej " Arduinoesque " i lepsza praktyka, aby uniknąć wielu przypisań w linii i trzymać się jednej operacji na linię? >
  • Nie, nie jest bardziej Arduinoesque używanie tylko jednej operacji w jednym przypisaniu. Czasami ma to na celu ułatwienie czytania. Twój problem z makrami nie musi mieć wiele wspólnego z Arduino. Bardziej ogólnie dotyczy sposobu oceny makr przez kompilator. Kompilator zastępuje makro tym, co jest w nim zapisane ' s definicją (i wstawia argument). To nie jest funkcja. I to nie jest specyficzne dla Arduino, ale zależy od kompilatora. Możesz także używać makr podczas programowania z innymi kompilatorami. Makra mogą być przydatne, ale należy ich używać ostrożnie.
  • @chrisl, istnieje już abs i labs funkcja. Makro arduino abs to absurdalna pomyłka autorstwa arduino. Aaron Ciuffo, kliknij link do Arduino.h w odpowiedzi Mikaela Patela, tam zobaczysz inne makra. Inną rzeczą jest nieużywanie zmiennej o nazwie " B1 ".

Dodaj komentarz

Twój adres email nie zostanie opublikowany. Pola, których wypełnienie jest wymagane, są oznaczone symbolem *