Урок 37. Широтно-импульсная модуляция в Ардуино.

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

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

Предыдущий урок     Список уроков     Следующий урок

Прервемся на урок от разработки контроллера холодильника, для того чтобы научиться работать с широтно-импульсным модулятором Ардуино.

 

В нашей разработке используется именно такой способ регулирования мощности на элементе Пельтье.

 

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

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

Можно выделить две основные области применения широтно-импульсной модуляции:

  • Во вторичных источниках питания, различных регуляторах мощности, регуляторах яркости источников света, скорости вращения коллекторных двигателей и т.п. В этих случаях применение ШИМ позволяет значительно увеличить КПД системы и упростить ее реализацию.
  • Для получения аналогового сигнала с помощью цифрового выхода микроконтроллера. Своеобразный цифро-аналоговый преобразователь (ЦАП). Очень простой в реализации, требует минимума внешних компонентов. Часто достаточно одной RC цепочки.

Принцип регулирования с помощью ШИМ – изменение ширины импульсов при постоянной амплитуде и частоте сигнала.

Диаграмма широтно-импульсной модуляции

На диаграмме можно увидеть основные параметры ШИМ сигнала:

  • Ui - амплитуда импульсов ;
  • Ton – время активного (включенного) состояния сигнала;
  • Toff – время отключенного состояния сигнала;
  • Tpwm – время периода ШИМ.

Даже интуитивно понятно, что мощность на нагрузке пропорциональна соотношению времени включенного и отключенного состояния сигнала.

Это соотношение определяет коэффициент заполнения ШИМ:

Kw = Ton / Tpwm.

Он показывает, какую часть периода сигнал находится во включенном состоянии.  Может меняться:

  •  от 0 – сигнал всегда выключен;
  •  до 1 - сигнал все время находится во включенном состоянии.

Чаще используют процентный коэффициент заполнения. В этом случае он находится в пределах от 0 до 100%.

Диаграммы с разными коэффициентами заполненияСреднее значение электрической мощности на нагрузке строго пропорционально коэффициенту заполнения. Когда говорят, что ШИМ равен, например, 20%, то имеют в виду именно коэффициент заполнения.

 

Формирование аналогового сигнала.

Если сигнал ШИМ пропустить через фильтр низких частот (ФНЧ), то на выходе фильтра мы получим аналоговый сигнал, напряжение которого пропорционально коэффициенту заполнения ШИМ.

U = Kw * Ui

В качестве ФНЧ можно использовать простейшую RC цепочку.

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

F = 1 / (2 π R C).

  • При повышении частоты среза ФНЧ на выходе фильтра увеличиваются пульсации с частотой ШИМ.
  • При уменьшении частоты среза фильтра снижается время реакции выходного аналогового сигнала на изменения ширины импульсов.

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

Я бы рекомендовал:

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

Даже простейшие моделирующие программы вычисляют уровень пульсаций достаточно точно. Вот результаты моделирования на SwCAD для ШИМ частотой 500 Гц и RC фильтрами с частотами среза 500 Гц, 50 Гц и 5 Гц. Зеленым цветом показана диаграмма ШИМ, синим – напряжение на выходе RC фильтра.

Частота среза 500 Гц (10 кОм, 32 нФ).

Диаграмма пульсаций

Частота среза 50 Гц (10 кОм, 320 нФ).

Диаграмма пульсаций

Частота среза 5 Гц (10 кОм, 3,2 мкФ).

Диаграмма пульсаций

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

К недостаткам использования широтно-импульсных модуляторов в качестве ЦАП также следует отнести высокое выходное сопротивление. Оно определяется сопротивлением резистора RC фильтра и не может быть низким из-за малой нагрузочной способности выходов микроконтроллера.

 

Широтно-импульсные модуляторы в Ардуино.

Платы Ардуино на базе микроконтроллеров ATmega168/328 имеют 6 аппаратных широтно-импульсных модуляторов. Сигналы ШИМ могут быть сгенерированы на выводах 3, 5, 6, 9, 10, 11.

Управление аппаратными ШИМ осуществляется с помощью системной функции analogWrite().

void analogWrite(pin, val)

Функция переводит вывод в режим ШИМ и задает для него коэффициент заполнения. Перед использованием analogWrite() функцию pinMode() для установки вывода в режим “выход” вызывать необязательно.

Аргументы:

  • pin – номер вывода для генерации ШИМ сигнала.
  • val – коэффициент заполнения ШИМ. Без дополнительных установок  диапазон val от 0 до 255 и соответствует коэффициенту заполнения от 0 до 100 %. Т.е. разрядность системных ШИМ в Ардуино 8 разрядов.

analogWrite(9, 25);  // на выводе 9 ШИМ = 10%

Частота ШИМ Ардуино 488,28 Гц.

Для генерации ШИМ используются все три таймера Ардуино.

Таймер Используется для генерации ШИМ на выводах
Таймер  0 выводы 5 и 6
Таймер  1 выводы 9 и 10
Таймер  2 выводы 3 и 11

Если таймер используется для других целей, например для прерывания, то параметры ШИМ соответствующих выводов могут не соответствовать указанным выше.

Поэтому, при использовании библиотек MsTimer2, TimerOne или им подобных некоторые выводы в качестве ШИМ сигналов использовать нельзя.

 

Увеличение частоты и разрядности ШИМ Ардуино.

Система Ардуино устанавливает на всех выводах ШИМ параметры:

  • частота 488,28 Гц;
  • разрешение 8 разрядов (0…255).

Очень низкая частота. Для большинства приложений совершенно не допустимая.

В разработке контроллера элемента Пельтье, начатой в предыдущем уроке, частота ШИМ должна быть не менее 30-50 кГц. В интернете достаточно много предложений по увеличению частоты ШИМВо всех описываются методы увеличения частоты до 31 кГц. В принципе приемлемый вариант, но мне захотелось большего.

Я разобрался с Таймером 1 микроконтроллера ATmega168/328, перевел ШИМ в быстродействующий режим и добился частоты ШИМ Ардуино до 62,5 кГц. Заодно я научился менять разрядность ШИМ. Чтобы в следующий раз не копаться в документации на микроконтроллеры ATmega168/328 я свел всевозможные варианты ШИМ для таймера 1 в таблицу.

Строчки из правого столбца для выбранного варианта необходимо написать в функции setup().

Варианты параметров ШИМ на выводах 9 и 10 Ардуино (таймер 1).

Разрешение Частота ШИМ Команды установки режима
8 бит 62 500 Гц TCCR1A = TCCR1A & 0xe0 | 1;
TCCR1B = TCCR1B & 0xe0 | 0x09;
7 812,5 Гц TCCR1A = TCCR1A & 0xe0 | 1;
TCCR1B = TCCR1B & 0xe0 | 0x0a;
976,56 Гц TCCR1A = TCCR1A & 0xe0 | 1;
TCCR1B = TCCR1B & 0xe0 | 0x0b;
244,14 Гц TCCR1A = TCCR1A & 0xe0 | 1;
TCCR1B = TCCR1B & 0xe0 | 0x0c;
61,04 Гц TCCR1A = TCCR1A & 0xe0 | 1;
TCCR1B = TCCR1B & 0xe0 | 0x0d;
9 бит 31 250 Гц TCCR1A = TCCR1A & 0xe0 | 2;
TCCR1B = TCCR1B & 0xe0 | 0x09;
3 906,25 Гц TCCR1A = TCCR1A & 0xe0 | 2;
TCCR1B = TCCR1B & 0xe0 | 0x0a;
488,28 Гц TCCR1A = TCCR1A & 0xe0 | 2;
TCCR1B = TCCR1B & 0xe0 | 0x0b;
122,07 Гц TCCR1A = TCCR1A & 0xe0 | 2;
TCCR1B = TCCR1B & 0xe0 | 0x0c;
30,52 Гц TCCR1A = TCCR1A & 0xe0 | 2;
TCCR1B = TCCR1B & 0xe0 | 0x0d;
10 бит 1 5625 Гц TCCR1A = TCCR1A & 0xe0 | 3;
TCCR1B = TCCR1B & 0xe0 | 0x09;
1 953,13 Гц TCCR1A = TCCR1A & 0xe0 | 3;
TCCR1B = TCCR1B & 0xe0 | 0x0a;
244,14 Гц TCCR1A = TCCR1A & 0xe0 | 3;
TCCR1B = TCCR1B & 0xe0 | 0x0b;
61,04 Гц TCCR1A = TCCR1A & 0xe0 | 3;
TCCR1B = TCCR1B & 0xe0 | 0x0c;
15,26 Гц TCCR1A = TCCR1A & 0xe0 | 3;
TCCR1B = TCCR1B & 0xe0 | 0x0d;

Следующий скетч генерирует на выводе 9 ШИМ с частотой 62,5 кГц и коэффициентом заполнения примерно 10 %.

void setup() {
  // ШИМ 8 разрядов, 62,5 кГц
  TCCR1A = TCCR1A & 0xe0 | 1;
  TCCR1B = TCCR1B & 0xe0 | 0x09; 
  analogWrite(9, 25); // на выводе 9 ШИМ=10%
}

void loop() {
}

Это максимально возможная частота ШИМ Ардуино для большинства плат (с частотой генератора 16 мГц).

 

В следующем уроке вернемся к разработке контроллера элемента Пельтье.

Предыдущий урок     Список уроков     Следующий урок

14 комментариев на «Урок 37. Широтно-импульсная модуляция в Ардуино.»

  1. приветствую Эдуард. Вот тут. http://avr-start.ru/?p=367. правда на втором таймере получили 125 кГц. Может ветку в форуме откроем. Разработка Ардуино-контроллера элемента Пельтье. Импульсный (ключевой) регулятор напряжения.

    • Я решил первый таймер использовать. С ним и разобрался. А что касается форума — открывайте тему, буду рад. Я собирался написать там про увеличение частоты ШИМ Ардуино.

      • Может я что-то не понимаю. Но максимальная частота в микроконтроллере 16 МГц. Это соответствует периоду 62,5 нс. 62,5 * 256 = 16 мкс. Т.е. при разрядности 8 период ШИМ не может быть меньше 16 мкс или частота выше 62,5 мкс.

          • Я ошибся. Последнее число 62,5 кГц, а не мкс. В остальном все правильно.

          • я думаю что Вы правы если таймер тикает с частотой процессора то 16 000 000 / 256 = 62 500 или 62,5 кГЦ

  2. Спасибо, очень понятно всё написано.
    Правда при испытаниях на ардуино UNO:
    10 бит 1 562,5 Гц и 1 953,13 Гц
    случается странность.
    от 0 до 1024 яркость светодиода плавно растёт, но при значении 255 она увеличивается до максимума.
    for (int i=0; i <= 1024; i++){
    analogWrite(9, i); // устанавливаем значение на 9 ножке
    Serial.println(i);
    delay(100);
    }
    Другие частоты не пробовал.

    • Все режимы я не проверял. Но 10 разрядов на высокой частоте у меня работало. Разрядность ШИМ 8 или именно число 255 неправильно отрабатывается? Максимальное значение ШИМ должно быть 1023.

      • Сергей, а Вы правы. Запустил Вашу программу.

        void setup() {
        // 10 бит 1 562,5 Гц
        TCCR1A = TCCR1A & 0xe0 | 3;
        TCCR1B = TCCR1B & 0xe0 | 0x09;
        }

        void loop() {
        for (int i=0; i < 1024; i++){ analogWrite(9, i); delay(100); } } Посмотрел осциллографом. Все коды отрабатываются правильно, кроме 255. Код 511 тоже работает правильно. У меня предположение такое. Функция analogWrite() некорректно обрабатывает данные разрядностью больше, чем 8. Код 255 при расширении до 16ти разрядов выглядит как 65535, т.е. все 1. Это особенность двоичной знаковой математики. 255 это -1, а -1 при 16ти разрядах это 65535. Происходит расширение знаковой переменной. Я пробовал явно указывать отсутствие знака (unsigned)i. Не помогло. Получается, что необходимо искусственно исключить код 255 или работать с регистрами таймера.

  3. В этой программке в цикле я просто вставил условие что бы прибавить единицу к переменной » i » когда она равна 255 что бы она перескочила сразу на 256. Надо бы ещё проверить одинакова ли разность в уровне сигнала между 253-254 и 254-256. Тогда проблему можно решить только дополнительным условием.
    Хочу применить склеенный светодиод фоторезистор для регулировки тока. С дополнительным измерением тока, путём измерения падения напряжения на резисторе.

    • Правильнее непосредственно с регистрами таймера 1 работать. На форуме я написал как http://mypractic-forum.ru/viewtopic.php?t=15

  4. Я использую такой код для ШИМ:
    /* Вызываем для изменения скважности) */
    void analogWrite16(uint16_t value) { OCR1A = value;}

    /* Вызываем в setup() */
    void setup16bitPWM () {
    pinMode(9,OUTPUT);
    TCCR1A=(1<<COM1A1)|(1<<COM1A0)|(1<<WGM11);
    TCCR1B=(1<<WGM13)|(1<<WGM12)|(1<<CS10); //mode14 FastPwm
    ICR1=65535;
    OCR1A=32768; //50% default value
    }

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

Ваш e-mail не будет опубликован. Обязательные поля помечены *