Valores negativos inesperados de la función abs () en línea con analogRead

Al muestrear desde A0 con una señal de 0-5V en un micro arduino con el código siguiente, obtengo algunos valores negativos.

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

Valores:

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

Cuando se ejecuta (aparentemente) matemáticamente código equivalente a continuación obtengo valores exclusivamente positivos.

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

No creo que este sea un desbordamiento de enteros como en esta publicación porque cuando cambio a long sensor = 0 obtengo los mismos resultados negativos.

¿Qué está pasando aquí?

Respuesta

abs() se define en Arduino.h como macro:

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

Una macro no se evalúa de la misma forma que una función.

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

Esta declaración se expandirá en tiempo de compilación a:

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

Ahora el «error» es fácil de entender. El pin analógico se lee dos veces. El «error» se puede evitar agregando la siguiente línea primero en su boceto:

#undef abs 

Esto eliminará la macro abs() y la función de biblioteca estándar se utilizarán en su lugar.

¡Salud!

Comentarios

  • El error es la abs() macro en Arduino.h
  • Gracias por la respuesta clara. No tenía idea de que existieran macros en el mundo de Arduino. Encontré una publicación de 2011 que analiza esto y una breve lista de otras macros. ¿Conoces una lista definitiva? ¿Es solo más " Arduinoesque " y una mejor práctica para evitar múltiples asignaciones en una línea y ceñirse a una operación por línea?
  • No, no es más arduino usar solo una operación en una asignación. A veces, esto se hace para facilitar la lectura. Su problema con las macros no tiene mucho que ver con Arduino. Se trata más generalmente de cómo el compilador evalúa las macros. El compilador reemplaza la macro con lo que está escrito en su definición ' s (y pone el argumento). No es una función. Y esto no es específico de Arduino, sino que depende del compilador. También puede utilizar macros al programar con otros compiladores. Las macros pueden ser útiles, pero debes usarlas con precaución.
  • @chrisl, ya existe un abs y labs función. La macro arduino abs es un ridículo error de arduino. Aaron Ciuffo, haz clic en el enlace a Arduino.h en la respuesta de Mikael Patel, ahí ves las otras macros. Otra cosa es no usar una variable con el nombre " B1 ".

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *