Широтно-імпульсна модуляція (ШІМ, PWM)

Широтно-імпульсна модуляція
Мікроконтролери зазвичай не можуть видавати довільну напругу. Вони можуть видати або напругу живлення (наприклад, 5 В), або землю (тобто 0 В).
Але існує багато речей, що управляються зміною рівня напруги: наприклад, яскравість світлодіода або швидкість обертання мотора. Для симуляції неповної напруги (рисунок 1) використовується ШІМ (Широтно-Імпульсна Модуляція, англ. Pulse Width Modulation або просто PWM).

pwm_1

Застосування

Вихід мікроконтролера перемикається між землею і Vcc тисячі разів в секунду. Або, як ще кажуть, має частоту в тисячі герц. Око не помічає мерехтіння більше 50 Гц, тому нам здається, що світлодіод не мерехтить, а горить в півсили.
Аналогічно, розігнаний мотор не може зупинити вал за мілісекунди, тому ШІМ-сигнал змусить обертатися його в неповну силу.

Шпаруватість
Відношення часу увімкнення і вимкнення називають шпаруватістю (скважністю) (англ. duty cycle). Розглянемо кілька сценаріїв при напрузі живлення Vcc рівній 5 вольтам.
50% — еквівалент 2,5 В

pwm_2

10% — еквівалент 0,5 В

pwm_3

90% — еквівалент 4,5 В

pwm_4

Під’єднання кнопки та світлодіода до Arduino Uno

arduino_pwm

Резистор до кнопки – 10 кОм, резистор до світлодіода – 220 Ом.



Функції читання/запису з контактів Arduino
digitalRead(pin) – функція зчитує із заданого входу значення HIGH або LOW.
digitalWrite(pin, value) – подає на цифровий вхід/вихід значення HIGH або LOW.
analogRead(pin) – функція зчитує значення із заданого аналогового входу.
analogWrite(pin, value) – формує задану аналогову напругу на виводі у виді ШІМ-сигналу.

Напишемо програму для керування яскравістю світлодіода. В даній програмі світлодіод має три рівні яскравості (85*3=255).

int switchPin = 8; //контакт для кнопки
int ledPin = 11; //контакт для світлодіода
//запам'ятати стан кнопки
boolean lastButton = LOW;
//запам'ятати рівень PWM (0-255)
int ledLevel = 0;
//запам'ятати стан кнопки для функції стабілізації
boolean currentButton = LOW;

void setup()
{
//ініціалізація входів/виходів
pinMode(switchPin, INPUT);
pinMode(ledPin, OUTPUT);
}

//функція для стабілізації кнопки
boolean debounce(boolean last)
{
//визначити поточний стан перемикача
boolean current = digitalRead(switchPin);
//порівняти з попереднім значенням, щоб знати чи натискали кнопку
if (last != current)
{
//якщо стан кнопки змінився робимо затримку на 5 секунд,
//протягом яких кнопка стабілізується
delay(5);
//повторне читання вже стабілізованої кнопки
current = digitalRead(switchPin);
}
//повернути значення кнопки
return current;
}
void loop()
{
//запуск функції стабілізації
currentButton = debounce(lastButton);
//перевірка, що кнопка була щойно натиснута
if (lastButton == LOW && currentButton == HIGH)
{
//збільшити яскравість
ledLevel = ledLevel + 85;
}
lastButton = currentButton;
//вимкнення світлодіода, якщо ledLevel > 255
if (ledLevel > 255) ledLevel = 0;
analogWrite(ledPin, ledLevel);
}




Результат роботи програми:

Оставить ответ

Обязательные поля помечены*

Этот сайт использует Akismet для борьбы со спамом. Узнайте как обрабатываются ваши данные комментариев.