3.5.md
ШИРОТНО-ИМПУЛЬСНАЯ МОДУЛЯЦИЯ
Как управлять яркостью свечения светодиодом.
При создании разнообразных устройств очень часто требуется управление скоростью вращения двигателя, яркостью свечения светодиодов, углом поворота сервоприводов и т.д. Для этого используется ШИМ!
ШИМ (PWM) —широтно-импульсная модуляция (power wigth modulation). Основана на изменении ширины импульса при постоянном периоде их появления.
НАПОМИНАНИЕ
При использовании внешнего питания сначала подключаем внешнее питание, а потом USB-кабель для связи или программирования. При выключении все делаем наоборот: сначала вытаскиваем USB-кабель, а затем внешнее питание. Несоблюдение данного правила может привести к выходу из строя платы Рудирон.
Для лучшего понимания рассмотрим временную диаграмму ШИМ:
На диаграмме мы видим, что импульсы поступают через промежутки времени Т (называется периодом). Так же есть следующие параметр tимп (ширина импульса) и tпаузы (время паузы), D (скважность). Т, tимп, tпаузы измеряются в секундах так как это временные промежутки. D измеряется в процентах % и показывает насколько ширина импульса отличается от паузы. Чем выше скважность, тем действующее напряжение будет на управляемом устройстве и как следствие светодиоды будут ярче светиться, а частота вращения двигателей максимальная. При значении D близкому к 100% график будет стремиться к прямой линии по высоте близкой к максимальному напряжению (3,3 В).
За формирование ширины импульса отвечает один из трех таймеров контроллера. Таймер может считать до 255 импульсов внутренних генераторов. Отсюда можно понять, что при скважности D=1% таймер будет подсчитывать 2 импульса с внутреннего генератора. При скважности D=100 будет подсчитывать 255 импульсов с внутреннего генератора.
Даже если вы не поняли из описания что такое ШИМ не расстраивайтесь. Основное это то, что нам необходимо задавать различную длину импульса на выходе контроллера и это будет регулироваться напряжение на внешнем устройстве. Ниже приведем диаграмму как влияют команды с различными параметрами на длину импульса.
ПРОГРАММНОЕ УПРАВЛЕНИЕ ШИМ МОДУЛЯЦИЕЙ
Команда, которая позволяет выводить ШИМ сигнал на вывод контроллера analogWrite(«Номер порта», «Длина импульса в относительных единицах»).
Прежде чем использовать ШИМ необходимо обратится к знакомой нами таблице GPIO и посмотреть на какие выводы могут генерироваться ШИМ сигналы.
ВАЖНО Не все выводы контроллера могут использоваться как ШИМ!
Следующие выводы контроллера могут использовать ШИМ: 5 (A2), 7 (A4), 8 (A5), 12 (B7), 20 (C2), 23 (D3), 28 (E1), 29 (E2), 33 (E6)
Описание портов ввода-вывода (GPIO)
Номер | Альтернативное обозначение | Порт | ШИМ | Внешнее прерывание | Альтернативная функция |
0 | —- | F3 | —- | —- | SSP1_RXD/CAN2_TX |
1 | —- | F2 | —- | —- | SSP1_FSS/CAN2_RX |
2 | —- | F1 | —- | —- | SSP1_CLK/UART2_TXD |
3 | —- | F0 | —- | —- | SSP1_TXD/UART2_RXD |
4 | —- | A1 | —- | —- | —- |
5 | L1 (светодиод на плате) | A2 | + | —- | —- |
6 | —- | A3 | —- | —- | —- |
7 | L2 (светодиод на плате) | A4 | + | —- | |
8 | —- | A5 | + | —- | —- |
Из таблицы видим, что в контроллере светодиоды L1 и L2 подключены к выводам контроллера с возможностью генерации ШИМ (отдельный столбец ШИМ если есть возможность генерировать, то стоит +). При проектировании контроллера так сделали специально, чтобы можно было изучить основы ШИМ без необходимости подключения дополнительных устройств.
Задача — написать программу изменения яркости свечения светодиода L1, используя ШИМ модуляцию
#include “Arduino.h” void setup()
{
pinMode(LED_BUILTIN_1, OUTPUT);
}
void loop()
{
analogWrite(LED_BUILTIN_1, 0); // светодиод не светится
delay(2000);
analogWrite(LED_BUILTIN_1, 10); // слабое свечение светодиода
delay(2000);
analogWrite(LED_BUILTIN_1, 60);
delay(2000);
analogWrite(LED_BUILTIN_1, 175);
delay(2000);
analogWrite(LED_BUILTIN_1, 255); // макс. яркость свечения
delay(2000);
}
Программа довольная простая. Вывод контроллера настраивается на вывод pinMode(LED_BUILTIN_1, OUTPUT);.
Далее мы задаем команду analogWrite(LED_BUILTIN_1, 0) и делаем задержку в 2 секунды (2000 милисекунд), чтобы увидеть насколько ярко светит светодиод.
Светодиод не светится, так как длина импульсов минимальна. Далее мы увеличиваем длину импульса analogWrite(LED_BUILTIN_1, 10) с задержкой в 2 секунды и наблюдаем слабое свечение светодиода. Повторяем команды и увеличиваем длину импульсов ШИМ. В результате выполнения программы мы увидим, что светодиод L1 каждые 2 секунда будет светиться все ярче и ярче.
При использовании ШИМ для управления свечением светодиодов мы получаем еще один положительный эффект. Пониженное энергопотребление (уменьшение тока потребления). Поэтому в современных устройствах, особенно автономных, ШИМ используется обязательно.
Временная диаграмма, отражающая работу нашей программы:
Мы научились работать с кнопками, задержкой и управлять шириной импульса в ШИМ сигнале. Еще мы использовали циклы.
Совместим все наши знания в новой программе. По нажатию кнопки B1 пусть плавно начинает увеличивать яркость свечения светодиод LED1. При нажатии кнопки B3 будет происходить плавное уменьшение яркости свечения LED2. Для реализации программы будем использовать циклы.
#include “Arduino.h” void setup()
{
// настраиваем входы для кнопок с подключением подтягивающих резисторов к земле
pinMode(BUTTON_BUILTIN_1, INPUT_PULLDOWN);
pinMode(BUTTON_BUILTIN_3, INPUT_PULLDOWN);
// настраиваем выходы светодиодов pinMode(LED_BUILTIN_1, OUTPUT);
pinMode(LED_BUILTIN_2, OUTPUT);
}
bool btnState; // создаем переменную для хранения true или false
void loop()
{
// обрабатываем нажатие кнопки В1 на реализацию плавного увеличения силы свечения светодиода LED1
btnState = digitalRead(BUTTON_BUILTIN_1); if (btnState)
{
// цикл каждые 100 миллисекунд увеличиваем ширину импульса сигнала ШИМ на 1 единицу
for (int i = 0; i < 100; i++)
{
analogWrite(LED_BUILTIN_1, i); delay(100);
}
analogWrite(LED_BUILTIN_1, 0);
} // обрабатываем нажатие кнопки В3 на реализацию плавного уменьшения силы свечения светодиода LED2
btnState = digitalRead(BUTTON_BUILTIN_3); if (btnState)
{ // цикл каждые 100 миллисекунд уменьшаем ширину импульса сигнала ШИМ на 1 единицу
for (int i = 100; i >0; i--)
{
analogWrite(LED_BUILTIN_2, i); delay(100);
}
analogWrite(LED_BUILTIN_2, 0);
}
}
Текст программы Вам должен быть понятен, так как мы использовали все те конструкции и команды, что и в предыдущих программах.
Единственное отличие это реализация цикла с уменьшением счетчика, а не увеличением i–.
for (int i = 100; i >0; i--)
{
analogWrite(LED_BUILTIN_2, i); delay(100);
}
Цикл с уменьшением часто используется в программах, в том числе при обработке массивов. А теперь посмотрим как изменяются характеристики сигнала на осциллографе. Для этого загрузим в Рудирон следующую программу и подключим к контактам «5» и «Земля» (обозначение ) осциллограф.
#include “Arduino.h” void setup()
{
// конфигурация последовательного порта
Serial.begin(115200);
// отправка приветствия через последовательный порт
Serial.println(«Рудирон Бутерброд!»);
}
void loop()
{
// запуск шим стандартной частотой 490 Гц с пошаговым увеличением длительности импульса от 1 до 255
analogWrite(LED_BUILTIN_1, 1); delay(3000);
analogWrite(LED_BUILTIN_1, 5); delay(3000);
analogWrite(LED_BUILTIN_1, 10); delay(3000);
analogWrite(LED_BUILTIN_1, 15); delay(3000);
analogWrite(LED_BUILTIN_1, 30); delay(3000);
analogWrite(LED_BUILTIN_1, 50); delay(3000);
analogWrite(LED_BUILTIN_1, 125); delay(3000);
delay(3000); analogWrite(LED_BUILTIN_1, 135);
delay(3000);
analogWrite(LED_BUILTIN_1, 145);
delay(3000);
analogWrite(LED_BUILTIN_1, 175);
delay(3000);
analogWrite(LED_BUILTIN_1, 195);
delay(3000);
analogWrite(LED_BUILTIN_1, 250);
delay(3000);
analogWrite(LED_BUILTIN_1,10);
delay(3000);
}
Можно посмотреть снимки с экрана осциллографа как изменяется длительность сигнала:
На экране прибора мы видим частоту сигнала, измеряемую осциллографом Freq = 490 Гц. Так же видим длину импульса сигнала +Wid = 80 мкс. По мере изменения передаваемой длительности сигнала от 1 до 255 мы увидите, как меняется длительность импульса на экране.
Для того, чтобы генерация ШИМ сигналов была гибче, мы дополнили библиотеку новой функцией
pwm(Номер порта контроллера, Частота сигнала ШИМ, Процент заполнения, 100);
Она позволяет задавать степень заполнения (длительность импульса) в процентах от 0 до 100 и так же задать нужную нам частоту генерации сигнала. Обратите внимание, что для использования данной функции мы должны подключить дополнительную библиотеку:
#include “rudiron/timer.h”
Ниже представлен листинг программы и снимки с экрана осциллографа, где в цикле меняется длительность импульса на 10 процентов.
#include “Arduino.h” #include “rudiron/timer.h”
#define PWM_PIN 5
using namespace Rudiron; void setup()
{
// конфигурация последовательного порта
Serial.begin(115200);
// отправка приветствия через последовательный порт
Serial.println(«Рудирон Бутерброд!»);
}
void loop()
{
for(int i=0;i<101;i=i+10){
// запуск ШИМ с частотой 50 Гц с заполнением от 0 до 100% с шагом в 10 процентов каждые 3 секунды
pwm(PWM_PIN, 50, i, 100);
// пауза программы на 1 секунду
delay(3000);
}
// остановка шим на выводе PWM_PIN
pinMode(PWM_PIN, OUTPUT);
}
На экране осциллографа видно, что частота сигнала стала 50 Гц вместо 490 Гц по умолчанию.
ПРИМЕЧАНИЕ Если Вы хотите выполнять программу при последующих включениях «Рудирона», то не забудьте переставить перемычку из положения «Режим программирования» обратно в «Режим выполнения». Если этого не сделать, то программа при включении «Рудирона» выполняться не будет.
ВЫВОДЫ
Мы научились работать с кнопками, задержкой и управлять шириной импульса в ШИМ-сигнале. Еще мы использовали циклы и новую функцию pww() для управления ШИМ-сигналом.
СПИСОК КОНТРОЛЬНЫХ ВОПРОСОВ
- Что такое ШИМ? Как расшифровывается сокращение?
- Для чего применяется ШИМ-модуляция?
- Как работает широтно-импульсная модуляция?
- Какие выводы контроллера можно использовать для ШИМ?
- Можно ли применять ШИМ для встроенных светодиодов L1 и L2?
- Какой прибор можно использовать для просмотра характеристик ШИМ-сигнала?
- Как можно подключить осциллограф для контроля характеристик ШИМ-сигнала для встроенных светодиодов L1 и L2?
- Что будет результатом выполнения нашей первой программы?
- Что будет результатом выполнения нашей второй программы?
- Что будет результатом выполнения нашей третьей программы?
СПИСОК ДОПОЛНИТЕЛЬНЫХ ЗАДАЧ
- Использовать для написания программы среду Arduino IDE.
- Собрать все 3 программы в одну программу, которая анализирует нажатие кнопок, сообщает в терминал результат нажатия, выводит переменную, включает/выключает встроенный светодиод L1 в зависимости от введенных данных («0» – выключить, «1» – включить).
- В программе из п.2 заменить выводимую переменную, ввести управление встроенным светодиодом L2 («1» – выключить, «0» – включить).
ЭЛЕМЕНТЫ КОНТРОЛЯ И ПРОВЕДЕНИЯ СОРЕВНОВАНИЙ
- Проведение тестирования по контрольным вопросам. Критерии: кто быстрее и допустил меньшее количество ошибок.
- Программирование задач с использование разных кнопок (B1, B2, B3) и поведения встроенных светодиодов L1 и L2 (медленное включение, медленное выключение, включение на максимум, включение на минимум и т.д.). Критерии: Правильно написанная программа согласно выданного задания, работающий контроллер и наименьшее количество времени затраченного на эти работы.