1

When sampling from A0 with a 0-5V signal on an arduino micro with the code below I get some negative values.

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

Values:

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

When running the (apparently) mathematically equivalent code below I get exclusively positive values.

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

I don't think this is an integer overflow as in this post because when I switch to long sensor = 0 I get the same negative results.

What's going on here?

6

abs() is defined in Arduino.h as a macro:

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

A macro does not evaluate in the same way as a function.

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

This statement will be expanded at compile-time to:

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

Now the "error" is easy to understand. The analog pin is read twice. The "error" can be avoided by adding the following line first in your sketch:

#undef abs

This will remove the macro abs() and the standard library function will be used instead.

Cheers!

  • The error is the abs() macro in Arduino.h – Jot Mar 14 at 6:33
  • Thanks for the clear answer. I had no idea that macros even existed in the Arduino world. I found a post from 2011 discussing this and a short list of other macros. Do you know of a definitive list? Is it just more "Arduinoesque" and better practice to avoid multiple assignments in a line and stick to one operation per line? – Aaron Ciuffo Mar 14 at 7:05
  • No, it is not more Arduinoesque to use only one operation in one assignment. Sometimes this is done to make it easier to read. Your problem with macros does not have to do much with Arduino. It is more generally about how macros are evaluated by the compiler. The compiler replaces the macro with what is written in it's definition (and puts in the argument). It is not a function. And this is not Arduino specific, but depends on the compiler. You can also use macros, when programming with other compilers. Macros can be useful, but you have to use them with caution. – chrisl Mar 14 at 8:18
  • @chrisl, there is already a abs and labs function. The arduino abs macro is a ludicrous blunder by arduino. Aaron Ciuffo, click on the link to Arduino.h in the answer by Mikael Patel, there you see the other macros. Another thing is not to use a variable with the name "B1". – Jot Mar 14 at 8:23

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.