Valori negativi imprevisti dalla funzione abs () in linea con analogRead

Quando si campiona da A0 con un segnale 0-5V su un micro arduino con il codice sotto, ottengo alcuni valori negativi.

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

Valori:

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

Quando si esegue (apparentemente) matematicamente codice equivalente di seguito ottengo valori esclusivamente positivi.

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

Non credo che si tratti di un numero intero overflow come in questo post perché quando passo a long sensor = 0 ottengo gli stessi risultati negativi.

Cosa succede qui?

Risposta

abs() è definita in Arduino.h come macro:

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

Una macro non viene valutata allo stesso modo di una funzione.

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

Questa istruzione verrà espansa in fase di compilazione a:

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

Ora l “errore” è facile da capire. Il pin analogico viene letto due volte. L “errore” può essere evitato aggiungendo prima la seguente riga nel tuo schizzo:

#undef abs 

Questo rimuoverà la macro abs() e verrà utilizzata la funzione di libreria standard .

Saluti!

Commenti

  • Lerrore è la macro abs() in Arduino.h
  • Grazie per la chiara risposta. Non avevo idea che le macro esistessero anche nel mondo Arduino. Ho trovato un post del 2011 che parlava di questo e di un breve elenco di altre macro. Conosci una lista definitiva? È solo più " Arduinoesque " e una pratica migliore per evitare più assegnazioni in una riga e attenersi a unoperazione per riga?
  • No, non è più arduino utilizzare una sola operazione per assegnazione. A volte questo viene fatto per renderlo più facile da leggere. Il tuo problema con le macro non ha molto a che fare con Arduino. Si tratta più in generale di come le macro vengono valutate dal compilatore. Il compilatore sostituisce la macro con ciò che è scritto nella definizione ' (e inserisce largomento). Non è una funzione. E questo non è specifico per Arduino, ma dipende dal compilatore. È inoltre possibile utilizzare le macro durante la programmazione con altri compilatori. Le macro possono essere utili, ma devi usarle con cautela.
  • @chrisl, esistono già abs e labs funzione. La macro arduino abs è un ridicolo errore di arduino. Aaron Ciuffo, clicca sul link ad Arduino.h nella risposta di Mikael Patel, lì vedi le altre macro. Unaltra cosa è non utilizzare una variabile con il nome " B1 ".

Lascia un commento

Il tuo indirizzo email non sarà pubblicato. I campi obbligatori sono contrassegnati *