Многоканальный вольтметр на arduino uno с пк. Цифровой вольтметр на Arduino с подключением к ПК через последовательный порт

Привет, Хабр! Сегодня хочу продолжить тему «скрещивания» arduino и android. В предыдущей публикации я рассказал про bluetooth машинку , а сегодня речь пойдет про DIY bluetooth вольтметр. Еще такой девайс можно назвать смарт вольтметр, «умный» вольтметр или просто умный вольтметр, без кавычек. Последнее название является неправильным с точки зрения грамматики русского языка, тем не менее частенько встречается в СМИ. Голосование на эту тему будет в конце статьи, а начать предлагаю с демонстрации работы устройства, чтобы понять о чем же пойдет речь в статье.


Disclaimer: статья рассчитана на среднестатистического любителя arduino, который обычно не знаком с программированием под android, поэтому как и в прошлой статье, приложение для смартфона мы будем делать, используя среду визуальной разработки android-приложений App Inventor 2.
Чтобы сделать DIY bluetooth вольтметр нам нужно написать две относительно независимых друг от друга программы: скетч для ардуино и приложение для андроид.Пожалуй начнем со скетча.
Для начала следует знать, что существует три основных варианта измерения напряжения при помощи ардуино, не зависимо от того куда нужно выводить информацию: в com-порт, на подключенный к ардуино экранчик, или на смартфон.
Первый случай: измерения напряжения до 5 вольт. Здесь достаточно одной-двух строк кода, а напряжение подается напрямую на пин А0:
int value = analogRead(0);// читаем показания с А0
voltage = (value / 1023.0) * 5; // верно только если Vcc = 5.0 вольт
Второй случай: для измерения напряжения более 5 вольт используется делитель напряжения. Схема очень простая, код тоже.

Скетч

int analogInput = A0;
float val = 0.0;
float voltage = 0.0;
float R1 = 100000.0; //Battery Vin-> 100K -> A0
float R2 = 10000.0; //Battery Gnd -> Arduino Gnd and Arduino Gnd -> 10K -> A0
int value = 0;

Void setup() {
Serial.begin(9600);
pinMode(analogInput, INPUT);
}

Void loop() {
value = analogRead(analogInput);
val = (value * 4.7) / 1024.0;
voltage = val / (R2/(R1+R2));
Serial.println(voltage);
delay(500);
}


Arduino Uno
Блютуз модуль
Третий случай. Когда нужно получить более точные о напряжении в качестве опорного напряжения нужно использовать не напряжение питания, которое может немного меняться при питании от акб, например, а напряжение внутренного стабилизатора ардуино 1.1 вольт.Тут схема такая же, но код чуть длиннее. Подробно этот вариант разбирать не буду, так как он и так хорошо описан в тематических статьях, а мне вполне и достаточно второго способа, поскольку питание у меня стабильное, от usb-порта ноутбука.
Итак с измерением напряжения мы разобрались, теперь перейдем ко второй половине проекта: созданию андроид-приложения. Приложение будем делать прямо из браузера в среде визуальной разработки android-приложений App Inventor 2. Заходим на сайт appinventor.mit.edu/explore , авторизуемся с помощью гугл-аккаунта, нажимаем кнопку create, new project, и путем простого перетаскивания элементов создаем примерно такой дизайн:

Я сделал графику очень простой, если кому-то захочется более интересной графики, напомню, что для этого нужно использовать вместо.jpeg файлов, файлы формата.png с прозрачным фоном.
Теперь переходим во вкладку Blocks и создаем там логику работы приложения примерно так:


Если все получилось можно нажимать кнопку Build и save .apk to my computer, а затем уже скачиваем и устанавливаем приложение на смартфон, хотя есть и другие способы заливки приложения. тут уж кому как удобнее. В итоге у меня получилось вот такое приложение:


Понимаю, что мало кто использует среду визуальной разработки android-приложений App Inventor 2 в своих проектах, поэтому может возникнуть много вопросов по поводу работы в ней. Чтобы снять часть таких вопросов, я сделал подробное видео, о том как сделать такое приложение «с нуля»(для просмотра нужно перейти на ютуб):

P.S. Сборник из более 100 обучающих материалов по ардуино для начинающих и профи

Описано как собрать самодельный двойной вольтметр на основе платформы Arduino UNO с использованием ЖК-дисплея 1602A. В некоторых случаях необходимо измерять одновременно два постоянныхнапряжения и сравнивать их. Это может потребоваться, например, при ремонте или налаживании стабилизатора постоянного напряжения, чтобы измерять напряжение на его входе и выходе, либо в других случаях.

Принципиальная схема

Используя универсальный микроконтроллерный модуль ARDUINO UNO и двухстрочный ЖК-дисплей типа 1602А (на основе контроллера HD44780) можно легко сделать такой прибор. В одной строке он будет показывать напряжение U1, в другой - напряжение U2.

Рис. 1. Принципиальная схема двойного вольтметра с дисплеем 1602A на Arduino UNO.

Но, прежде всего, хочу напомнить, что ARDUINO UNO это относительно недорогой готовый модуль, - небольшая печатная плата, на которой расположен микроконтроллер ATMEGA328, а так же вся его «обвязка», необходимая для его работы, включая USB-программатор и источник питания.

Тем, кто незнаком с ARDUINO UNO, советую сначала ознакомиться со статьями Л.1 и Л.2. Схема двойного вольтметра показана на рис. 1. Он предназначен для измерения двух напряжений от 0 до 100V (практически, до 90V).

Как видно из схемы, к цифровым портам D2-D7 платы ARDUINO UNO подключен модуль жидкокристаллического индикатора Н1 типа 1602А. Питается ЖК-индикатор от стабилизатора напряжения 5V, имеющегося на плате стабилизатора напряжения 5V.

Измеряемые напряжения поступают на два аналоговых входа А1 и А2. Всего аналоговых входов шесть, - А0-А5, можно было выбрать любые два из них. В данном случае, выбраны А1 и А2. Напряжение на аналоговых портах может быть только положительным и только в пределах от нуля до напряжения питания микроконтроллера, то есть, номинально, до 5V.

Выход аналогового порта преобразуется АЦП микроконтроллера в цифровую форму. Для получения результата в единицах вольт, нужно его умножить на 5 (на опорное напряжение, то есть, на напряжение питания микроконтроллера) и разделить на 1024.

Для того чтобы можно было измерять напряжение более 5V, вернее, более напряжения питания микроконтроллера, потому что реальное напряжение на выходе 5-вольтового стабилизатора на плате ARDUINO UNO может отличаться от 5V, и обычно немного ниже, нужно на входе применить обычные резистивные делители. Здесь это делители напряжения на резисторах R1, R3 и R2, R4.

При этом, для приведения показаний прибора к реальному значению входного напряжения, нужно в программе задать деление результата измерения на коэффициент деления резистивного делителя. А коэффициент деления, обозначим его «К», можно вычислить по такой формуле:

К = R3 / (R1+R3) или К = R4 / (R2+R4),

соответственно для разных входов двойного вольтметра.

Очень любопытно то, что резисторы в делителях совсем не обязательно должны быть высокоточными. Можно взять обычные резисторы, затем измерить их фактическое сопротивление точным омметром, и уже в формулу подставить эти измеренные значения. Получится значение «К» для конкретного делителя, которое и нужно будет подставлять в формулу.

Программа для вольтметра

Программа на языке C++ приведена на рисунке 2.

Рис. 2. Исходный код программы.

Для управления ЖК-индикатором решено было использовать порты с D2 по D7 платы ARDUINO UNO. В принципе, можно и другие порты, но я вот так, решил использовать именно эти.

Для того чтобы индикатор взаимодействовал с ARDUINO UNO нужно в программу загрузить подпрограмму для его управления. Такие подпрограммы называются «библиотеками», и в программном комплекте для ARDUINO UNO есть много разных «библиотек». Для работы с ЖК-индикатором на основе HD44780 нужна библиотека LiquidCrystal. Поэтому программа (таблица 1) начинается с загрузки этой библиотеки:

Эта строка дает команду загрузить в ARDUINO UNO данную библиотеку. Затем, нужно назначить порты ARDUINO UNO, которые будут работать с ЖК-индикатором. Я выбрал порты с D2 по D7. Можно выбрать другие. Эти порты назначены строкой:

LiquidCrystal led(2, 3, 4, 5, 6, 7);

После чего, программа переходит собственно к работе вольтметра. Для измерения напряжения решено было использовать аналоговые входы А1 и А2. Эти входы заданы в строках:

int analogInput=1;

int analogInput1=2;

Для чтения данных с аналоговых портов используется функция analogRead. Чтение данных с аналоговых портов происходит в строках:

vout=analogRead(analogInput);

voutl=analogRead(analoglnput1);

Затем, производится вычисление фактического напряжения с учетом коэффициента деления делителя входного напряжения:

volt=vout*5.0/1024.0/0.048 ;

volt1=vout1*5.0/1024.0/0.048;

В этих строках число 5.0 - это напряжение на выходе стабилизатора платы ARDUINO UNO. В идеале должно быть 5V, но для точной работы вольтметра это напряжение нужно предварительно измерить. Подключите источник питания и измерьте достаточно точным вольтметром напряжение +5V на разъеме POWER платы. Что будет, то и вводите в эти строки вместо 5.0, например, если будет 4.85V, строки будут выглядеть так:

volt=vout*4.85/1024.0/0.048;

volt1=vout1*4.85/1024.0/0.048;

На следующем этапе нужно будет измерить фактические сопротивления резисторов R1-R4 и определить коэффициенты К (указаны 0.048) для этих строк по формулам:

К1 = R3 / (R1+R3) и К2 = R4 / (R2+R4)

Допустим, К1 = 0.046, а К2 = 0.051, так и пишем:

volt=vout*4.85/1024.0/0.046 ;

volt1=vout1*4.85/1024.0/0.051;

Таким образом, в текст программы нужно внести изменения соответственно фактическому напряжению на выходе 5-воль-тового стабилизатора платы ARDUINO UNO и согласно фактическим коэффициентам деления резистивных делителей. После этого прибор будет работать точно и никакого налаживания или калибровки не потребует.

Изменив коэффициенты деления резистивных делителей (и, соответственно, коэффициенты «К») можно сделать другие пределы измерения, и совсем не обязательно одинаковые для обоих входов.

Каравкин В. РК-2017-01.

Литература:

  1. Каравкин В. - Ёлочная мигалка на ARDUINO как средство от боязни микроконтроллеров. РК-11-2016.
  2. Каравкин В. - Частотомер на ARDUINO. РК-12-2016.

Идея

Идея устройства для измерения напряжения, тока, емкости, разряда, а может и заряда возникла давно и не только у меня. Можно найти немало игрушек под названием USB Tester (Doctor) для тестирования различных устройств с USB. Мне же интересно несколько более универсальное устройство, независимое от интерфейса, а просто рассчитанное на определенные напряжения и токи. Например, 0 - 20.00в, 0 - 5.00а, 0 - 99.99Ач. Что касается функций, то я вижу так

  • Отображение текущих напряжения и тока, то есть вольт-ампер-метр. Впринципе, можно и мощность сразу отразить.
  • Подсчет и отображение накопленной емкости. В ампер-часах и всего скорее в ватт-часах.
  • Отображение времени процесса
  • И, всего скорее, настраиваемые нижний и верхний пороги отключения по напряжению (ограничения разряда и заряда)

Разработка

Для реализации расчетов и измерений нам понадобится контроллер. Я вспомнил эту идею в рамках знакомства с Arduino, поэтому контроллером будет простая популярная Atmega328 и программироваться она будет в среде Arduino. С инженерной точки зрения выбор наверно не самый хороший - контроллер для задачи слегка жирноват, а его АЦП не назовешь измерительными, но... будем пробовать.

  • Паять в этом проекте много не будем. В качестве основы возьмем готовый модуль Arduino Pro Mini, благо китайцы готовы их поставлять по $1.5 в розницу.
  • В качестве устройства отображения будет выступать дисплей 1602 - еще $1.5. У меня вариант с интерфейсным модулем I2C, но в этом проекте он не сильно нужен ($0.7).
  • Для разработки нам понадобиться макетная плата. В моем случае это небольшая BreadBoard за $1.
  • Разумеется понадобятся провода и некоторое количество резисторов разного номинала. Для дисплея 1602 без I2C нужен также подбор контрастности - делается переменным резистором на 2 - 20 кОм.
  • Для реализации амперметра понадобится шунт. В первом приближении им может быть резистор 0.1 Ом, 5 Вт.
  • Для реализации автоматики отключения понадобится реле с контактами рассчитанными на максимальный ток устройства и напряжением равным напряжению питания. Для управления реле нужен npn транзистор и защитный диод.
  • Устройство будет питаться от внешнего источника питания, очевидно, что не менее 5 в. Если питание будет сильно варьироваться, то так же потребуется интегральный стабилизатор типа 7805 - он и определит напряжение реле.
  • В случае Arduino Pro Mini для заливки прошивки потребуется USB-TTL конвертер.
  • Для наладки понадобится мультиметр.

Вольтметр

Я реализую простой вольтметр с одним диапазоном примерно 0 - 20в. Это замечанием важно, тк АЦП нашего контроллера имеет разрядность 10 бит (1024 дискретных значения), поэтому погрешность составит не менее 0.02 в (20 / 1024). Для реализации железно нам нужен аналоговый вход контроллера, делитель из пары резисторов и какой-нибудь вывод (дисплей в законченном варианте, для отладки можно последовательный порт).

Принцип измерения АЦП состоит в сравнении напряжения на аналоговом входе с опорным VRef. Выход АЦП всегда целый - 0 соответствует 0в, 1023 соответствует напряжению VRef. Измерение реализовано путем серии последовательных чтений напряжения и усреднения по периоду между обновлениями значения на экране. Выбор опорного напряжения важен, поскольку по умолчанию оно равно напряжению питания, которое может быть не стабильно. Это нам совершенно не подходит - за основу мы будем брать стабильный внутренний опорный источник напряжением 1.1в, инициализируя его вызовом analogReference(INTERNAL). Затем мы откалибруем его значение по показаниям мультиметра.

На схеме слева - вариант с прямым управлением дисплея (он просто управляется - смотрите стандартный скетч LiquidCrystal\HelloWorld). Справа - вариант с I2C, который я и буду использовать дальше. I2C позволяет сэкономить на проводах (коих в обычном варианте - 10, не считая подсветки). Но при этом необходим дополнительный модуль и более сложная инициализация. В любом случае, отображение символов на модуле надо сначала проверить и настроить контрастность - для этого надо просто вывести после инициализации любой текст. Контрастность настраивается резистором R1, либо аналогичным резистором I2C модуля.

Вход представляет собой делитель 1:19, который позволяет при Vref = 1.1 получить максимальное напряжение около 20в (обычно параллельно входу ставят конденсатор + стабилитрон для защиты, но нам пока это не важно). Резисторы имеют разброс, да и опорное Vref контроллера тоже, поэтому после сборки надо измерить напряжение (хотя бы питания) параллельно нашим устройством и эталонным мультиметром и подобрать Vref в коде до совпадения показания. Так же стоить отметить, что любой АЦП имеет напряжение смещения нуля (которое портит показания в начале диапазона), но мы пока не будем в это углубляться.

Также важным будет разделение питающей и измерительной "земли". Наш АЦП имеет разрешение чуть хуже 1мВ, что может создавать проблемы при неправильной разводке, особенно на макете. Поскольку разводка платы модуля уже сделана и нам остается только выбор пинов. "Земляных" пинов у модуля несколько, поэтому мы должны сделать так, чтобы питание в модуль заходило по одной "земле", а измерения по другой. Фактически для изменений я всегда использую "земляной" пин ближайший к аналоговым входам.

Для управление I2C используется вариант библиотеки LiquidCrystal_I2C - в моем случае указывается специфическая распиновка модуля I2C (китайцы производят модули с отличающимся управлением). Так же отмечу, что I2C в Arduino предполагает использование именно пинов A4, A5 - на плате Pro Mini они находятся не с краю, что неудобно для макетирования на BreadBoard.

Исходный код

#include #include // Простой вольтметр с i2c дисплеем 1602. V 16.11 // Настройки i2c дисплея 1602 с нестандартной распиновкой #define LCD_I2C_ADDR 0x27 #define BACKLIGHT 3 #define LCD_EN 2 #define LCD_RW 1 #define LCD_RS 0 #define LCD_D4 4 #define LCD_D5 5 #define LCD_D6 6 #define LCD_D7 7 LiquidCrystal_I2C lcd(LCD_I2C_ADDR,LCD_EN,LCD_RW,LCD_RS,LCD_D4,LCD_D5,LCD_D6,LCD_D7); // Время обновления показаний, мс (200-2000) #define REFRESH_TIME 330 // Аналоговй вход #define PIN_VOLT A0 // Внутреннее опорное напряжение (подобрать) const float VRef = 1.10; // Коэффициент входного резистивного делителя (Rh + Rl) / Rl. IN <-[ Rh ]--(analogInPin)--[ Rl ]--|GND const float VoltMult = (180.0 + 10.0) / 10.0; float InVolt, Volt; void setup() { analogReference(INTERNAL); // Инициализация дисплея lcd.begin (16, 2); lcd.setBacklightPin(BACKLIGHT, POSITIVE); lcd.setBacklight(HIGH); // включить подсветку lcd.clear(); // очистить дисплей lcd.print("Voltage"); } void loop() { unsigned long CalcStart = millis(); int ReadCnt = 0; InVolt = 0; // Чтение из порта с усреднением while ((millis() - CalcStart) < REFRESH_TIME) { InVolt += analogRead(PIN_VOLT); ReadCnt++; } InVolt = InVolt / ReadCnt; // Смещение 0 для конкретного ADC (подобрать или отключить) if (InVolt > 0.2) InVolt += 3; // Перевод в вольты (Value: 0..1023 -> (0..VRef) scaled by Mult) Volt = InVolt * VoltMult * VRef / 1023; // Вывод данных lcd.setCursor (0, 1); lcd.print(Volt); lcd.print("V "); }

С некоторыми дополнениями.

Мало известная фишка Ардуино и многих других AVR чипов это возможность измерить внутренний источник опорного напряжения 1.1 В. Эта функция может быть использована для повышения точности функции Arduino — analogRead при использовании стандартного опорного напряжения 5 В (на платформах с напряжением питания 5 В) или 3.3 В (на платформах с напряжением питания 3.3 В). Она также может быть использована для измерения Vcc , поданного на чип , обеспечивая средство контроля напряжения батареи без использования драгоценных аналоговый выводов .

Мотивация

Есть, по крайней мере, две причины для измерения напряжения, питающего наш Arduino (Vcc). Одним из них является наш проект, питающийся от батареи, если мы хотим следить за уровнем напряжения батареи. Кроме того, когда питание от батареи (Vcc) не может быть 5,0 вольт(например питание от 3-х элементов 1.5 В), а мы хотим сделать аналоговые измерения более точными - мы должны использовать либо внутренний источник опорного напряжения 1,1 В либо внешний источник опорного напряжения. Почему?

Обычно предполагают при использовании analogRead () то, что аналоговое напряжение питания контроллера составляет 5.0 вольт, когда в действительности это может быть совсем не так(например питание от 3-х элементов 1.5 В). Официальная документация Arduino даже может привести нас к этому неправильному предположению. Дело в том, что питание не обязательно 5,0 вольт, независимо от текущего уровня это питание подано на Vcc чипа. Если наше питание не стабилизировано или если мы работаем от аккумулятора, это напряжение может меняться совсем немного. Вот пример кода, иллюстрирующий эту проблему:

Double Vcc = 5.0; // не обязательно правда int value = analogRead(0); / читаем показания с А0 double volt = (value / 1023.0) * Vcc; // верно только если Vcc = 5.0 вольт Для того чтобы измерить напряжение точно, необходимо точное опорное напряжение. Большинство чипов AVR обеспечивает три источника опорного напряжения:

  • 1,1 в от внутреннего источника, в документации он проходит как bandgap reference (некоторые из них 2,56 В, например ATMega 2560). Выбор осуществляется функцией analogReference() с параметром INTERNAL : analogReference(INTERNAL) ;
  • внешний источник опорного наптяжения, на ардуинке подписан AREF. Выбор: analogReference(EXTERNAL);
  • Vcc - источник питания самого контроллера. Выбор: analogReference(DEFAULT).

В Arduino нельзя просто взять и подключить Vcc к аналоговому пину напрямую - по умолчанию AREF связан с Vcc и вы всегда будете получать максимальное значение 1023, от какого бы напряжения вы не питались. Спасает подключение к AREF источника напряжения с заранее известным, стабильным напряжением, но это - лишний элемент в схеме.

Еще можно соединить Vcc с AREF через диод : падение напряжение на диоде заранее известно, поэтому вычислить Vcc не составит труда. Однако, при такой схеме через диод постоянно протекает ток , сокращая жизнь батареи, что тоже не очень удачно.

Источник внешнего опорного напряжения является наиболее точным, но требует дополнительных аппаратных средств. Внутренний ИОН стабильным, но не точен + / - 10% отклонение. Vcc является абсолютно ненадежен в большинстве случаев. Выбор внутреннего источника опорного напряжения является недорогим и стабильным, но большую часть времени, мы хотели бы измеряет большее напряжение чем 1.1 В, так что использование Vcc является наиболее практичным, но потенциально наименее точным. В некоторых случаях оно может быть очень ненадежным!

Как это сделать

Многие чипы AVR включая серию ATmega и ATtiny обеспечивают средства для измерения внутреннего опорного напряжения. Зачем это нужно? Причина проста - путем измерения внутреннего напряжения, мы можем определить значение Vcc. Вот как:

  1. Установить источник опорного напряжения по умолчанию: analogReference(DEFAULT); . Используем как источник - Vcc.
  2. Снять показания АЦП для внутреннего источника 1.1 В.
  3. Расчитать значение Vcc основываясь на измерении 1.1 В по формуле:

Vcc * (Показания АЦП) / 1023 = 1.1 В

Из чего следует:

Vcc = 1,1 В * 1023 / (Показания АЦП)

Собираем все вместе и получаем код:

long readVcc() { // Read 1.1V reference against AVcc // set the reference to Vcc and the measurement to the internal 1.1V reference #if defined(__AVR_ATmega32U4__) || defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) ADMUX = _BV(REFS0) | _BV(MUX4) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1); #elif defined (__AVR_ATtiny24__) || defined(__AVR_ATtiny44__) || defined(__AVR_ATtiny84__) ADMUX = _BV(MUX5) | _BV(MUX0); #elif defined (__AVR_ATtiny25__) || defined(__AVR_ATtiny45__) || defined(__AVR_ATtiny85__) ADMUX = _BV(MUX3) | _BV(MUX2); #else ADMUX = _BV(REFS0) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1); #endif delay(75); // Wait for Vref to settle ADCSRA |= _BV(ADSC); // Start conversion while (bit_is_set(ADCSRA,ADSC)); // measuring uint8_t low = ADCL; // must read ADCL first - it then locks ADCH uint8_t high = ADCH; // unlocks both long result = (high<<8) | low; result = 1125300L / result; // Calculate Vcc (in mV); 1125300 = 1.1*1023*1000 return result; // Vcc in millivolts }

Использование

Проверка напряжения Vcc или батареи

Вы можете назвать эту функцию – readVcc(), если Вы хотите мониторить Vcc. Примером может служить для проверка уровня заряда батареи. Вы также можете использовать её для определения подключены ли Вы к источнику питания или работаете от батареи.

Измерение Vcc для опорного напряжения

Вы также можете использовать её, чтобы получить правильное значение Vcc для использования с analogRead (), когда вы используете опорное напряжение (Vcc). Пока Вы не используете стабилизированный источник питания, Вы не можете быть уверенны, что Vcc = 5.0 вольт. Эта функция позволяет получить правильное значение. Хотя есть один нюанс….

В одной из статей я сделал заявление, что эта функция может использоваться, чтобы улучшить точность аналоговых измерений в тех случаях, когда Vcc было не совсем 5.0 вольт. К сожалению, эта процедура не будет давать точный результат. Почему? Это зависит от точности внутреннего источника опорного напряжения. Спецификация дает номинальное напряжение 1.1 вольт, но говорится, что оно может отличаться до 10%. Такие измерения могут быть менее точными, чем наш источник питания Arduino!

Повышаем точность

Пока большие допуски внутреннего источника питания 1.1 В. значительно ограничивают точность измерений при использовании в серийном производстве, для индивидуальных проэктов мы можем добиться большей точности. Сделать это просто, просто измерив Vcc с помощью вольтметра и нашей функции readVcc(). Далее заменяем константу 1125300L новой переменной:

scale_constant = internal1.1Ref * 1023 * 1000

internal1.1Ref = 1.1 * Vcc1 (показания_вольтметра) / Vcc2 (показания_функции_readVcc())

Это калиброванное значение будет хорошим показателем для измерений AVR чипом, но может зависеть от изменений температуры. Не стесняйтесь экспериментировать с вашим собственным измерениям.

Вывод

С этой маленькой функцией можно сделать многее. Вы можете использовать стабильное опорное напряжение близкое к 5.0 В не имея на самом деле 5.0 В на Vcc. Вы можете измерять напряжение вашей батареи или даже увидеть на каком вы питание от батареи или от стационарного источника питания.

И наконец, код будет поддерживать все Arduino, включая новый Leonardo, а также чипы ATtinyX4 и ATtinyX5 серий.

Представлена полезная схема для любителей поэкспериментировать с Ардуино. Это простой цифровой вольтметр, которым надежно можно измерять постоянное напряжение в диапазоне 0 – 30В. Плату Ардуино, как обычно, можно питать от 9В батареи.

Как вам вероятно известно, аналоговые входы Ардуино можно использовать для измерения постоянного напряжения в диапазоне 0 – 5В и этот диапазон можно увеличить,
используя два резистора в качестве делителя напряжения. Делитель уменьшит измеряемое напряжение до уровня аналоговых входов Ардуино. А затем программа вычислит реальную величину напряжения.

Аналоговый датчик на плате Ардуино определяет наличие напряжения на аналоговом входе и преобразует его в цифровую форму для дальнейшей обработки микроконтроллером. На рисунке напряжение подается на аналоговый вход (А0) через простой делитель напряжения, состоящий из резисторов R1 (100кОм) и R2 (10кОм).

При этих значениях делителя на плату Ардуино можно подавать напряжение от 0 до
55В. На входе А0 имеем измеряемое напряжение деленное на 11,т.е.55В / 11=5В. Иначе говоря, при измерении 55В на входе Ардуино имеем максимально допустимое значение 5В. На практике лучше на этом вольтметре написать диапазон “0 – 30В”, чтобы оставался
Запас по безопасности!

Примечания

Если показания дисплея не совпадают с показаниями промышленного (лабораторного) вольтметра, то необходимо точным прибором измерить величину сопротивлений R1 и R2 и вставить эти значения вместо R1=100000.0 и R2=10000.0 в коде программы. Затем следует измерить лабораторным вольтметром реальное напряжение между выводами 5В и “Земля” платы Ардуино. Получится значение меньшее, чем 5В, например, получилось 4.95В. Это реальное значение следует вставить в строке кода
vout = (value * 5.0) / 1024.0 вместо 5.0.
Кроме того, старайтесь применять прецизионные резисторы с допуском 1%.

Резисторы R1 и R2 обеспечивают некоторую защиту от повышенных входных напряжений.Однако следует помнить, что любые напряжения выше 55В могут вывести из строя плату Ардуино. Кроме того, в этой конструкции не предусмотрены другие виды защиты(от скачков напряжения, от переполюсовки или повышенного напряжения).

Программа цифрового вольтметра

/*
DC Voltmeter
An Arduino DVM based on voltage divider concept
T.K.Hareendran
*/
#include
LiquidCrystal lcd(7, 8, 9, 10, 11, 12);
int analogInput = 0;
float vout = 0.0;
float vin = 0.0;
float R1 = 100000.0; // resistance of R1 (100K) -see text!
float R2 = 10000.0; // resistance of R2 (10K) – see text!
int value = 0;
void setup(){
pinMode(analogInput, INPUT);
lcd.begin(16, 2);
lcd.print(“DC VOLTMETER”);
}
void loop(){
// read the value at analog input
value = analogRead(analogInput);
vout = (value * 5.0) / 1024.0; // see text
vin = vout / (R2/(R1+R2));
if (vin<0.09) {
vin=0.0;//statement to quash undesired reading !
}
lcd.setCursor(0, 1);
lcd.print(“INPUT V= “);
lcd.print(vin);
delay(500);
}

Принципиальная схема Ардуино-вольтметра

Перечень компонентов

Плата Arduino Uno
100 кОм резистор
10 кОм резистор
100 Ом резистор
10кОм Подстроечный резистор
LCD дисплей 16?2 (Hitachi HD44780)