Неожиданные отрицательные значения из функции abs(), встроенной в AnalogRead
При выборке из A0 с сигналом 0–5 В на Arduino Micro с помощью приведенного ниже кода я получаю некоторые отрицательные значения.
int sensor = 0;
sensor = abs(analogRead(A0) - 512);
Значения:
77
25
-74
-58
46
113
-74
102
-91
-51
-126
47
31
При запуске (очевидно) математически эквивалентного кода ниже я получаю исключительно положительные значения.
int sensor = 0;
sensor = analogRead(A0);
sensor = sensor - 512;
sensor = abs(sensor);
Я не думаю, что это целочисленное переполнение, как в этом посте, потому что когда я переключаюсь на long Sensor = 0
Я получаю такие же отрицательные результаты.
Что здесь происходит?
@Aaron Ciuffo, 👍1
1 ответ
Лучший ответ:
abs()
определен в Arduino.h как макрос:
#define abs(x) ((x)>0?(x):-(x))
Макрос не оценивается так же, как функция.
sensor = abs(analogRead(A0) - 512);
Этот оператор будет расширен во время компиляции до:
sensor = ((analogRead(A0) - 512)>0?(analogRead(A0) - 512):-(analogRead(A0) - 512));
Теперь «ошибку» понять легко. Аналоговый вывод считывается дважды. «Ошибки» можно избежать, добавив в скетч сначала следующую строку:
#undef abs
Это приведет к удалению макроса abs()
и функции стандартной библиотеки вместо этого будет использоваться.
Удачи!
- Arduino Micro против Pro Micro
- Разные и самые быстрые способы вычисления синусов и косинусов в Arduino
- Arduino Pro Micro не распознается компьютером и не отображается в портах
- Программирование Arduino Micro через RX/TX
- Избегайте математических вычислений с плавающей запятой, чтобы ускорить Arduino
- TCCR1A и TCCR2A на Леонардо
- функция eval() для Arduino?
- 433 МГц отправка не принимается
Ошибка — макрос
abs()
в Arduino.h., @JotСпасибо за четкий ответ. Я понятия не имел, что макросы вообще существуют в мире Arduino. Я нашел [сообщение](http://forum.arduino.cc/index.php?topic=84364.0) от 2011 года, в котором обсуждался этот и краткий список других макросов. Знаете ли вы окончательный список? Является ли это просто более «ардуинским» подходом и лучшей практикой избегать нескольких присваиваний в строке и придерживаться одной операции в строке?, @Aaron Ciuffo
Нет, использование только одной операции в одном задании не более похоже на Arduino. Иногда это делается для облегчения чтения. Ваша проблема с макросами не имеет большого отношения к Arduino. В более общем плане речь идет о том, как компилятор оценивает макросы. Компилятор заменяет макрос тем, что написано в его определении (и помещает аргумент). Это не функция. И это не специфично для Arduino, а зависит от компилятора. Вы также можете использовать макросы при программировании с помощью других компиляторов. Макросы могут быть полезны, но их следует использовать с осторожностью., @chrisl
@chrisl, функции abs и labs уже есть. Макрос Arduino
abs
— это нелепая ошибка Arduino. Аарон Чуффо, щелкните ссылку на Arduino.h в ответе Микаэля Пателя, там вы увидите другие макросы. Другое дело — не использовать переменную с именем «B1»., @Jot