4.02. Аналоговые сигналы и ШИМ.md


В предыдущем параграфе мы научились управлять миром с помощью нулей и единиц — включали и выключали устройства. Но реальный мир гораздо богаче и разнообразнее. Яркость солнца, громкость музыки, скорость автомобиля — всё это аналоговые величины, которые изменяются плавно, а не скачками. Как же наш цифровой Рудирон, мыслящий только категориями HIGH и LOW, может управлять аналоговыми устройствами, например, плавно менять яркость светодиода или скорость вращения вентилятора?

Для этого микроконтроллер использует один очень умный трюк — широтно-импульсную модуляцию, или ШИМ (в английской литературе — PWM, Pulse-Width Modulation).

Что такое аналоговый сигнал?

Прежде чем мы разберёмся с ШИМ, давайте поймём, что такое аналоговый сигнал. Представьте обычный выключатель света — у него два положения: включено и выключено. Это цифровой принцип. А теперь представьте диммер — ручку, поворачивая которую, вы можете плавно регулировать яркость лампы от 0% до 100%. Эта плавная регулировка и есть суть аналогового сигнала. Он может принимать любое значение в определённом диапазоне.

Наш микроконтроллер не может напрямую выдать напряжение, скажем, 1.5 В или 2.1 В. Его GPIO порты умеют выдавать только 0 В (LOW) или 3.3 В (HIGH). И здесь на помощь приходит ШИМ.

ШИМ - магия быстрого переключения

Идея ШИМ гениально проста! Вместо того чтобы пытаться выдать промежуточное напряжение, микроконтроллер начинает очень быстро переключать пин между HIGH и LOW.

Представьте, что вы невероятно быстро щёлкаете выключателем света. Если вы будете держать его включённым половину времени, а выключенным — другую половину, то вашему глазу покажется, что лампочка горит вполсилы. Электроника, например, светодиод или мотор, ведёт себя так же. Из-за своей инерционности она не успевает полностью включиться и выключиться вслед за быстрыми переключениями и реагирует на среднее напряжение.

У ШИМ-сигнала есть два ключевых параметра: 1. Период — время, за которое сигнал успевает один раз включиться и выключиться. На Рудироне это происходит с очень высокой и постоянной частотой. 2. Коэффициент заполнения — это процент времени внутри одного периода, в течение которого сигнал находится в состоянии HIGH. Именно изменяя этот параметр, мы и управляем “яркостью” сигнала!

  • Коэффициент заполнения 20%: Сигнал большую часть времени LOW. Светодиод будет светить тускло.
  • Коэффициент заполнения 50%: Сигнал половину времени HIGH, половину LOW. Светодиод будет светить со средней яркостью.
  • Коэффициент заполнения 80%: Сигнал большую часть времени HIGH. Светодиод будет светить ярко, но не на полную мощность.

Давайте посмотрим, как это выглядит на графиках:

Рис. 1. ШИМ-сигнал

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

Функция analogWrite()

Для генерации ШИМ-сигнала в Рудироне используется функция analogWrite(). Важно помнить, что не все пины поддерживают ШИМ. На плате Рудирон такие пины отмечены специальным символом апострофа (').

Синтаксис функции:

analogWrite(номерПина, значение);
  • номерПина. Пин, который поддерживает ШИМ.
  • значение. Число от 0 до 255, которое задаёт коэффициент заполнения.

Почему именно от 0 до 255? Ответ кроется в битах. Микроконтроллер Рудирона использует 8-битный ШИМ. Это значит, что для описания коэффициента заполнения у него есть 8 двоичных разрядов (бит).

1 0 1 1 0 0 1 1
128 (2^7) 64 (2^6) 32 (2^5) 16 (2^4) 8 (2^3) 4 (2^2) 2 (2^1) 1 (2^0)

Каждый бит — это степень двойки. Чтобы перевести двоичное число в десятичное, нужно сложить значения тех разрядов, где стоит единица.

  • Максимальное значение: 11111111 Это 128 + 64 + 32 + 16 + 8 + 4 + 2 + 1 = 255. Это соответствует 100% заполнению.
  • Пример из таблицы: 10110011 Это 128 + 0 + 32 + 16 + 0 + 0 + 2 + 1 = 179. Это соответствует заполнению примерно 70% (179 / 255 * 100%).

Таким образом, мы получаем 256 уровней «яркости»:

  • analogWrite(pin, 0); — 0% заполнения (сигнал всегда LOW).
  • analogWrite(pin, 127); — примерно 50% заполнения.
  • analogWrite(pin, 255); — 100% заполнения (сигнал всегда HIGH).

Пример (плавное затухание светодиода):

const int ledPin = 5; // Пин 5 на Рудироне поддерживает PWM (`)

void setup() {
  pinMode(ledPin, OUTPUT); // Настраиваем пин как выход
}

void loop() {
  // Плавно уменьшаем яркость от максимальной до нуля
  for (int brightness = 255; brightness >= 0; brightness--) {
    analogWrite(ledPin, brightness);
    delay(10); // Небольшая задержка для плавности эффекта
  }
  
  // Плавно увеличиваем яркость от нуля до максимальной
  for (int brightness = 0; brightness <= 255; brightness++) {
    analogWrite(ledPin, brightness);
    delay(10);
  }
}

Зачем это нужно?

ШИМ — это невероятно мощный и универсальный инструмент. С его помощью вы можете:

  • Плавно управлять яркостью светодиодов для создания световых эффектов.
  • Контролировать скорость моторов постоянного тока в роботах или вентиляторах.
  • Генерировать простые звуковые сигналы на пьезодинамике.
  • Управлять положением сервоприводов.

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