В этой статье мы разберём как использовать функции аналогово-цифрового преобразователя (АЦП) в микроконтроллере Raspberry Pi Pico. Для демонстрации и проверки напишем небольшую программу с использованием MicroPython.
Аналого-цифровой преобразователь.
Для начала давайте скажем несколько слов об аналогово-цифровых преобразователях. Без преувеличения будет сказать, что все величины в физическом мире носят аналоговый характер, и поэтому могут быть измерены аналоговыми измерительными приборами, в которых выходной сигнал или показания являются непрерывной функцией изменений измеряемой величины (самый банальный пример — всем известный со школьных уроков физики лепестковый электроскоп, или стрелочный амперметр или вольтметр).
Свойства аналоговых сигналов в значительной мере являются противоположностью свойств цифровых сигналов: отсутствие чётко отличимых друг от друга дискретных уровней сигнала приводит к невозможности применить для его описания понятие информации в том виде, как она понимается в цифровых технологиях. Содержащееся в одном отсчёте «количество информации» будет ограничено лишь динамическим диапазоном средства измерения. Аналоговые сигналы часто используют для представления непрерывно изменяющихся физических величин. К примеру, аналоговый электрический сигнал, снимаемый с термопары, несёт информацию об изменении температуры, а сигнал, снимаемый с микрофона — о быстрых изменениях давления в звуковой волне, передающихся мембране микрофона и т.п. Показания, снимаемые с аналоговых приборов, можно соотнести с какой-то шкалой и получить градацию данных в виде цифровых значений, т.е. получить набор дискретных данных, записанных с помощью цифр. Аналогово-цифровой преобрезователь автоматизирует этот процесс и превращает аналоговый сигнал в цифровой код, используемый в вычислительных устройствах.
Итак, аналого-цифровой преобразователь (АЦП, англ. Analog-to-digital converter, ADC) — это устройство, преобразующее входной аналоговый сигнал в цифровой сигнал, т.е. в цифровой двоичный код, который затем может быть легко интерпретирован вычислительными устройствами и использоваться в вычислениях и программах. По сути, АЦП являются одним из самых важных электронных компонентов в измерительном и тестовом оборудовании, а также в системах сбора данных.
В случае приложений для взаимодействия с реальным миром (real-life applications), АЦП - это система, которая преобразует аналоговый сигнал, например звук, улавливаемый микрофоном, или свет, попадающий в цифровую камеру, в цифровой сигнал. АЦП также может обеспечивать изолированное измерение, реализуемое в электронных устройствах, которые преобразуют входное аналоговое напряжение или ток в цифровое число, представляющее значение величины напряжения или тока.
Аналого-цифровые преобразователи идеально подходит для датчиков. С помощью АЦП можно определить параметры окружающей среды, такие как свет, звук, расстояние, сила тяжести, ускорение, вращение, запах, газы и т.п. Акселерометр, гироскоп (гиротахометр), барометр, магнитометр, и даже видеокамера — все эти приборы соединяются с центральным процессором с помощью АЦП
В настоящее время большинство микроконтроллеров имеют встроенные преобразователи АЦП. Также возможно подключение внешнего преобразователя АЦП к микроконтроллеру любого типа. Преобразователи АЦП обычно имеют 10 или 12 разрядов, имеющих от 1024 до 4096 уровней квантования. 16-битный АЦП имеет 65536 уровней квантования. Raspberry Pi Pico имеет 12-битный АЦП с уровнем квантования 4096, что в 4 раза лучше, чем 10-битный АЦП Arduino.
Давайте немного подробнее разберемся с уровнем квантования, или другими словами, с разрядностью.
Числа 1024 (0-1023) и 4096 (0-4095) — это и есть разрядность, т.е. точность определения измеряемых величин и чем больше значение этого параметра, тем точнее работает прибор. Предположим, что у нас есть АЦП с разрядностью 1. Подавая на вход любое напряжения от 0 до 2,5 Вольт, на выходе мы получим 0. Любое же напряжение от 2,5 до 5 вольт даст нам единицу. То есть 1-битный АЦП сможет распознать только два уровня напряжения. Графически это можно изобразить так:
Аналого-цифровой преобразователь с разрядностью 2 распознает уже четыре уровня напряжения:
- от 0 до 1,25 — это 0;
- от 1,25 до 2,5 — это 1;
- от 2,5 до 3,75 — это 2;
- наконец, от 3,75 до 5 — это 3.
На этих двух картинках изображена работа АЦП с разрядностью 2 бита и 3 бита:
В Arduino Uno установлен 10-битный АЦП, и это значит, что любое напряжение на аналоговом входе в диапазоне от 0 до 5 вольт будет преобразовано в число с точностью 1/1024 вольта. На графике будет сложно изобразить столько ступенек. Имея такую точность, 10-битный АЦП может «почувствовать» изменение напряжение на входе величиной всего около 5 милливольт (4,8 милливольт). Возвращаясь к Raspberry Pi Pico — он имеет 12-битный АЦП с уровнем квантования 4096, то есть в 4 раза дискретнее и может «почувствовать» изменение напряжение на входе величиной всего около 1 милливольта (если быть точнее, то 1,2 мВ).
Есть нюанс, который может стать причиной ошибки измерения с помощью АПЦ. Ранее в примере мы рассматривали диапазон от 0 до 5 вольт в котором работает устройство. Однако в общем случае этот диапазон выглядит иначе:
от 0 до опорного напряжения
Это изменение повлечет за собой изменение формулы расчета точности АЦП:
точность = опорное напряжение / 4096
Опорное напряжение определяет границу диапазона, с которым будет работать АЦП. В нашем примере опорное напряжение будет равно напряжению питания Raspberry Pi Pico, которое дал USB порт компьютера (5В). Но что будет, если запитать микроконтроллер от другого источника? Допустим есть четыре NiMh аккумулятора на 1.2 В каждый. В сумме при последовательном соединении они дадут 4.8 В, а если они будут немного разряжены, то и того меньше, например 4,2В. Точность измерения в этом случае будет равна 4.2 / 4096, иэто будет отличаться от случая 5 / 4096, что тоже следует учитывать. Также следует учитывать, что результат измерения значения напряжения не может превышать границы диапазона. Если мы выбираем в качестве опорного напряжения 3.3 Вольта, а поступающий сигнал будет с большим напряжением, то мы получим неправильное значение напряжения, поскольку АЦП «не знает» о наличии более высокого напряжения.
АЦП Raspberry Pi Pico.
Raspberry Pi Pico поддерживает четыре 12-битных аналого-цифровых преобразователя на основе последовательного приближения SAR (Successive-approximation) — это тип аналого-цифрового преобразователя, который преобразует непрерывный аналоговый сигнал в дискретное цифровое представление, используя двоичный поиск по всем возможным уровням квантования, прежде чем окончательно сойтись на цифровом выходе для каждого преобразования.
Из 4-х поддерживаемых микроконтроллером можно использовать только 3 аналоговых канала. 4-й аналоговый канал внутренне подключен к внутреннему датчику температуры микроконтроллера, благодаря чему можно измерить температуру, используя встроенный датчик и считывая аналоговое значение ADC4. В следующей таблице показано соответствие АЦП и разъёмов GPIO (входной сигнал для ADC0, ADC1 и ADC2 может быть подключен к контактам GP26, GP27 и GP28 соответственно).
Модуль АЦП | Разъём GPIO | Номер контакта |
ADC0 | GP26 | 31 |
ADC1 | GP27 | 32 |
ADC2 | GP28 | 34 |
Вы можете выполнять аналого-цифровое преобразование в режиме опроса, прерывания и FIFO в режиме DMA. Скорость преобразования АЦП на выборку составляет 2 мкс, то есть 500 kS/s (килосэмплов в секунду, тысяч отсчётов в секунду). Микроконтроллер RP2040 работает на тактовой частоте 48 МГц, которая поступает от USB PLL. Таким образом, его АЦП требует 96 тактов ЦП для выполнения одного преобразования. Следовательно, частота дискретизации (96 x 1 / 48MHz) = 2 мкс на выборку (500 kS/s, т.е. 500 000 отсчётов в секунду).
Пишем код для Raspberry Pi Pico
Для начала давайте запустим MicroPython на интегрированной среде разработки Thonny IDE (англ. Integrated development environment — IDE). У кого Thonny IDE и MicroPython уже установлены, переходите далее к 10-му шагу.
Ну а для тех, кто начинает с самого начала, давайте кратко опишем весь процесс.
Pi Pico может быть запрограммирован с использованием языков C / C++, Python, и других языков. Поскольку уровень сложности проектов на Pico достаточно различен и адаптируется к широкому спектру приложений (и соответственно уровней навыков пользователя), то разработчики отталкивались от минимального уровня подготовки пользователя, поэтому начать работу с Raspberry Pi Pico так же просто, как перетащить файл по экрану. Если вы работаете с языком C, рекомендуется использовать систему на основе Linux, например компьютер Raspberry Pi, поскольку легко загрузить SDK и написать программы на C в Linux.
Но в большинстве случаев из=за интуитивно понятного и простого синтаксиса рекомендуется использовать MicroPython для программирования Raspberry Pi Pico. MicroPython — это интерпретатор языка Python, разработанный для микроконтроллеров и встраиваемых систем. Синтаксис MicroPython очень похож на Python. Итак, если вы работали с Python, то работать с MicroPython будет совсем просто.
Чтобы запрограммировать Raspberry Pi Pico с помощью Micropython, вы можете использовать:
1. Thonny IDE
2. IDE uPyCraft
Но прежде чем начать работу с Raspberry Pi Pico, вам необходимо установить MicroPython на плату Raspberry Pi Pico. Для этого необходимо:
1. Нажать и удерживать кнопку BOOTSEL на Pico, а затем немедленно подключить плату Pico к компьютеру с помощью кабеля micro USB. Затем отпустить BOOTSEL, как только имонка диска RPI-RP2 появится на вашем компьютере.
2. Откройте диск RPI-RP2, который отображается на вкладке «Диски».
3. Посетите страницу официальной документации Raspberry Pi Pico по этой ссылке: Документация Raspberry Pi.
4. Загрузите файл MicroPython UF2 со вкладки MicroPython.
5. Перетащите файл UF2 на диск RPI-RP2. Raspberry Pi Pico с RP перезагрузится и теперь будет работать с MicroPython.
Для начала работы с Raspberry Pi Pico с использованием MicroPython в Thonny IDE необходимо проделать ещё несколько простых действий:
6. Первым делом необходимо скачать Thonny с ресурса https://thonny.org/
7. Подключите Raspberry Pi Pico к компьютеру. Затем из Thonny перейдите в Инструменты > Параметры (Tools > Options) и щелкните вкладку Интерпретатор (Interpreter). В раскрывающемся списке интерпретатора выберите MicroPython (Raspberry Pi Pico). Раскрывающееся меню порта можно оставить для автоматического определения Pico. Щелкните ОК, чтобы закрыть.
8. Когда вы подключите плату Raspberry Pi Pico, откроется вкладка установки прошивки для raspberry pi pico. Нажмите «Установить», и будут загружены некоторые необходимые файлы.
9. После успешной установки версия MicroPython и плата Raspberry появятся в оболочке Python. Для проверки мы можем написать функцию быстрого вывода классической фразы «Hello World». Нажмите Enter, чтобы запустить код. В ответ вы получите Hello World.
10. Теперь давайте узнаем, как использовать АЦП Raspberry Pi Pico.
Мы будем использовать потенциометр с сопротивлением 10 кОм для изменения входного аналогового напряжения. Мы сопоставим аналоговое напряжение от 0 до 3,3 В с 12-битным или 16-битным АЦП. Схема подключения потенциометра:
Подключите контакт 1 и контакт 3 потенциометра к контакту 3,3 В (GP36) и контакту GND (GP38) Raspberry Pi Pico соответственно. Подключите контакт 2 потенциометра к GP28 (ADC2) Raspberry Pie Pico.
Пришло время написать код и проверить аналоговое считывание. Для этого вы можете использовать Thonny IDE или uPyCraft IDE.
Скопируйте этот код и нажмите кнопку «Загрузить и запустить».
В этой части кода мы определяем вход АЦП, подключенный к выводу 28 (.ADC(28)). Затем, чтобы создать бесконечный цикл, мы делаем while true, а затем я считываем значение АЦП с помощью функции чтения read_u16(). Затем, используя оператор print, мы печатаем значение в консоли (shell monitor).
Во время вращения потенциометра, значение изменяется от 0 до 65536, и это странно, потому что значение должно изменяться от 0 до 4096. Это происходит потому что программно значения 12-битного АЦП масштабируются до 16-битных значений, а 16-битность удобна, потому что другие системы MicroPython возвращают 16-битное значение для АЦП независимо от того, сколько бит на самом деле имеет АЦП. Просто имейте это ввиду. На официальном форуме raspberrypi.org/forums можно подробнее изучить этот феномен.
В следующем видео показана реализация данного примера (тайминг начиная с 8:56).