ШИМ. Урок 4. Ардуино

ШИМ
Порты поддерживающие ШИМ обозначены ~
Порты поддерживающие ШИМ обозначены ~

Привет! Продолжаем говорить про ардуино. Сегодня речь пойдет про широтно-импульсную модуляцию или шим. Что это, как использовать, при чем здесь ардуино? Давайте разбираться.

В прошлый раз мы говорили про написание своей собственной функции. Пожалуйста, посмотрите тот пост, если уже забыли или пропустили его.

Функции. Урок 3. Ардуино

В предыдущих статьях мы рассматривали возможности ардуино по приему и выводу цифровых сигналов. В этом случае мы можем вывести на пин напряжение 0 или 5 вольт. Что считается логическим 0 и 1 соответственно. И также мы можем считать напряжение на пине. Например, когда используем кнопку.

Но часто необходимо использовать напряжение между 0 и 5 вольтами. Чтобы вывести такое напряжение платы ардуино uno недостаточно. Можно использовать ардуино due или подключить внешнюю схему цифроаналогового преобразователя.

Однако, мы можем имитировать аналоговый сигнал на цифровых выходах ардуино с помощью широтно-импульсной модуляции или шим.

Контакты, которые можно использовать для генерации шим сигнала, помечены на плате ардуино специальным символом ~.

На плате ардуино uno, контакты 3, 5, 6, 9, 10, 11 поддерживают вывод ШИМ сигнала.

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

  • Ардуино UNO
  • Макетная плата
  • Перемычки
  • 4 Резистора номиналом 220 Ом
  • 4 Светодиода 5 мм
  • Кабель USB

analogWrite()

Чтобы использовать возможности шим, рассмотрим новую функцию analogWrite().

Функция analogWrite() принимает два аргумента: номер пина для вывода и 8 разрядное число от 0 до 255, которое будет выводиться на контакте.

В стандартной библиотеке ардуино ide уже есть программа для демонстрации работы шим. Давайте загрузим ее и посмотрим как это работает.

Загрузим программу из меню File — Examples — Basics — Fade.ino и соберем простую схему на макетной плате. Нам понадобятся один резистор, один светодиод и несколько перемычек.

Принципиальная схема подключения для шим сигнала
Принципиальная схема подключения для шим сигнала

Текст программы

int led = 9;           // the PWM pin the LED is attached to
int brightness = 0;    // how bright the LED is
int fadeAmount = 5;    // how many points to fade the LED by

// the setup routine runs once when you press reset:
void setup() {
  // declare pin 9 to be an output:
  pinMode(led, OUTPUT);
}

// the loop routine runs over and over again forever:
void loop() {
  // set the brightness of pin 9:
  analogWrite(led, brightness);

  // change the brightness for next time through the loop:
  brightness = brightness + fadeAmount;

  // reverse the direction of the fading at the ends of the fade:
  if (brightness <= 0 || brightness >= 255) {
    fadeAmount = -fadeAmount;
  }
  // wait for 30 milliseconds to see the dimming effect
  delay(30);
}

В тексте программы все уже должно быть понятно, чуть позже мы модифицируем ее и разберем подробнее. Пока что нас интересует только функция analogWrite() которая устанавливает на пин 9 напряжение 5 вольт, но особым способом.

Скважность

Скважность — это отношение периода повторения импульсов к длительности импульса. Чтобы лучше это понять рассмотрим графики.

ШИМ представляет собой изменение скважности прямоугольной последовательности импульсов. Скважность можно трактовать как процент времени, когда прямоугольный импульс имеет уровень HIGH, ко всему периоду повторения. Скважность 50% означает, что половину периода сигнал имеет высокий уровень, а половину — низкий.

ШИМ и скважность
ШИМ и скважность

Функция analogWrite() устанавливает скважность последовательности прямоугольных импульсов в зависимости от значения, передаваемого ей.

На графиках видно, что для сигнала со скважностью 25% значение HIGH действует в течение четверти периода, а остальные 75% времени установлено значение LOW. Частота прямоугольной последовательности импульсов в случае Arduino составляет приблизительно 490 Гц. Другими словами, уровень сигнала меняется от высокого (5 В) к низкому (0 В) приблизительно 490 раз каждую секунду.

Как видим, напряжение, подаваемое на светодиод, на самом деле не понижается, почему же при уменьшении скважности наблюдается спад яркости свечения светодиода? Это связано с особенностью нашего зрения. Если светодиод включается и выключается один раз за 1 мс (при скважности 50%), то вам кажется, что яркость свечения светодиода составляет приблизительно 50% от максимальной, потому что переключение происходит быстрее, чем глаза могут это зафиксировать. Ваш мозг фактически усредняет сигнал и создается впечатление, что светодиод работает на половине яркости.

Теперь изменим программу и соберем более интересную схему.

Принципиальная схема подключения светодиодов и шим
Принципиальная схема подключения светодиодов и шим

Подключим все 4 светодиода к шим портам ардуино через резисторы. Катоды всех диодов подключим к общей земле. Используем контакты 3, 6, 9 и 11.

Объявим массив светодиодов, счетчики и настроим пины на вывод.

int brightness = 0;
int fadeAmount = 5;

int leds[] = {3, 6, 9, 11};
int j=0;
int delta=1;
void setup() {
  pinMode(leds[0], OUTPUT);
  pinMode(leds[1], OUTPUT);
  pinMode(leds[2], OUTPUT);
  pinMode(leds[3], OUTPUT);
}

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

void fade(int i){

  for(brightness=0; brightness <= 255; brightness+=fadeAmount){
    analogWrite(leds[i], brightness);
    delay(10);
  }
  for(brightness=255; brightness >= 0; brightness-=fadeAmount){
    analogWrite(leds[i], brightness);
    delay(10);
  }
    
}

А в основном цикле loop() будем вызывать функцию и последовательно передавать ей номер массива. В конце меняем знак переменной delta, чтобы цикл шел в обратном направлении.

void loop() {
  for(j=0;j<=3;j+=delta){
    fade(j);
    if (j < 0 || j >= 3) {delta = -delta;}
  }
}
ШИМ эффект на светодиоде
ШИМ эффект на светодиоде

Полный текст программы

int brightness = 0; 
int fadeAmount = 5;

int leds[] = {3, 6, 9, 11};
int j=0;
int delta=1;
void setup() {
  pinMode(leds[0], OUTPUT);
  pinMode(leds[1], OUTPUT);
  pinMode(leds[2], OUTPUT);
  pinMode(leds[3], OUTPUT);
}

void fade(int i){
  for(brightness=0; brightness <= 255; brightness+=fadeAmount){
    analogWrite(leds[i], brightness);
    delay(10);
  }
  for(brightness=255; brightness >= 0; brightness-=fadeAmount){
    analogWrite(leds[i], brightness);
    delay(10);
  }
}

void loop() {
  for(j=0;j<=3;j+=delta){
    fade(j);
    if (j < 0 || j >= 3) {
      delta = -delta;
    }
  }
}

Заключение

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

Добавить комментарий

Ваш адрес email не будет опубликован.