Источники питания Keen Side

Нужен дополнительный АЦП? Добавьте его за несколько центов

Arduino Arduino Nano

,

При проектировании устройств с микроконтроллерами мне нравится вместе со всеми необходимыми сигналами датчиков использовать некоторые входы аналого-цифрового преобразователя (АЦП) для измерения напряжений питания на печатной плате. Это означает, что мне часто не хватает входов АЦП. Итак, здесь представлен способ добавления дополнительных АЦП, не требующий использования внешних микросхем, стоимостью менее 5 центов и занимающий ничтожно мало места на печатной плате!

В используемом микроконтроллере есть две вещи: выход широтно-импульсного модулятора (ШИМ) и встроенный аналоговый компаратор. Некоторые линейки микроконтроллеров, в которых они есть, – это микроконтроллеры PIC, AVR и ATmega компании Microchip. Линейки Piccolo от TI и STM32L5 от STMicroelectronics также имеют одновременно и ШИМ, и компаратор.

Итак, давайте посмотрим, как это устроено.

Основная концепция

На Рисунке 1 представлена схема, показывающая добавление резистора и конденсатора в проект на микроконтроллере.

Основная концепция схемы, в которой для создания АЦП используется микроконтроллер со встроенным ШИМ и компаратором, а также RC-фильтр.
Рисунок 1. Основная концепция схемы, в которой для создания АЦП
используется микроконтроллер со встроенным ШИМ и
компаратором, а также RC-фильтр.

Резистор и конденсатор образуют однополюсный фильтр нижних частот. Таким образом, концепция схемы основана на использовании выходных импульсов встроенного ШИМ и фильтрации их для получения сигнала постоянного тока, который задается коэффициентом заполнения ШИМ. Затем это постоянное напряжение сравнивается с входным сигналом с помощью встроенного компаратора. Схема очень проста, поэтому давайте поговорим о программном коде, используемом для создания АЦП на основе этой схемы.

Чтобы получить значение входного сигнала, мы начнем с установки ШИМ на 50%-ный коэффициент заполнения. Эти симметричные прямоугольные импульсы ШИМ будут отфильтрованы RC-фильтром нижних частот, чтобы получить напряжение, равное ½ системного напряжения микроконтроллера. На выходе компаратора будет высокий уровень (или цифровая «1»), если отфильтрованное постоянное напряжение больше, чем мгновенное напряжение входного сигнала; в противном случае на выходе компаратора будет низкий уровень (цифровой «0»).

Теперь программа будет считывать состояние выхода компаратора и выполнять поиск, чтобы найти новый уровень, при котором выход компаратора примет противоположное состояние. Другими словами, если на выходе компаратора «0», программа будет корректировать коэффициент заполнения ШИМ до тех пор, пока компаратор не выдаст «1». Если компаратор в данный момент показывает «1», коэффициент заполнения ШИМ будет уменьшаться до тех пор, пока компаратор не выдаст «0». Если разрешение ШИМ поддерживает что-то вроде 256 шагов коэффициента заполнения (или больше), этот поиск может занять значительное время. Чтобы смягчить проблему, мы будем выполнять двоичный поиск, поэтому если число шагов ШИМ равно 256, для проверки уровней потребуется log2(256), или 8 шагов.

Краткое описание двоичного поиска заключается в том, что после первого считывания 50-поцентного уровня, следующим шагом будет проверка уровня 25% или 75%, в зависимости от состояния выхода компаратора. На следующих шагах будут снова проверяться середины оставшихся уровней.

Пример работы схемы

Давайте рассмотрим простой пример, предполагая следующее:

  • Системное напряжение: 5 В.
  • Число доступных уровней ШИМ: 256.
  • Мгновенный уровень входного сигнала: 1 В.

Первый тест будет выполнен с коэффициентом заполнения ШИМ примерно 50% (уставка 128), создающим сигнал 2.50 В, который подается на неинвертирующий вход компаратора. Это означает, что компаратор выдаст высокий уровень, показывающий, что коэффициент заполнения ШИМ слишком высок. Поэтому мы уменьшим коэффициент заполнения вдвое, установив значение 64, что даст на неинвертирующем входе напряжение 1.25 В. Компаратор снова выдаст «1»… слишком много, поэтому мы опять уменьшим коэффициент заполнения ШИМ в два раза до 32. Это даст 0.625 В на неинвертирующем входе. Теперь компаратор покажет «0», так что мы знаем, что уровень слишком низкий, и увеличиваем коэффициент заполнения ШИМ. Мы знаем, что 64 было слишком высоко, а 32 – слишком низко, поэтому переходим к среднему, или (64 + 32)/2 = 48, что дает 0.9375 В. Мы все еще слишком низко, поэтому, разделив разность между 64 и 48, мы получаем 56, или около 1.094 В… слишком много. Продолжаем с (56 + 48)/2 = 52 и получаем 1.016 В… слишком много. Опять же, с уставкой ШИМ (52 + 48)/2 = 50, получаем 0.9766 В. Последний шаг, (52 + 50)/2 = 51, дает 0.9961 В.

Это заняло 8 шагов и позволило нам максимально приблизиться к ответу. Итак, наш АЦП вернет ответ, что мгновенное напряжение входного сигнала составляет 0.9961 В.

Пример схемы с Arduino Nano

Давайте рассмотрим реальный пример. В нем используется Arduino Nano с микроконтроллером ATmega328P, который имеет несколько выходов ШИМ и один аналоговый компаратор. ШИМ, который мы будем использовать, может тактироваться различной частотой, и мы хотим, чтобы эта частота была выше, так как это облегчит фильтрацию. Это также уменьшит время установления конечного уровня выходного сигнала фильтра. Мы выберем тактовую частоту ШИМ около 31.4 кГц. На Рисунке 2 показана схема с однополюсным RC-фильтром нижних частот.

Пример схемы с использованием Arduino Nano и однополюсного RC-фильтра нижних частот.
Рисунок 2. Пример схемы с использованием Arduino Nano и однополюсного
RC-фильтра нижних частот.

В этой схеме вывод D11 – это выход ШИМ, D6 – неинвертирующий вход компаратора, а D7 – инвертирующий вход компаратора. Фильтр состоит из резистора 20 кОм и конденсатора 0.1 мкФ. Я пришел к этим значениям, экспериментируя с моделированием в LTspice, чтобы попытаться минимизировать остаточные импульсы ШИМ (пульсации), сохраняя при этом достаточно малое время установления. Целью для уровня пульсаций было разрешение изменения ШИМ на 1 бит или меньше. При напряжении питания системы 5 В и при 8-битной ШИМ (256 состояний) мы получаем разрешение 5 В/256 ≈ 20 мВ. Моделирование в LTspice показало пульсации 18 мВ, в то время как постоянное выходное напряжение устанавливалось в пределы нескольких милливольт от своего конечного значения за 15 мс. Поэтому при написании кода в качестве задержки между выборками я использовал 15 мс (с небольшим дополнением, которое вы увидите ниже). Поскольку для получения конечного полезного результата требуется 8 измерений, это займет 8 × 15 мс = 120 мс или 8.3 выборки в секунду. Как отмечалось в начале, вы не будете делать выборки звуковых частот, но, безусловно, сможете контролировать постоянное напряжение на плате или медленно изменяющиеся аналоговые сигналы.

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

Пример программного кода

В разделе Загрузки находится ссылка на листинг программы для использования в интегрированной среде разработки Arduino. Программа считывает входной сигнал, выполняет двоичный поиск, преобразует код в напряжение, а затем отображает конечное 8-битное значение АЦП, соответствующее значение напряжения и более медленно изменяющееся отфильтрованное значение.

Ниже приведено более подробное описание кода:

  • Строки 1-8 определяют вывод, который мы используем для ШИМ, и объявляют наши переменные. Обратите внимание, что в строке 3 задается напряжение системы. Его значение следует измерять на выводе питания вашего микроконтроллера.
  • Строки 11 и 12 устанавливают требуемую частоту ШИМ.
  • Строки 15 и 16 настраивают используемый внутренний компаратор.
  • Строка 18 инициализирует последовательный порт, в который мы будем выводить результаты.
  • Со строки 22 начинается основной код. Сначала мы инициализируем некоторые переменные каждый раз перед началом двоичного поиска.
  • В строке 29 мы начинаем 8-шаговый двоичный поиск, а строка 30 устанавливает коэффициент заполнения ШИМ. Затем вводится задержка в 15 миллисекунд, чтобы позволить установиться фильтру нижних частот.
  • Строка 34 – это «небольшое дополнение», о котором говорилось выше. Здесь вводится вторая, случайная задержка от 0 до 31 микросекунды. Это сделано в связи с тем, что присутствующие после фильтра пульсации ШИМ коррелируют с тактовым генератором 16 МГц микроконтроллера, поэтому, чтобы помочь отфильтровать их из конечного показания, мы вводим эту задержку, исключающую корреляцию.
  • Строки 37 и 38 проверят состояние компаратора после реализации задержки. В зависимости от результата сравнения изменяется диапазон для следующего коэффициента заполнения ШИМ.
  • Строка 40 вычисляет новый коэффициент заполнения ШИМ в этом новом диапазоне. Затем код повторяется 8 раз для завершения двоичного поиска.
  • Строки 43 и 44 вычисляют текущее значение мгновенного напряжения, а также значение отфильтрованного среднего напряжения. Это усреднение выполняется с использованием очень простого БИХ-фильтра (фильтра с бесконечной импульсной характеристикой).
  • Строки 46-51 отправляют информацию в монитор последовательного порта Arduino для отображения.

Результаты теста

Первым шагом было измерение напряжения системы на выводе +5V Arduino Nano. Это значение (4.766 В) было введено в строку 3 кода. Затем я запустил код на Arduino Nano V3 и отслеживал выходные данные на мониторе последовательного порта Arduino. Для проверки кода и системы сначала я подключил к входу сигнала опорное напряжение 2.5 В. После прогрева это напряжение было измерено калиброванным 5½-разрядным цифровым мультиметром. Измеренное значение опорного напряжения составило 2.5001 В. Последовательный монитор показал мгновенное напряжение, изменяющееся от 2.5232 до 2.4858 В, а среднее напряжение варьировалось от 2.5061 до 2.5074 В. Таким образом, погрешность составила около 0.9% в измерениях мгновенного напряжения и около 0.3% в измерениях усредненного напряжения. Это показывает, что мы получаем результаты с погрешностью около ±1 LSB для мгновенных значений напряжения и около ±0.4 LSB для отфильтрованных. При подаче различных других напряжений я получил сопоставимую точность.

Я также протестировал схему при входном напряжении, равном напряжению питания (4.766 В), и увидел результат 4.7473 В, означающий, что он может работать с входными напряжениями, очень близкими к верхней шине питания. При заземленном входе были показаны значения мгновенного и отфильтрованного напряжения 0.000 В.

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

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

Загрузки

  1. Листинг программы для использования в интегрированной среде разработки Arduino

Материалы по теме

  1. Datasheet Arduino Arduino Nano

EDN

Перевод: AlexAAN по заказу РадиоЛоцман

На английском языке: Need an extra ADC? Add one for a few cents

T-electron
Россия и страны СНГ
DKNANO.ARDUINONANO79 767 ₽
ТМ Электроникс. Электронные компоненты и приборы. Скидки, кэшбэк и бесплатная доставка
Для комментирования материалов с сайта и получения полного доступа к нашему форуму Вам необходимо зарегистрироваться.
Имя