В этом материале мы рассмотрим, как можно с большей точностью измерять меньшие напряжения, используя аналоговые выводы Arduino или совместимой плате вместе с выводом AREF.
Обзор
Вы можете вспомнить, что вы можете использовать функцию Arduino analogRead() для измерения напряжения электрического тока от датчиков и т.п., используя один из выводов аналогового входа. Значение, возвращаемое функцией analogRead(), должно быть в диапазоне от 0 до 1023, где ноль представляет собой ноль вольт, а 1023 представляет рабочее напряжение используемой платы Arduino.
И когда мы говорим, рабочее напряжение - это напряжение, доступное Arduino после схемы питания. Например, если у вас есть типичная плата Arduino Uno и вы запускаете ее через разъем USB (для платы есть доступные 5 В через разъем USB на вашем компьютере), то напряжение немного уменьшается, поскольку ток идет через всю схему к микроконтроллеру или USB-источник может не давать абсолютное значение.
Это можно легко продемонстрировать, подключив Arduino Uno к USB и установив мультиметр для измерения напряжения на контактах 5В и GND. Некоторые платы возвращают напряжение до 4,8 В, некоторые показывают значения выше 4,8 В, ниже 5 В. Поэтому, если вы стремитесь к точности, питайте вашу плату от внешнего источника питания через разъем постоянного тока или Vin-контакт, например, 9 В постоянного тока. Затем, после этого, пройдя через цепь регулятора мощности, вы получите хорошее напряжение 5 В.
Это важно, поскольку точность любых значений analogRead() будет зависеть от отсутствия истинных 5 В. Если у вас нет никакой опции, вы можете использовать некоторые математические расчеты в своем эскизе, чтобы компенсировать падение напряжения. Например, если ваше напряжение равно 4,8 В - диапазон analogRead() от 0 до 1023 будет относиться к 0 ~ 4,8 В, а не к 0 ~ 5 В. Это может звучать тривиально, однако, если вы используете датчик, который возвращает значение в виде напряжения (например, датчик температуры TMP36) - рассчитанное значение будет неверным. Поэтому в интересах точности используйте внешний источник питания.
Почему analogRead() возвращает значение от 0 до 1023?
Это связано с разрешением АЦП. Разрешение (в рамках этой статьи) - это степень, в которой что-то может быть представлено численно. Чем выше разрешение, тем выше точность, с которой что-то можно представить. Мы измеряем разрешение в терминах количества бит разрешения.
Например, 1-битное разрешение позволит использовать только два (два в степени одного) значения - ноль и единицу. 2-битное разрешение позволило бы получить четыре (два в степени двух) значения - ноль, один, два и три. Если мы попытаемся измерить диапазон в пять вольт с двухбитным разрешением, а измеренное напряжение будет равно четырем вольтам, наш АЦП вернет числовое значение 3 - при падении четырех вольт между 3,75 и 5В. Проще представить это с изображением выше.
Таким образом, в нашем примере АЦП с 2-битным разрешением может представлять напряжение только с четырьмя возможными результирующими значениями. Если входное напряжение падает между 0 и 1,25, АЦП возвращает цифру 0; если напряжение падает между 1,25 и 2,5, АЦП возвращает числовое значение 1. И так далее. С диапазоном АЦП нашего Arduino от 0 до 1023 - у нас есть 1024 возможных значения - или от 2 до 10, поэтому у наших Arduino есть АЦП с 10-битным разрешением.
Что такое AREF?
Когда ваш Arduino берет аналоговое показание, он сравнивает напряжение, измеренное на используемом аналоговом выводе, с так называемым опорным напряжением. При обычном использовании аналогового чтения эталонное напряжение - это рабочее напряжение платы.
Для более популярных плат Arduino, таких как платы Uno, Mega, Duemilanove и Leonardo / Yún, рабочее напряжение 5В. Если у вас есть плата Arduino Due, рабочее напряжение составляет 3,3 В. Таким образом, если у Вас есть опорное напряжение 5 В, каждый блок, возвращаемого analogRead() оценивается в 0.00488 В. (Это рассчитывается путем деления 1024 на 5В). Что если мы хотим измерить напряжения между 0 и 2 или 0 и 4,6? Как АЦП узнает, что составляет 100% от нашего диапазона напряжений?
И в этом заключается причина существования вывода AREF. AREF означает Analog Reference. Это позволяет нам "скормить" Arduino опорное напряжение от внешнего источника питания. Например, если мы хотим измерить напряжения с максимальным диапазоном 3,3 В, мы бы подали хорошие плавные 3,3 В на вывод AREF, например, от ИС регулятора напряжения.
Тогда каждый шаг АЦП будет представлять около 3,22 милливольт (разделить 1024 на 3,3В). Обратите внимание, что самое низкое опорное напряжение вы можете иметь 1.1В. Существует две формы AREF - внутренняя и внешняя, поэтому давайте их проверим.
Внешний AREF
Внешний AREF тот, куда направляется внешний источник опорного напряжения на плате Arduino. Это может происходить от регулируемого источника питания, или, если вам нужно 3,3 В, вы можете получить его от 3,3 В вывода Arduino. Если вы используете внешний источник питания, обязательно подключите GND к выводу GND Arduino. Или, если вы используете источник 3,3 В Arduno - просто установите перемычку с контакта 3,3 В на контакт AREF.
Чтобы активировать внешний AREF, используйте следующее в void setup ():
analogReference(EXTERNAL); // использование AREF для опорного напряжения
Это устанавливает опорное напряжение на то, что вы подключили к пину AREF, что, конечно, будет иметь напряжение между 1,1В и напряжением работы платы.
Очень важное примечание - при использовании внешнего опорного напряжения вы должны установить analogReference() на EXTERNAL (внешнее), прежде чем использовать analogRead(). Это предотвратит вас от короткого замыкания активного внутреннего опорного напряжения и вывода AREF, которое может повредить микроконтроллер на плате. При необходимости вы можете вернуться к рабочему напряжению платы для AREF (то есть - вернуться в нормальное состояние) с помощью следующей команды:
analogReference(DEFAULT);
Как нам продемонстрировать внешний AREF в работе? Используя AREF 3,3 В, следующий скетч измеряет напряжение от A0 и отображает процентная доля всего AREF и рассчитанного напряжения:
#include "LiquidCrystal.h" LiquidCrystal lcd(8,9,4,5,6,7); int analoginput = 0; // our analog pin int analogamount = 0; // stores incoming value float percentage = 0; // used to store our percentage value float voltage =0; // used to store voltage value void setup() { lcd.begin(16, 2); analogReference(EXTERNAL); // use AREF for reference voltage } void loop() { lcd.clear(); analogamount=analogRead(analoginput); percentage=(analogamount/1024.00)*100; voltage=analogamount*3.222; // in millivolts lcd.setCursor(0,0); lcd.print("% of AREF: "); lcd.print(percentage,2); lcd.setCursor(0,1); lcd.print("A0 (mV): "); lcd.println(voltage,2); delay(250); }
Результаты скетча показаны на видео выше.
Внутренний AREF
Микроконтроллеры на наших платах Arduino также могут генерировать внутреннее опорное напряжение 1.1В, и мы можем использовать это для работы AREF. Просто используйте строку:
analogReference(INTERNAL);
Для плат Arduino Mega в void setup() используйте:
analogReference(INTERNAL1V1);
Для Arduino Mega есть также опорное напряжение 2.56В, которое активируется так:
analogReference(INTERNAL2V56);
Наконец, прежде чем останавливаться на результатах, полученных на вашем выводе AREF, всегда откалибруйте показания по известному исправному мультиметру. Функция AREF дает вам больше гибкости при измерении аналоговых сигналов.
5 декабря 2020 в 09:53
Статья хорошая, спору нет. Но всё-таки хотелось, чтобы при переводе учитывались и особенности русского технического языка. Ну не говорят у нас: «Важно, что-то там…», а говорят «Обратите внимание» или «Имейте в виду».
И делить надо не 1024 на 3.3, а наоборот 😉
А в целом, спасибо большое!
7 февраля 2021 в 10:58
Почему нужно делить на 1024, а не на 1023? Ведь 1023 равняется максимальному напряжению.
17 февраля 2021 в 11:45
Потому что делить надо на количество возможных вариантов, а их вместе с вариантом «0» будет 1024.
31 января 2022 в 15:48
А вот как раз и не верно, делить надо на 1023. Даже в видео было видно, что ардуина занижает значения относительно мультиметра. У тебя опорное 5 вольт и максимальный знак 1023. Ты подаёшь 5 вольт и получаешь значение 1023. Очень глупо его делить на 1024, т.к. получится меньше чем 5 вольт.
6 ноября 2022 в 11:47
Если опорное напряжение 5 вольт, то максимальное измеряемое напряжение — примерно 4,995 вольт — код 1023. 5 вольт — уже переполнение. Поэтому REF делить надо на 1024, чтобы узнать напряжение на один бит.
12 июля 2021 в 12:51
Здравствуйте, есть ли у вас схема подключения всех компонентов, если есть, не могли бы вы ей поделиться?
23 декабря 2021 в 19:58
Что нужно изменить в коде чтоб получить три знака после запятой?
16 апреля 2023 в 19:40
Можно ли подавать внешнее опорное напряжение меньше 1,1 В ? Спасибо.