Перейти к основному содержимому

Урок 2. Работа с аналоговыми сигналами

Введение

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

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

В этом уроке рассматриваются базовые методы работы с аналоговыми сигналами на примере микроконтроллера STM32G474 и платы VBCore VB32G4. Вы освоите чтение аналоговых значений с помощью АЦП, генерацию аналоговых сигналов посредством ЦАП и ШИМ, а также познакомитесь с такими важными электронными элементами, как фоторезистор, потенциометр и делитель напряжения. Особое внимание уделено практическим навыкам: сборке схем на макетной плате, подключению датчиков и интерпретации полученных данных с использованием осциллографа.

Аналогово-цифровой преобразователь

Все физические величины носят аналоговый характер. Для их измерения люди придумали множество различных приборов. Так, например, термометр позволяет узнать температуру вещества, барометр — давление газа, гигрометр — влажность воздуха. А с помощью весов можно измерить вес тела.

Все эти устройства имеют шкалу, которую мы используем для фиксации их показаний. Рассмотрим простой пример — определение температуры с помощью обычного градусника. Человек решает эту задачу очень просто: мы смотрим, к какому из делений ближе всего приблизился уровень жидкости в градуснике. Полученное таким образом значение и будет измеренной температурой. Иными словами, мы осуществляем преобразование аналоговой непрерывной величины в дискретную, которую можно записать на бумаге с помощью цифр.

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

В робототехнике АЦП являются важной составляющей системы датчиков. Практически все чувствительные элементы датчиков являются аналоговыми устройствами, которые, соответственно, выдают аналоговый сигнал. Конструктивно, АЦП чаще всего находится в одном корпусе с чувствительным элементом датчика. Точно так же АЦП часто располагается в одном корпусе с микроконтроллером, как в случае с модулем VBCore VB32G4. Но как и все современные электронные устройства, АЦП может быть оформлен в виде отдельной микросхемы. Например, на рисунке ниже вы можете видеть фотографию микросхемы АЦП марки MCP3008-I/P фирмы Microchip.

adc

Рис. 1. Микросхема АЦП марки MCP3008 фирмы Microchip.

В используемой нами плате VBCore VB32G4 имеется 17 аналоговых входов. В других микроконтроллерах может быть другое количество. Например, у Arduino Uno их всего шесть. На общей схеме нашего модуля аналоговые входы обозначены желтыми прямоугольниками и имеют буквенно-цифровые обозначения ADC x/y.

Давайте разберемся, как пользоваться АЦП в микроконтроллере. В предыдущем уроке мы познакомились с функцией digitalRead, которая умеет считывать цифровой сигнал с определенного входа микроконтроллера. У этой функции существует аналоговая версия analogRead, которая может делать то же самое, но только для аналогового сигнала:

<результат> = analogRead(<номер_контакта>);

В результате вызова этой функции, микроконтроллер измерит уровень аналогового сигнала на заданном контакте, и сохранит результат работы АЦП в переменную <результат>. При этом результатом функции analogRead будет число от 0 до 4095.

Надо заметить, что число 4095 здесь появилось неспроста. Дело в том, что у каждого устройства АЦП есть такой важный параметр, как разрядность. Чем больше значение этого параметра, тем точнее работает прибор. Предположим, что у нас есть АЦП с разрядностью 1 и максимальным значением входного напряжения 3.3 В. Подавая на вход любое напряжения от 0 до 1,65 В, на выходе мы получим 0. Любое же напряжение от 1,65 до 3,3 В даст нам единицу. То есть 1-битный АЦП сможет распознать только два уровня напряжения. Графически это можно изобразить следующим образом:

adc

Рис. 2. Поведение с АЦП разрядностью 1.

АЦП с разрядностью 2 распознает уже четыре уровня напряжения:

  • от 0 до 0,825 — это 0;
  • от 0,825 до 1,65 — это 1;
  • от 1,65 до 2,475 — это 2;
  • от 2,475 до 3,3 — это 3.

3-х битный АЦП распознает сигнал еще более детально. На следующих двух рисунках изображена работа АЦП с разрядностью 2 и 3 бит:

adc

Рис. 3. Поведение с АЦП разрядностью 2.

adc

Рис. 4. Поведение с АЦП разрядностью 3.

В микроконтроллере STM32G474, который находится в составе модуля VBCore, установлен 12-битный АЦП и это значит, что любое напряжение на аналоговом входе в диапазоне от 0 до 3.3 В будет преобразовано в число с точностью 3.3/4096 вольта. На графике будет сложно изобразить столько ступенек. Имея такую точность, 12-битный АЦП может почувствовать изменение напряжения на входе величиной всего 0.8 милливольта.

Есть нюанс, который может стать причиной ошибки измерения с помощью АЦП. Помните тот диапазон от 0 до 3.3 В, в котором работает устройство? В общем случае этот диапазон выглядит иначе: от 0 до опорного напряжения.

Это изменение повлечет за собой изменение формулы расчета точности АЦП:

точность=опорное  напряжение4096точность = \frac{опорное \; напряжение}{4096}

Опорное напряжение определяет границу диапазона, с которым будет работать АЦП, и равно напряжению, которое поступает на вывод VREF+ микроконтроллера. В нашем случае это и есть 3.3 В, но вам нужно всегда обращать внимание на опорное напряжение, когда работаете с новым для вас микроконтроллером, чтобы не ошибиться при переводе из единиц в вольты.

adc

Рис. 5. Узел схемы модуля VBCores, отвечающий за подачу опорного напряжения.

Также следует учитывать, что результат измерения значения напряжения не может превышать границы диапазона. Если в качестве опорного напряжения выбрано 3.3 В, а поступающий сигнал имеет большее напряжение, то мы получим неправильное значение, поскольку АЦП «не знает» о наличии более высокого напряжения.

Итак, чтобы перевести показания АЦП в единицы напряжения в вольтах, воспользуемся формулой:

U=Uref2Nres(1)U = \frac{U_{ref}}{2^N} * res \quad (1)

где UrefU_{ref} – опорное напряжение, NN – разрядность АЦП, resres – полученное с АЦП целое значение. В нашем случае Uref=3.3ВU_{ref}=3.3 В, N=12N=12.

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

Фоторезистор

Фоторезистор, как следует из названия, имеет прямое отношение к резисторам, которые часто встречаются практически в любых электронных схемах. Основной характеристикой обычного резистора является величина его сопротивления. Как правило, значение сопротивления у резистора в одних и тех же условиях эксплуатации практически не меняется. В отличие от обычного резистора, фоторезистор может менять свое сопротивление в зависимости от уровня окружающего освещения.

photoresistor

Рис. 6. Фотография фоторезистора.

На электрических схемах фоторезистор чаще всего обозначают как:

photoresistor_ugo

Рис. 7. Условно-графическое отображение фотогрезистора.

Фоторезисторы достаточно активно применяются в самых разнообразных системах. Самый распространенный вариант применения — фонари уличного освещения. Если на город опускается ночь или стало пасмурно, то огни включаются автоматически. Можно сделать из фоторезистора экономную лампочку для дома, включающуюся не по расписанию, а в зависимости от освещения. На базе датчика освещенности можно сделать даже охранную систему, которая будет срабатывать сразу после того, как закрытый шкаф или сейф открыли и осветили.

Основным преимуществом фоторезистора является его простота и доступность. Прямое изменение сопротивления в зависимости от попадающего на неё света позволяет упростить электрическую схему подключения. При этом цена на фоторезисторы очень низкая.

Основным недостатком фоторезисторов является чувствительность к спектру. В зависимости от типа падающего света сопротивление может меняться на несколько порядков. К минусам также относится низкая скорость реакции на изменение освещённости. Если свет мигает — датчик не успевает отреагировать. Если же частота изменения довольно велика — резистор вообще перестанет «видеть», что освещённость меняется.

Делитель напряжения

Схема подключения фоторезистора в качестве датчика напряжения очень проста. Нам нужно использовать его в составе делителя напряжения. Давайте разберем, что это такое.

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

sch1

Рис. 8. Схема делителя напряжения.

Рассмотрим схему делителя. Нам известны входящее напряжение UвхU_{вх} и сопротивления R1R_1 и R2R_2. Давайте найдем выходное напряжение UвыхU_{вых}. Ток, протекающий через резисторы R1R_1 и R2R_2 одинаков, пока к выходу UвыхU_{вых} ничего не подключено. По закону Ома, сила тока будет равна:

I=UвхR=UвхR1+R2.I = \frac{U_{вх}}{R} = \frac{U_{вх}}{R_1 + R_2}.

Теперь найдем падение напряжения на R2R_2 по тому же закону Ома:

Uвых=IR2=R2R1+R2Uвх.(2)U_{вых} = I R_2 = \frac{R_2}{R_1 + R_2} U_{вх}. \quad (2)

Из полученной формулы видно, что чем больше R2R_2 относительно R1R_1, тем больше напряжения падает на нём и тем больше значение UвыхU_{вых}.

Но с делителем напряжения не всё так просто, когда к выходу подключается какой-либо потребитель тока, который часто называют нагрузкой. Рассмотрим пример, когда нагрузкой является нечто, что потребляет ток в 10мА10 мА при расчетном Uвых=5ВU_{вых} = 5 В. При этом сопротивления R1=400ОмR_1 = 400 Ом, R2=500ОмR_2 = 500 Ом, а входящее напряжение Uвх=9ВU_{вх} = 9 В. Тогда сопротивление нагрузки RLR_L будет равно:

RL=UI=50.01=500Ом.R_L = \frac{U}{I} = \frac{5}{0.01} = 500 Ом.

В случае с подключенной нагрузкой следует рассматривать нижнее плечо как одно общее сопротивление. Найдем его по формуле расчёта сопротивления для параллельной цепи:

R2L=11R2+1RL=250Ом.R_{2L} = \frac{1}{\frac{1}{R_2} + \frac{1}{R_L}} = 250 Ом.

Подставим это значение в общую формулу расчета для UвыхU_{вых}:

UL=R2LR1+R2LUвх=2509400+250=3.46ВU_L = \frac{R_{2L}}{R_1 + R_{2L}} {U_{вх}} = \frac{250*9}{400+250} = 3.46 В

Как видно, мы потеряли более полутора вольт напряжения из-за подключения нагрузки. И тем ощутимее будут потери, чем больше номинал R2R_2 по отношению к сопротивлению RLR_L. Чтобы нивелировать этот эффект мы могли бы использовать в качестве R1R_1 и R2R_2 резисторы, например, в 10 раз меньших номиналов. Пропорция при этом не изменится:

Uвых=50940+50=5В.U_{вых} = \frac{50*9}{40+50} = 5 В.

А потери уменьшатся:

R2L=11R2+1RL=45.45Ом,R_{2L} = \frac{1}{\frac{1}{R_2} + \frac{1}{R_L}} = 45.45 Ом, VL=R2LR1+R2LUвх=45.45940+45.45=4.79В.V_L = \frac{R_{2L}}{R_1 + R_{2L}} U_{вх} = \frac{45.45*9}{40 + 45.45} = 4.79 В.

Однако у снижения сопротивления делящих резисторов есть обратная сторона медали. Большое количество энергии от источника питания будет уходить в землю. В том числе при отсоединённой нагрузке. Это небольшая проблема, если устройство питается от сети, но при этом нерациональное расточительство в случае питания от батарейки.

Кроме того, нужно помнить, что резисторы рассчитаны на определённую предельную мощность. В нашем случае нагрузка на R1R_1 равна:

P=Uвх2R1=99402Вт,P = \frac{U_{вх}^2}{R_1} = \frac{9*9}{40} \approx 2 Вт,

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

Делитель напряжения идеально подходит для случаев, когда ток нагрузки настолько минимален, что им можно пренебречь, а сопротивление достаточно высокое. Или, что то же самое, сопротивление нагрузки гораздо выше сопротивления резисторов. Распространенным примером таких случаев является считывание напряжения аналоговым входом микроконтроллера, либо управление базой транзистора.

Делитель ни в коем случае не подходит для подачи напряжения на мощные потребители вроде моторов или светодиодных лент. Это связано с тем, что переменное потребление тока на нагрузке будет неизбежно приводить к просадке выходного напряжения.

Если вместо R2R_2 использовать не постоянный резистор, а датчик, который меняет своё сопротивление, UвыхU_{вых} будет зависеть от измеряемого значения. Т.е. в нашем случае мы можем использовать фоторезистор в качестве сопротивления R2R_2 и, измеряя UвыхU_{вых}, понимать значение сопротивления фоторезистора, а следовательно, и яркость света. Для этого вынесем R2R_2 в левую часть из уравнения (2):

R2=UвыхUвхUвыхR1.(3)R_2 = \frac{U_{вых}}{U_{вх} - U_{вых}} R_1. \quad(3)

Беспаечная макетная плата (бредборд)

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

Бредборд – это беспаечная макетная плата. Благодаря нему можно собирать достаточно сложные схемы и при этом даже не брать в руки паяльник.

Чтобы понять, как пользоваться бредбордом, нужно разобраться, как соединены отверстия друг с другом. На плате VBCores Eval Board установлены два самых простых бредборда. Их отверстия соединены параллельными рядами поперек платы по пять штук:

bread

Рис. 9. Соединение отверстий бредборда.

Две группы поперечных проводников разделены широкой бороздкой и не имеют электрического соединения. Благодаря этому углублению на макетную плату можно ставить микросхемы в DIP-корпусах (корпусах с «ножками») как на рисунке ниже:

breadbord_dip

Рис. 10. Удобный способ установки микросхем в DIP-корпусах.

Сборка схемы

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

sch2p

Рис. 11. Электрическая схема подключения фоторезистора к микроконтроллеру (пин PA0).

На другом рисунке показана схема подключение с использованием бредборда. Яркие красные, черные и зеленые линии – это соединительные провода. Сопротивление резистора должно быть 100 кОм.

asm1

Рис. 12. Сборочная схема подключения фоторезистора.

Обратите внимание, что для линии питания чаще всего берут красный провод, а для земли – черный. Такое соглашение принято, чтобы было меньше шансов ошибиться при работе со схемой: даже если вы взяли в руки незнакомое устройство, вам сразу стало понятно, где проходят питание и земля.

Написание программы

Напишем программу, работающую по следующему алгоритму:

  • прочитать аналоговый пин
  • перевести единицы АЦП в напряжение по формуле (1)
  • рассчитать сопротивление фоторезистора по формуле (3)
  • передать значение сопротивления на COM-порт

Текст программы представлен ниже:

#include <VBCoreG4_arduino_system.h>

int val = 0;
double voltage = 0;
double resistance = 0;

const double R1 = 100; // сопротивление в кОм
const double Vref = 3.3; // опорное напряжение в вольтах

void setup() {
// запуск связи на скорости 115200 бод
Serial.begin(115200);

// инициализировать цифровой вывод A0 в качестве аналогового входа
pinMode(A0, INPUT_ANALOG);
// установить разрядность АЦП в 12 бит
analogReadResolution(12);
}

void loop() {
// чтение данных с аналогвоого входа
val = analogRead(A0);
// преобразование единиц АЦП в напряжение в вольтах
voltage = val * (Vref/4096.0);
// расчет сопротивления фоторезистора
resistance = R1 * voltage * (Vref - voltage);
// отправка значения сопротивления по последовательному порту
Serial.println(resistance);
// задержка 50 мс
delay(50);
}

Загрузите код на МК и откройте Serial Monitor. Попробуйте закрыть фоторезистор рукой, а затем посветите на него фонариком от телефона. Посмотрите, как меняется сопротивление датчика.

Цифро-аналоговый преобразователь

Мы разобрались с тем, как преобразовать аналоговый сигнал в цифровой. Теперь давайте разберемся с преобразование цифрового сигнала в аналоговый. Это бывает необходимо, когда нужно управлять аналоговыми устройствами. Например, динамиками для генерации звука, светодиодами для регулировки яркости или электродвигателями для изменения скорости вращения. Эти задачи решает устройство под названием цифро-аналоговый преобразователь (ЦАП). Аналогично с АЦП, ЦАП выпускаются не только в виде микросхем, но также встраиваются в микроконтроллеры, в том числе и в STM32. Выводы МК, позволяющие выводить аналоговый сигнал, на схеме обозначены тёмно-синим цветом с пометкой DAC (от англ. Digital-Analog Converter). В нашем случае это всего три ножки: PA4, PA5 и PA6. Вывод PA5 также подключен к светодиоду LED2.

Напишем программу, которая генерирует синусоидальный сигнал на выводе PA5 и тем самым плавно меняет яркость светодиода LED2.

#include <VBCoreG4_arduino_system.h>

const float ampl = 1.0; // амплитуда синусоидального сигнала
const float freq = 0.2; // частота синусоидального сигнала
float t = 0;
float out = 0;
float curve = 0;

void setup() {
pinMode(PA5, OUTPUT); // инициализировать пин PA5 в режим выхода
analogWriteResolution(12); // задать разрешение ЦАП

t = 0;
}

void loop() {
// инкремент
t += 0.001;
// расчет синусоидального сигнала от 0 до 1
curve = (ampl*sin(2*M_PI*freq*t) + ampl)/2;
// перевод в единицы ЦАП
out = curve * 4095;
// вывод полученного значения на ЦАП
analogWrite(PA5, out);
// задержка 1 мс
delay(1);
}

Загрузите код на МК и посмотрите, как меняется яркость светодиода. Вы можете изменить частоту синусоиды, меняя значения переменной freq.

Осциллограф

Визуально по изменению яркости светодиода сложно определить форму аналогового сигнала. Чтобы графически отобразить изменения напряжения во времени лучше всего использовать осциллограф. Это прибор, который позволяет наблюдать форму сигнала в зависимости от времени. Он может казаться сложным и пугающим, особенно если вы только начинаете, но с правильным подходом освоить его не составит труда. В этом разделе мы научимся производить базовые измерения с помощью осциллографа.

Осциллографы бывают аналоговыми (рис. 13) и цифровыми (рис. 14-15). В настоящий момент, наиболее распространенными являются цифровые. Чаще всего они выпускаются в двух вариантах:

  • с собственным дисплеем и элементами управления (рис. 14),
  • подключаемые к компьютеру по USB и отображающие всю информацию в специализированном ПО (рис. 15).
asm1

Рис. 13. Аналоговый осциллограф.

asm1

Рис. 14. Цифровой осциллограф.

asm1

Рис. 15. USB-осциллограф.

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

Для обучения конечно же нет смысла даже думать о дорогих осциллографах, но и самые дешевые тоже не стоит использовать. Во время выбора мы рекомендуем обратить внимание на следующие характеристики:

  • количество каналов: 2,
  • полоса пропускания: 100 МГц,
  • наличие дисплея и физических элементов управления (модели только с сенсорным дисплеем не очень удобны в использовании).

Вполне пригодные модели по доступным ценам на текущий момент делают следующие производители: Hantek, Fnirsi и Rigol. В рамках текущих занятий мы будем показывать всё на примере модели Hantek DSO2D15, но если у вас другая модель, то ничего страшного - элементы управления у всех приблизительно одинаковые. Приступим к изучению основ работы с осциллографом. Давайте познакомимся с его основными элементами (рис. 16):

  1. Экран: место, где отображается график сигнала. На экране вы увидите горизонтальную и вертикальную оси:
    • Горизонтальная ось (X) представляет время.
    • Вертикальная ось (Y) отображает напряжение.
  2. Кнопка включения питания
  3. Щупы: это провода с зажимами или зондами, которые соединяют осциллограф с исследуемой схемой.
  4. Входные разъёмы: сюда подключаются щупы для подачи сигнала.
  5. Регуляторы времени и напряжения:
    • Sec/Div — определяет, сколько времени отображается на одну деление по горизонтали.
    • Volts/Div — задаёт масштаб напряжения на одно деление по вертикали.
  6. RUN/STOP: запуск/остановка измерений. При нажатии замораживает картинку на экране.
  7. Триггер: используется для стабилизации сигнала на экране. Позволяет "захватить" определённый момент волны, чтобы сигнал не "бегал" по экрану.
    • Trig Menu: настройка параметров захвата сигнала (выбор источника сигнала, момент срабатывания триггера, тип сигнала и т.д.)
    • Trigger Level: уровень напряжения, при котором осциллограф начнет захватывать и отображать сигнал.
  8. Auto Set: помогает быстро сбросить все старые настройки и настроить осциллограф для отображения текущего сигнала. Отличная функция для начинающих.
  9. Position: настройка положения сигнала на экране. Можно регулировать:
    • положение по вертикали,
    • положение по горизонтали.
asm1

Рис. 16. Основные элементы управления осциллографом.

Во время работы с осциллографом не бойтесь менять параметры и экспериментировать с настройками. Так вы гораздо быстрее научитесь с ним работать. А если вдруг вы что-то поменяли, и не помните, как вернуть всё обратно, то помните, что есть кнопки Auto Set и Default Setup.

Для начала произведем тестовое измерение с помощью калибровочных контактов на осциллографе:

  • подключите щуп к каналу CH1 осциллографа
asm1

Рис. 17. Щуп, подключенный к каналу CH1.

  • включите питание
  • подключите другой конец осциллографа к калибровочному контакту, а крокодил к заземлению
asm1

Рис. 18. Подключение щупа к калибровочному контакту. Верхний контакт: сигнал; Нижний контакт: GND.

  • на экране должен отобразиться сигнал. Если вы его не видите, то возможно канал CH1 отключен. Включить его можно с помощью кнопки CH1 MENU.
  • поэкспериментируйте с элементами управления и добейтесь того, чтобы ваш сигнал не бегал и выглядел примерно, как на изображении ниже (воспользуйтесь элементами VOLTS/DIV, POSITION, TRIG LEVEL):
asm1

Рис. 19. Осциллограмма калибровочного сигнала.

Дополнительно мы можем измерить характеристики сигнала. При нажатии на кнопку MEASURE у вас отобразится информация о сигнале (рис. 20). Среди них:

  • Freq: частота сигнала (Гц),
  • Period: период сигнала (мс),
  • Vamp: амплитуда сигнала (В),
  • Avg: среднее значение напряжения (В),
  • Vmax: максимальное значение напряжения (В),
  • Vmin: минимальное значение напряжения (В).
подсказка

Если информация не отобразилась, то нажмите на MEASURE еще раз или выберите канал CH1 в пункте Source.

asm1

Рис. 20. Окно автоматических измерений.

warning

При работе с реальной платой будьте предельно аккуратны! Если замкнуть щупом сразу несколько контактов, то это может привести к короткому замыканию и вывести электронику из строя.

Теперь давайте визуализируем поведение сигнала, генерируемого микроконтроллером из примера о ЦАП. Для этого:

  • обесточьте плату
  • аккуратно подключите перемычки к контактам PA5 и GND, а затем щуп осциллографа к другим концам этих перемычек (крокодил должен быть подключен к GND)
asm1

Рис. 21. Подключение щупа осциллографа к отладочной плате.

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

Рис. 22. Осциллграмма синусоидального сигнала, генерируемого микроконтроллером (пин PA5).

Вы можете поэкспериментировать с разными значениями переменной freq и посмотреть, как меняется поведение сигнала на экране осциллографа.

подсказка

Часто в платах нет физических выводов для нужной цепи, как в примере выше, но измерить сигнал всё же нужно. Вы можете снять колпачок с щупа и приложить его иголкой непосредственно к точке пайки. Но, повторимся, будьте очень аккуратны, чтобы не замкнуть цепь!

Широтно-импульсная модуляция

Скорее всего вы уже обратили внимание, что выводов с поддержкой АЦП гораздо больше, чем выводов с поддержкой ЦАП. Дело в том, что ЦАП – это дорогой аналоговый блок. Каждый канал ЦАП требует точной матрицы резисторов, калибровки и защиты от помех. Также большое количество ЦАП сильно усложняют внутреннюю топологию кристалла. Поэтому разработчики МК стараются держать компактной ту часть, которая отвечает за ЦАП. Но что, если нам нужно управлять большим количеством аналоговых устройств? Например, управление одним только бесколлекторным мотором требует минимум шесть аналоговых выводов. На помощь в такой ситуации приходит широтно-импульсная модуляция, или сокращенно ШИМ. Для его реализации внутри МК требуется только таймер, а это уже гораздо более простое устройство, чем ЦАП.

Суть ШИМ заключается в очень быстром переключении цифрового сигнала между состояниями HIGH и LOW. Если делать это достаточно быстро, для инерционных устройств (как человеческий глаз или электромотор) это будет выглядеть не как мигание, а как постоянный сигнал с уменьшенной мощностью.

Разберем это на небольшом примере. Поставим своей целью запустить мотор на 50% от его максимальной скорости. Пусть наш двигатель идеальный, и чтобы достичь заданной скорости, нам нужно в единицу времени передавать на мотор в два раза меньше мощности. Как это сделать, не меняя источник питания?

Проведем мысленный эксперимент. Возьмём мотор постоянного тока с массивным маховиком, закрепленным на валу. Подадим питание от аккумулятора и мотор начнет набирать обороты. Через какое-то время, мотор достигнет номинальной мощности, а его выходной вал - максимальной скорости вращения. Отключим питание, и мотор постепенно начнет замедляться вплоть до полной остановки.

Следующий опыт. Снова включим мотор, и когда его скорость достигнет половины от максимальной — выключим. Заметив, что скорость падает — снова включим. И так далее. Включая и выключая питание мотора, мы заставим ротор вращаться со скоростью, близкой к половине от максимальной. Разумеется, в силу человеческой медлительности, мотор будет удерживать заданную скорость с некоторой погрешностью. Чтобы минимизировать эти отклонения, нам потребуется увеличить частоту переключений. Тут уже не обойтись без автоматики.

А как заставить мотор вращаться медленнее или быстрее? Количество переданной мотору энергии будет зависеть от отношения времени, когда мотор включен (tвкл) к времени, когда он выключен (tвыкл).

asm1

Рис. 23.

Так, для передачи мотору 50% мощности, tвкл будет равно tвыкл. Такой случай как раз изображен на графике. Чтобы мотор вращался еще медленнее, скажем с мощностью 25% от номинальной, придется время включения мотора уменьшить до этих самых 25% от общего периода управления tупр. Таким образом, имея возможность менять ширину импульсов, мы можем достаточно точно управлять скоростью вращения мотора.

asm1

Рис. 24.

Теперь рассмотрим параметры, которые характеризуют ШИМ-сигнал и которые следует учитывать при написании программ для микроконтроллеров. Начнем с самого главного параметра — коэффициента заполнения (он же скважность или duty cycle). Этот коэффициент равен отношению периода ШИМ сигнала к ширине импульса:

D=tвклtупр.D = \frac{t_{вкл}}{t_{упр}}.

Пример ШИМ-сигнала для разных значений D:

asm1

Рис. 25. Сигнал ШИМ при разных значениях скважности.

Следующий параметр – это частота ШИМ. Она определяет период импульса tупр. Требования к этой частоте диктуются несколькими факторами, в зависимости от типа управляемого устройства.

В случае управления светодиодами одним из главных факторов становится видимость мерцания. Чем выше частота, тем менее заметно мерцание излучаемого света. Высокая частота также помогает снизить влияние температурных скачков, которые светодиоды не любят. На практике для светодиодов достаточно иметь частоту ШИМ в пределах 100-300 Гц.

В случае с моторами, чем больше частота, тем более плавно и менее шумно он работает. Более подробно о моторах мы поговорим в будущих уроках, а пока рекомендуем для большинства задач по управлению DC-моторами использовать частоту ШИМ равную 2кГц.

Общая проблема для всех случаев управления силовой нагрузкой — потери в цепях силовой коммутации (в транзисторах, и не только), которые увеличиваются с ростом частоты ШИМ. Чем больше частота, тем большее время транзисторы находятся в переходных состояниях, активно выделяя тепло и снижая эффективность системы.

Ещё один важный параметр — разрешение (или разрядность) ШИМ-сигнала. Этот параметр показывает, с какой точностью мы можем менять коэффициент заполнения. Чем больше разрешение, тем плавнее будет меняться мощность на управляемом устройстве. Например, имея разрешение 8 бит мы получим возможность менять коэффициент заполнения от 0 до 255, где 255 будет соответствовать 100%.

За генерацию ШИМ сигнала в микроконтроллерах, как уже говорилось, отвечают аппаратные таймеры, от возможностей которых зависят частота и разрешение генерируемого сигнала. Следовательно, ШИМ-сигнал можно выводить не на любые контакты, а только на те, к которым подключены соответствующие таймеры. На схеме платы VBCores, выводы с поддержкой ШИМ обозначены блоками фиолетового цвета с пометкой PWM (от англ. Pulse-Width Modulator).

Давайте снова напишем программу, которая меняет яркость светодиода. Но так как, ножка PA5, подключенная к светодиоду LED2, уже зарезервирована за ЦАП библиотекой VBCoreG4_arduino_system, то выберем другую ножку и соберем на бредборде собственную схему со светодиодом.

Прежде чем приступить к сборке, сначала немного познакомимся со светодиодом. Светодиод (англ. Light Emitting Diode или просто LED) — энергоэффективная, надёжная, долговечная «лампочка». Светодиод – вид диода, который светится, когда через него проходит ток от анода (+) к катоду (−). Собственное сопротивление светодиода очень мало, и без резистора, ограничивающего ток, проходящий через светодиод, он перегорит. Порядок «резистор до» или «резистор после» – не важен.

На рисунке ниже вы можете обратить внимание, что одна ножка у светодиода длиннее, а другая – короче. Это не ошибка. Чтобы при сборке схем не перепутать, где катод (-), а где анод (+), у всех светодиодов ножки разной длины.

asm1

Рис. 26. Внешний вид (снизу) и условно-графическое отображение (сверху) светодиода.

Для сборки схемы вам понадобится светодиод любого цвета, резистор номиналом от 150 до 1000 Ом и две перемычки. На рисунках ниже показаны электрическая схема и сборочная схема подключения светодиода.

asm1

Рис. 27. Электрическая схема подключения светодиода к микроконтроллеру.

asm1

Рис. 28. Сборочная схема подключения светодиода к микроконтроллеру.

Теперь напишем программу:

#include <VBCoreG4_arduino_system.h>

const float ampl = 1.0; // амплитуда синусоидального сигнала
const float freq = 0.2; // частота синусоидального сигнала
float t = 0;
int out = 0;
float curve = 0;

void setup() {
pinMode(PA9, OUTPUT); // инициализировать пин PA9 в режим выхода
analogWriteResolution(12); // задать разрешение ШИМ
analogWriteFrequency(2000); // задать частоту ШИМ
// t = 0;
}

void loop() {
// инкремент
t += 0.001;
// расчет синусоидального сигнала от 0 до 1
curve = (ampl*sin(2*M_PI*freq*t) + ampl)/2;
// перевод в единицы ЦАП
out = curve * 4095;
// вывод полученного значения на ЦАП
analogWrite(PA9, out);
// задержка 1 мс
delay(1);
}

Загрузите код на микроконтроллер и убедитесь, что светодиод плавно меняет свою яркость с периодом 5 секунд. Подцепите щуп осциллографа к аноду светодиода и понаблюдайте за поведением сигнала.

asm1

Рис. 29. Осциллограмма ШИМ-сигнала.

Если сигнал отображается не как на изображении выше или постоянно плывет и скачет, то сделайте следующее:

  1. Установите развертку в 500 мкс;
  2. Установите масштаб по напряжению в 1 В;
  3. Воспользуйтесь функцией триггера. Для этого нажмите на кнопку TRIG и затем вращая ручку TRIGGER LEVEL, установите уровень триггера в положение в окрестности 1 В.

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

В последнем разделе рассмотрим проект, который объединяет весь пройденный материал и знакомит с еще одним устройством – потенциометром. Потенциометр – это переменный резистор со скользящим контактом. Их используют в робототехнике как регуляторы различных параметров — громкости звука, частоты, напряжения и т.п. Обратите внимание на рисунки ниже. На рис. 31 показано устройство потенциометра и принцип работы, а на рис. 32 – его условно-графическое отображение в электрических схемах.

Глядя на рис. 31 видно, что потенциометр - это по сути делитель напряжения. Это значит, что если подключить вывод 1 к питанию +3.3 В, а вывод 3 к земле, то на выводе 2 можно получать напряжение в диапазоне от 0 В до 3.3 В в зависимости от положения ручки потенциометра.

asm1

Рис. 30. Фотография оптенциометра.

asm1

Рис. 31. Устройство потенциометра.

asm1

Рис. 32. Условно-графическое отображение потенциометра.

Сделаем проект с потенциометром и светодиодом: при помощи потенциометра будем выполнять управление яркостью светодиода. Для этого нужно читать аналоговый сигнал с выхода потенциометра и отправлять ШИМ-сигнал на светодиод.

Соберите проект в соответствие со схемами:

asm1

Рис. 33. Электрическая схема проекта с потенциометром.

asm1

Рис. 34. Сборочная схема проекта с потенциометром.

И напишите программу:

#include <VBCoreG4_arduino_system.h>
int val = 0;

void setup() {
// инициализировать цифровой вывод A0 в качестве аналогового входа
pinMode(A0, INPUT_ANALOG);
// инициализировать пин PA9 в режим выхода
pinMode(PA9, OUTPUT);
// установить разрядность АЦП в 12 бит
analogReadResolution(12);
// задать разрядность ШИМ
analogWriteResolution(12);
// задать частоту ШИМ
analogWriteFrequency(2000);
}

void loop() {
// чтение данных с аналогового входа
val = analogRead(A0);

// вывод полученного значения на ЦАП
analogWrite(PA9, val);
}

Загрузите код на микроконтроллер и протестируйте собранную схему. Если что-то не работает, то убедитесь в том, что вы верно собрали схему и не сделали опечаток при написании программы. Дополнительно в качестве теста подключите одним щупом осциллографа к ножке PA0, а другим – к PA9. Посмотрите, как меняется заполнение ШИМ в зависимости от уровня напряжения на выходе потенциометра.

Заключение

В сегодняшнем уроке мы изучили основные принципы работы с АЦП, ЦАП и ШИМ. Более того, мы познакомились с такими устройствами, как делитель напряжения, фоторезистор и потенциометр. Впереди нас ждёт изучение таймеров и продолжение изучения основ электроники и программирования микроконтроллеров.