Пролог
Это текст про то, что программистам микроконтроллеров оказывается нужно уметь вычислять математические пределы! Кто бы мог подумать на первом курсе, что это вообще может пригодится?
В очередной тестировочной электронной плате появилась нужда эмитировать аналоговые датчики на проводах. Как водится, из-за Санкций и Эмбарго теперь нельзя просто взять и купить микросхему ASIC DAC с SPI управлением (типа AD5641)+ операционный усилитель ADC4700.
Поэтому было принято решение сделать DAC на основе PWM и RC цепочки.
Существует очень остроумный способ собрать DAC используя PWM сигнал и RC цепочку. На выходе будет аналоговый сигнал. Причем уровнем этого напряжения можно управлять цифровым образом из firmware меняя параметры PWM модуляции: заполнение и частоту.
Постановка задачи
Дана вот такая электрическая цепь.
Дано:
№ | Константа | Обозначение | единицы измерения |
1 | Сопротивление | R1 | Омы |
2 | Сопротивление | R2 | Омы |
3 | Ёмкость | C | Фарады |
4 | Амплитуда PWM сигнала | A | Вольты |
5 | Желаемое напряжение | Uout | Вольты |
Требуется найти такие параметры PWM сигнала при которых на выходе RC фильтра установится желаемое напряжение Uout. То есть надо найти
№ | Переменная | Обозначение | единицы измерения |
1 | Частоту PWM | F_pwm | Герцы |
2 | Период PWM | T | секунды |
5 | скважность импульсов PWM | Q=T/tau | -- |
3 | длительность импульса PWM к периоду | D=100*tau/T | Проценты |
4 | длительность импульса PWM | tau | секунды |
Получается, что надо, не много не мало, спроектировать псевдо DAC при помощи всего лишь PWM и RC фильтра нижних частот.
Решение
Сначала порассуждаем качественно, на пальцах. Понятное дело, что если длительность импульса PWM тау равна периоду tay=T, то PWM вырождается в постоянное напряжение и на выходе напряжение максимальное. При tau=0 напряжение на выходе, очевидно, равно нулю. Выходное напряжение определённо зависит от длительности импульса.
Глядя на переходной процесс, RC фильтр нижних частот вначале выступает как интегратор.
Однако тут же возникают некоторые вопросы:
1-- Вот у меня схемотехника с R и C. Какую выбрать частоту для PWM?
2--Зависит ли частота PWM от R и С?(спойлер: Частота PWM должна быть много больше чем частота среза ФНЧ)
3--Зависимость выходного напряжения от длительности импульса линейная? (спойлер: да)
4--Что вообще надо менять для регулирования напряжения на выходе: частоту или скважность PWM сигнала?(спойлер: скважность)
Что мы вообще хотим? По сути, мы хотим из PWM получить постоянное напряжение. Только и всего. Что такое PWM? Это постоянное напряжение смещения + какие-то высокочастотные гармоники.
Получается, надо из PWM отбросить все ненулевые гармоники. Вот так! А самая низкочастотная гармоника PWM это 1/T, где T- период PWM.
Эти нехитрые рассуждения привели к выводу, что частота среза RC фильтра должна быть меньше, чем самая низкая положительная частота PWM (1/T). Или частота PWM должна быть много больше чем частота среза ФНЧ. При этом частота среза RC фильтра должна быть больше нуля. Нулевую гармонику мы же хотим оставить и вывести на улицу. На этом этапе у нас появился ответ на второй вопрос. Да, частота PWM зависит от схемотехники и должна быть больше частоты среза RC фильтра первого порядка. Но вот только во сколько раз больше?
АЧХ такого RC-R фильтра мне не охотно сейчас выводить аналитической 4-этажной формулой. Можно легче обсчитать вот этим Python скриптом. Скрипт составлен исходя из того, что RC фильтр - это просто делитель напряжения с реактивным компонентом, чьё сопротивление зависит от частоты. Только и всего. Скрипт составлен исходя из второго закона Кирхгофа для изображенной выше электрической цепи
import matplotlib.pyplot as plt
import math
import numpy as np
Uin_v=3.3
R_79 = 39000 #To MCU
R_73 = 39000 #GND
C_26 = 1*(10**(-6))
f_end_hz = 600
f_step_hz = 0.1
f_hz = np.arange(0.00001, f_end_hz, f_step_hz)
omega_rad = 2math.pif_hz
Xc=1.0/(omega_radC_26)
R_gnd=(R_73Xc)/(R_73+Xc)
R_total = R_79+R_gnd
I_f=Uin_v/R_total
Uout_v = I_f*R_gnd
Frequency_response=Uout_v/Uin_v
plt.plot(f_hz, Uout_v, label="Uout")
#plt.plot(f_hz, Frequency_response, label="Uout")
plt.title('RCR filter Frequency response')
plt.xlabel('Freq,[Hz]')
plt.ylabel('Uout,Volts')
plt.grid()
#plt.xticks(rotation=-90)
plt.show()
В частности у меня на PCB получается вот такая AЧХ.
В принципе для частоты PWM можно выбрать себе 20kHz и отдыхать.
Теперь надо понять по какому закону меняется амплитуда нулевой гармоники PWM в зависимости от продолжительности импульса tau. Чтобы ответить на этот вопрос надо прибегнуть к цифровой обработке сигналов и вспомнить как выглядит спектр PWM сигнала.
Если посчитать график спектра по определению, то получится вот такая АЧХ.
Можно заметить, что чем уже импульс PWM тем шире его спектр. Тем шире импульс PWM тем уже его спектр.
Допустим мы взяли осциллограф и записали в память ровно один период PWM сигнала с импульсом по центру. Если мы вычисли преобразование Фурье от этого импульса, то получим функцию (1)
Чтобы понять вычисления этого интеграла надо вспомнить, что sin(x) в комплексном виде это (3), а экспонента не меняет вида при интегрировании (4)
Спектр периодической последовательности прямоугольных импульсов представляет собой множество гармоник с огибающей вида (1)
Нас интересует значение на нулевой частоте. Поэтому вычислим предел спектра PWM сигнала при частоте стремящейся к нулю. Тут возникает неопределённость вида 0/0. Как же быть? Для раскрытия неопределённости воспользуемся теоремой Лопиталя (предел дроби равен пределу производных в числителе и знаменателе). Тут это правило применимо.
Амплитуду "А" мы варьировать не можем, так как это цифровой пин GPIO, который может быть либо 0V либо 3.3V. Как видно, амплитуда нулевой гармоники S(0) линейно зависит от ширины импульса PWM сигнала. Вот мы и получили ответ на вопрос [3]. Да, выходное напряжение зависит от длительности импульса линейно. Это хорошая новость! Как, впрочем, и от частоты PWM тоже есть линейная зависимость. Однако тут появляется контр-интуитивное явление. Неужели можно увеличивать напряжение на выходе ФНЧ фильтра до бесконечности просто увеличивая частоту PWM? А вот и нет! Дело в том, что увеличивая частоту у вас будет уменьшаться период T (6). А длительность импульса tau ограничена сверху длительностью периода T (5).
Так что у нас в распоряжении для управления напряжением на выходе S(0) только длительность импульса tau (заполнение).
Как известно, MCU может выдавать напряжение от 0 до 3.3 В. Как же быть, если надо выставлять напряжения в более высоком диапазоне? Ответ тоже прост. Над сделать так, чтобы RC фильтр управлял резистором переменного сопротивления в высоковольтном делителе напряжения 1.
В качества резистора переменного сопротивления может выступать биполярный N-P-N транзистор BC847B. Захотев увеличить диапазон регулируемых напряжений, мы получили обратную пропорциональность между PWM заполнением tau и напряжением на выходе Vext.
Заполнение PWM | V_ext |
0 | Vin |
100 | 0 |
Не удобно? Да... Что ж, это расплата за дешевизну электрической цепи. В электронике так всегда. Закон сохранения сложности. Сделай проще схемотехнику, будет сложнее софт. Сделай проще софт, будет сложнее схемотехника.
Практическая часть
Теперь настало время выполнить решающий эксперимент. Проверить все эти эфемерные расчеты на реальном агрегате.
Установка низких напряжений
Если просто измерять напряжение на холостом ходу на выходе RC фильтра то получится вот такие значения напряжения.
Вот такой получился график. Как видно график получился линейный. Значит теория и практика совпадает. Успех!
Установка высоких напряжений
А теперь проверим как обстоят дела с установкой высоких напряжений. Тут мы, по сути, регулируем сопротивление GND-резистора в делителе напряжений. Сопротивление коллектор-эмиттер биполярного NPN не совсем понято, как зависит от приложенного напряжения на базе.
Для ясности я снял график зависимости напряжения на выходе делителя напряжения №1 от скважности и получил что-то похожее на арктангенс y=arctg(x). При этом образовался очень узкий рабочий диапазон эффективных скважностей, чтобы регулировать напряжение на выходе. Вот этот график построен при частоте PWM 20kHz
Результаты экспериментальных данных собраны вот в этом реестре: https://docs.google.com/spreadsheets/d/1-kPMUlmZBTUzocDJKJ00UnIG2HoR3Je3D6RODO36Ik4/edit?gid=0#gid=0
Однако есть хорошая новость. График монотонный (всюду убывает). Это значит, можно воспользоваться численными методами подбора нужной скважности. Одним из таких методов является PID регулятор.
Я добавил PID регулятор, чтобы по разности между желанным напряжением и измеренным напряжением устанавливать скважность PWM сигнала. При этом работает только интегральный контур PID регулятора. Коэффициенты P и D просто обнулены.
Таким образом, со временам скважность PWM сама подстраивается под нужное напряжение. И так для каждого из 4х каналов.
Получилось.
Что можно улучшить?
1--Попробовать использовать не PWM а BAM модуляцию. Вероятно это позволит уменьшить мерцания сигнала на низких частотах.
2--Собрать всю аналоговую схему в ASIC исполнении. Это уменьшить площадь PCB.
Достоинства PWM-DAC
1++Это дёшево. Всё что нужно это резисторы, конденсаторы и один транзистор.
Недостатки PWM-DAC
1--При недостаточной частоте PWM возникают пульсации напряжения на выходе.
2--Если повысить частоту PWM то появляется высокая инерционность. Длинный переходной процесс установки желаемого напряжения.
3--Если управлять высоковольтным делителем напряжения, то получается очень узкий диапазон возможных скважностей, чтобы регулировать напряжение на выходе.
4--Если конденсатор высокой ёмкости то будет очень длинный процесс установки напряжения. Опять высокая инерционность.
Итоги
Как видите, чтобы понять и собрать такую простецкую с аппаратной точки зрения вещь как PWM-DAC пришлось вспомнить ЦОС, интегралы, комплексные числа, тригонометрию, пределы, правило Лопиталя, преобразование Фурье, ТАУ, делители напряжения, законы Кирхгофа, RC фильтры и прочее.
При этом всём PWM-DAC это паллиативное решение. Тут две проблемы: пульсации на выходе и высокая инерционность. Решаешь первую проблему возникает вторая. Решаешь вторую возникает первая.
Ставьте лучше ASIC DACи в тандеме с OAP.
Словарь
Чтобы понять эту тему надо уметь распознавать вот эти аббревиатуры.
Акроним | Расшифровка |
ШИМ | Широтно-Импульсная Модуляция |
ФНЧ | Фильтр нижних частот |
ТАУ | Теория автоматического управления |
BAM | Binary angle modulation |
ASIC | Application-specific integrated circuit |
HW | Hard Ware |
OAP | Operational Amplifier |
АЧХ | Амплитудно-частотная характеристика |
PWM | Pulse Width Modulation |
ЦОС | Цифровая обработка сигналов |
PCB | printed circuit board |
DAC | Digital-to-analog converter |
RC | resistor–capacitor circuit |
Вопросы:
--Почему напряжение в физике обозначают буквой U?
Ссылки
№ | Название | URL |
1 | Спектр периодической последовательности прямоугольных импульсов | https://ru.dsplib.org/content/fourier_series_pimp/fourier_series_pimp.html |
2 | Convert PWM To A DAC – Using PWM To Generate Analog Waveforms | https://deepbluembedded.com/convert-pwm-to-a-dac-using-pwm-to-generate-analog-waveforms/ |
6 | Методы настройки ПИД-регулятора | https://drives.ru/stati/nastrojka-pid-regulyatora/ |
3 | AVR. Учебный курс. Использование ШИМ | https://easyelectronics.ru/avr-uchebnyj-kurs-ispolzovanie-shim.html |
4 | Правило Лопиталя | https://ru.wikipedia.org/wiki/Правило_Лопиталя |
5 | Редактор формул | https://latex.codecogs.com/eqneditor/editor.php |