Как считать напряжение ардуино

от admin

Узнаем напряжение питания Arduino

Часто в проектах c Arduino необходимо получать аналоговые значения с различных аналоговых датчиков, при этом, в большинстве случаев, источники внешнего опорного напряжения для АЦП не используются.

Мы просто читаем значение АЦП функцией analogRead( ВЫВОД ) , получаем число от 0 до 1023, которое преобразуем в напряжение по формуле: U = analogRead( ВЫВОД ) * 5.0 / 1023
где 5.0 — это напряжение питания Arduino в Вольтах, а 1023 — это максимальное значение АЦП.

Ошибки при чтении аналоговых значений:

Если в проекте используются только слаботочные модули или раздельное питание, то все аналоговые данные будут актуальны. Но если имеются модули потребляющие значительные токи (моторы, сервоприводы, соленоиды, осветительные приборы и т.д.) и они подключены к питанию Arduino, то это питание может снизится, и полученные аналоговые данные будут некорректны.

    Пример:
  • На аналоговом входе 2.0 В, питание 5.0 В, функция analogRead() вернёт значение 409.
  • На аналоговом входе 2.0 В, питание 4.5 В, функция analogRead() вернёт значение 455.
  • Используя формулу U = analogRead( ВЫВОД ) * 5.0 / 1023 , мы получим:
    • в первом случае: U = 409 * 5.0 / 1023 = 2,0 В. — Верно.
    • во втором случае: U = 455 * 5.0 / 1023 = 2,2 В. — Ошибка.
    • Но если нам известно реальное напряжение питания (Uпит), которое мы будем указывать в формуле пересчёта U = analogRead( ВЫВОД ) * Uпит / 1023 , то получим:
      • в первом случае: U = 409 * 5.0 / 1023 = 2,0 В. — Верно.
      • во втором случае: U = 455 * 4.5 / 1023 = 2,0 В. — Верно.

      Значит для исключения ошибки при чтении напряжений с аналоговых входов, нужно точно знать напряжение питания Arduino.

      Контроль за напряжением питания Arduino:

      Многие Arduino проекты являются портативными, источником питания которых являются аккумуляторы с DC-DC преобразователями.

      Напряжение аккумулятора уменьшается по мере его разряда и DC-DC преобразователь увеличивает потребляемый ток для поддержания стабильного напряжения на выходе. Но рано или поздно, напряжение на выходе DC-DC преобразователя так же начнёт снижаться. Если в схеме питания не предусмотрено отключение при снижении напряжения ниже определённого порога (≈4В), это может привести к нестабильной работе Arduino с непредсказуемым результатом.

      Таких последствий можно избежать, если в коде Arduino постоянно контролировать напряжение питания и, например, уходить в спящий режим при снижении питания ниже 4,5 В.

      Чтение напряжения питания Arduino:

      Для чтения напряжения питания Arduino достаточно подключить разработанную нами библиотеку iarduino_VCC. После чего вам будет доступна функция analogRead_VCC() , возвращающая напряжение питания в вольтах.

      Библиотека не требует создания объектов, подключения внешних деталей, делителей, модулей и т.д. Она не использует ни одного вывода Arduino. Просто у вас появится возможность получать напряжение питания Arduino функцией analogRead_VCC() .

      После загрузки данного скетча, в монитор последовательного порта будет выводиться напряжение питания Arduino. Если Arduino получает питание от компьютера по USB кабелю, то указанное напряжение равно напряжению USB порта вашего компьютера.

      Принцип работы:

      В микроконтроллерах плат Arduino UNO, Mini, Nano, Mega . всего один блок АЦП и он может подключаться к любому аналоговому входу. Обращаясь к функции analogRead( ВЫВОД ) , она переключает вход АЦП на указанный вывод, запускает преобразование АЦП и возвращает результат.

      Как видно из схемы, вход АЦП может подключаться не только к аналоговым входам, но и к встроенному в микроконтроллер датчику температуры, выводу GND или внутреннему источнику опорного напряжения (ИОН).

      Функция analogRead_VCC() переключает вход АЦП на выход ИОН 1V1, а источником опорного напряжения для АЦП выбирает напряжение питания Uпит. Получается что функция читает напряжение ИОН 1V1, которое заведомо известно Uион = 1,1В. Следовательно по показаниям АЦП можно выяснить точное значение напряжения питания Uпит = Uион * 1023 / АЦП.

      В действительности напряжение ИОН 1V1 микроконтроллеров Arduino может отличаться от заявленных 1,1 В на сотые доли. По этому в библиотеке имеются две дополнительные функции, позволяющие определить и указать точное напряжение ИОН 1V1.

      Основная функция библиотеки:

      Функция analogRead_VCC();

      • Назначение: Чтение напряжения питания Arduino.
      • Синтаксис: analogRead_VCC();
      • Параметры: Нет.
      • Возвращаемые значения: float — Напряжение питания в Вольтах.
      • Примечание:
        • Точность показаний до десятых долей вольт, без использования дополнительных функций.

        Дополнительные функции библиотеки:

        Дополнительные функции библиотеки позволяют увеличить точность чтения напряжения питания Arduino до сотых долей вольт. Если такая точность не требуется, то дополнительными функциями можно не пользоваться.

        Аналоговые пины

        В прошлом уроке мы разобрали измерение и вывод цифрового сигнала, а в этом разберём аналоговый сигнал. Зачем нужно читать аналоговый сигнал? Микроконтроллер может выступать в роли вольтметра, измерять собственное напряжение питания, например от аккумулятора, может измерять ток через шунт (если вы знаете закон Ома), можно измерять сопротивление, а также работать с потенциометрами (крутильными, линейными, джойстиками), которые являются очень удобными органами управления.

        В уроке про возможности микроконтроллера мы обсуждали аналоговые входы, т.е. входы, подключенные к АЦП – аналогово-цифровому преобразователю (ADC). Взглянем на распиновку популярных плат (Arduino Nano и Wemos Mini):

        blank

        blank

        Пины, на которых выведен ADC, могут измерять аналоговый сигнал. На плате Nano это пины, маркированные буквой А (A0A7), а у esp8266 такой пин всего один – A0.

        Чтение сигнала

        “Аналоговые” пины могут принимать напряжение от 0V (GND) до опорного напряжения и преобразовывать его в цифровое значение, просто в какие-то условные единицы. АЦП на AVR и esp8266 имеет разрядность в 10 бит, т.е. мы получаем измеренное напряжение в виде числа от 0 до 1023 .

        Функция, которая оцифровывает напряжение, называется analogRead(pin) . Она принимает в качестве аргумента номер аналогового пина и возвращает оцифрованное напряжение. Сам пин должен быть сконфигурирован как INPUT (вход). Нумерация:

        • Arduino Nano:
          • Просто номером А-пина: A0 – 0
          • Как на плате: A0 – A0
          • Порядковым номером GPIO: А0 – 14 , A1 – 15 .. А7 – 21
          • Просто номером А-пина: A0 – 0
          • Как на плате: A0 – A0

          Пример, опрашивающий пин А0:

          Хранить полученное значение разумно в переменной типа int , потому что значение варьируется от 0 до 1023.

          10k) – можно, но всё равно не рекомендуется этого допускать.

          Потенциометры

          Аналоговые пины очень часто используются при работе с потенциометрами (переменный резистор). При помощи полученного значения можно влиять на ход работы программы, менять какие-то настройки и тому подобное. У потенциометра всегда три ноги: две крайние и одна центральная. Всё вместе это представляет собой делитель напряжения, который и позволяет менять напряжение в диапазоне 0-VCC: К Arduino потенциометр подключается следующим образом: средний вывод на любой A-пин, крайние – на GND и питание. От порядка подключения GND и питания зависит направление изменения значения. Что касается сопротивления, то читай заметку по делителям напряжения ниже в этом уроке. Чаще всего для МК ставят потенциометры с сопротивлением 10 кОм, но диапазон в принципе очень широк: от 1 кОм до 100 кОм. Чем больше, тем более шумным будет приходить сигнал, а если брать меньше – пойдут потери тока в нагрев потенциометра, а это никому не нужно. blank

          Опорное напряжение (для AVR Arduino)

          Опорное напряжение играет главную роль в измерении аналогового сигнала, потому что именно от него зависит максимальное измеряемое напряжение и вообще возможность и точность перевода полученного значения 0-1023 в Вольты. Изучим функцию analogReference(mode) , где mode:

          • DEFAULT : опорное напряжение равно напряжению питания МК. Активно по умолчанию
          • INTERNAL : встроенный источник опорного на 1.1V (для ATmega168 или ATmega328P) и 2.56V (на ATmega8)
          • INTERNAL1V1 : встроенный источник опорного на 1.1V (только для Arduino Mega)
          • INTERNAL2V56 : встроенный источник опорного на 2.56V (только для Arduino Mega)
          • EXTERNAL : опорным будет считаться напряжение, поданное на пин AREF

          После изменения источника опорного напряжения (вызова analogReference() ) первые несколько измерений могут быть нестабильными. Значение 1023 функции analogRead() будет соответствовать выбранному опорному напряжению или напряжению выше его.

          В режиме DEFAULT мы можем оцифровать напряжение от 0 до напряжения питания VCC. Если напряжение питания 4.5 Вольта, и мы подаём 4.5 Вольт – получим оцифрованное значение 1023. Если подаём 5 Вольт – опять же получим 1023, т.к. выше опорного. Это правило работает и дальше, главное не превышать 5.5 Вольт. Как измерять более высокое напряжение, читайте ниже.

          Что касается точности: при питании от 5V и режиме DEFAULT мы получим точность измерения напряжения (5 / 1024)

          4.9 милливольт. Поставив INTERNAL мы можем измерять напряжение от 0V до 1.1V с точностью (1.1 / 1024)

          0.98 милливольт. Весьма неплохо, особенно если баловаться с делителем напряжения.

          Что касается внешнего источника опорного напряжения: нельзя подавать напряжение меньше 0V (отрицательное) или выше 5.5V в качестве внешнего опорного в пин AREF. Также при подключении внешнего опорного напряжения нужно вызвать analogReference(EXTERNAL) до первого вызова функции analogRead() (начиная с запуска программы), иначе можно повредить микроконтроллер!

          Чтобы “на лету” переключаться между внутренними и внешним опорными, можно подключить его на AREF через резистор на

          5 кОм. Вход AREF имеет собственное сопротивление в 32 кОм, поэтому реальное опорное будет вычисляться по формуле REF = V * 32 / (R + 32), где R – сопротивление резистора (кОм), через которое подключено опорное напряжение V (Вольт). Например для 2.5V получим 2.5 * 32 / (32 + 5) =

          2.2V реальное опорное.

          Измерение напряжения

          0-5 Вольт

          Простой пример, как измерить напряжение на аналоговом пине и перевести его в Вольты. Плата питается от 5V.

          Таким образом переменная voltage получает значение в Вольтах, от 0 до 5. Чуть позже мы поговорим о более точных измерениях при помощи некоторых хаков. Почему мы делим на 1024, а не на 1023 , ведь максимальное значение измерения с АЦП составляет 1023? Ответ можно найти в даташите:
          АЦП при преобразовании отнимает один бит, т.е. 5.0 Вольт он в принципе может измерить только как 4.995, что и получится по формуле выше: 1023 * 5 / 1024 == 4.995.. . Таким образом делить нужно на 1024.

          Сильно больше 5 Вольт

          Для измерения постоянного напряжения больше 5 Вольт нужно использовать делитель напряжения на резисторах (Википедия). Схема подключения, при которой плата питается от 12V в пин Vin и может измерять напряжение источника (например, аккумулятора):
          Код для перевода значения с analogRead() в Вольты с учётом делителя напряжения:

          Как выбрать/рассчитать делитель напряжения?

          • Согласно даташиту на ATmega, сумма R1 + R2 не рекомендуется больше 10 кОм для достижения наибольшей точности измерения. В то же время через делитель на 10 кОм будет течь ощутимый ток, что критично для автономных устройств (читай ниже). Если девайс работает от сети или от аккумулятора, но МК не используется в режиме сна – ставим делитель 10 кОм и не задумываемся. Также рекомендуется поставить конденсатор между GND и аналоговым пином для уменьшения помех.
          • Если девайс работает от аккумулятора и микроконтроллер “спит”: пусть аккумулятор 12V, тогда через 10 кОм делитель пойдёт ток 1.2 мА. Сам микроконтроллер в режиме сна потребляет

          1 мкА, что в тысячу раз меньше! На самом деле можно взять делитель с гораздо бОльшим суммарным сопротивлением (но не больше 20 МОм, внутреннего сопротивления самого АЦП), но обязательно поставить конденсатор на

          3.13 . Я хочу измерять литиевый аккумулятор с максимальным напряжением 12.8 Вольт. 12.8 / 3.13

          Сильно меньше 5 Вольт

          Для более точных измерений маленького напряжения можно подключить пин AREF к источнику низкого опорного напряжения (об этом было выше), чтобы “сузить” диапазон работы АЦП. Источник может быть как внешний, так и внутренний, например изменив опорное на внутреннее 1.1V ( analogReference(INTERNAL) ) можно измерять напряжение от 0 до 1.1 Вольта с точностью 1.1/1024

          How to make a digital voltmeter using Arduino

          Harshita Arora

          Last Sunday, while I was explaining the basics of electronics and Arduino to my roommate, she challenged me to understand how a voltmeter works and build one from scratch just using the stuff I own already. I accepted the challenge, started hacking, coding, testing, re-coding, and re-testing, and finally I had my voltmeter ready and working by dinner time!

          I used Arduino Uno (to collect voltage in analog and to power the LCD), a small LCD screen that I got in my Arduino starter kit (to display the voltage), a breadboard (to connect everything), and jumper wires.

          If you’re looking for an easy project to learn electronics, then making a digital voltmeter will be fun. Let’s get started!

          The Electric Circuit

          Step 1

          Take a breadboard (I used a small one with 30 rows) and connect an LCD screen to it. Then using a wire, connect one wire from the GND pin (ground state) on the Arduino to the negative charge on breadboard, and one wire from the 5V pin to the positive charge. This provides electric current to the columns on the breadboard, which we can now connect to the LCD.

          Step 2

          Now we’ll connect the pins on the LCD to the breadboard so we can get current to it. Connect Pin 1 of the LCD to a negative charge, Pin 2 to a positive charge, Pin 3 to a negative charge, Pin 5 to a negative charge, Pin 15 to a positive charge, and Pin 16 to a negative charge. Plug in your Arduino to test and see if the LCD turns on!

          Step 3

          Let’s connect the LCD to the Arduino so that we can display the voltage (which we will collect from an analog pin) on the LCD. Connect Pins 4, 6, 11, 12, 13, and 14 of the LCD to any digital pin on Arduino (for example, Pin 2). Then put a wire in the GND and another in an analog pin, like A5. The two wires are now your probe leads.

          We’re now done with the electronics/hardware. Let’s move on to the code.

          The Code

          The code is pretty simple. We just want to collect the analog signal that the Arduino receives at Pin A5 (or any other analog pin) and convert it to digital. We then want to display the results on the LCD screen.

          This is the code that you can copy-paste.

          What’s going on here?

          So we’re first importing the LCD library, then creating a variable named Vpin (which will be the voltage collected from A5). Next, we create two more variables for the voltage, and then a variable of type LiquidCrystal. Finally, we do setup with the Serial monitor (which is a really useful tool in Arduino! Sort of like debug console), convert the analog voltage to digital voltage, and print (display) that value to the LCD screen.

          And that’s it! Go and test out various batteries and points! Here are photos from some tests I did:

          Also, if you want to make the reading on the LCD more legible, put a 1k ohm resistor in the path to Pin 3 (which is for contrast adjustments). By limiting the electric current flowing to that pin, you’ll improve the contrast of the screen.

          Also important note: In this voltmeter, whatever voltage you test will go as a direct input to the Arduino, so you should only test stuff that is in the range of volts that Arduino can safely handle (0–5V). Testing with a 9V battery will fry your Arduino.

          Thanks to this video tutorial for helping me figure out the electric circuit. Special thanks to my friends Nick Arner and Johnny Wang for helping me fix stuff. And thanks to Laura Deming for the challenge! 🙂

          More articles and tutorials on electronics/hardware and brain-computer interfaces on the way! 😀

          Read Analog Voltage

          This example shows you how to read an analog input on analog pin 0, convert the values from analogRead() into voltage, and print it out to the serial monitor of the Arduino Software (IDE).

          Hardware Required

          10k ohm potentiometer

          Circuit

          circuit

          Connect the three wires from the potentiometer to your board. The first goes to ground from one of the outer pins of the potentiometer. The second goes to 5 volts from the other outer pin of the potentiometer. The third goes from the middle pin of the potentiometer to analog input 0.

          By turning the shaft of the potentiometer, you change the amount of resistance on either side of the wiper which is connected to the center pin of the potentiometer. This changes the voltage at the center pin. When the resistance between the center and the side connected to 5 volts is close to zero (and the resistance on the other side is close to 10 kilohms), the voltage at the center pin nears 5 volts. When the resistances are reversed, the voltage at the center pin nears 0 volts, or ground. This voltage is the analog voltage that you're reading as an input.

          The microcontroller of the board has a circuit inside called an analog-to-digital converter or ADC that reads this changing voltage and converts it to a number between 0 and 1023. When the shaft is turned all the way in one direction, there are 0 volts going to the pin, and the input value is 0. When the shaft is turned all the way in the opposite direction, there are 5 volts going to the pin and the input value is 1023. In between, analogRead() returns a number between 0 and 1023 that is proportional to the amount of voltage being applied to the pin.

          Schematic

          schematic

          In the program below, the very first thing you'll do will be in the setup function, to begin serial communication at 9600 bits of data per second, between your board and your computer with the line:

          Next, in the main loop of your code, you need to establish a variable to store the resistance value (which will be between 0 and 1023, perfect for an datatype) coming in from your potentiometer:

          To change the values from 0-1023 to a range that corresponds to the voltage the pin is reading, you'll need to create another variable, a , and do a little math. To scale the numbers between 0.0 and 5.0, divide 5.0 by 1023.0 and multiply that by sensorValue :

          Finally, you need to print this information to your serial monitor. You can do this with the command Serial.println() in your last line of code:

          Now, when you open your Serial Monitor in the Arduino IDE (by clicking on the icon on the right side of the top green bar or pressing Ctrl+Shift+M), you should see a steady stream of numbers ranging from 0.0 — 5.0. As you turn the pot, the values will change, corresponding to the voltage coming into pin A0.

          Learn more

          You can find more basic tutorials in the built-in examples section.

          You can also explore the language reference, a detailed collection of the Arduino programming language.

          Читать:
          Почему при зарядке аккумулятора не падает ток заряда

Похожие публикации