ОБНОВЛЕНИЯ
- v1.2 — исправлены мелкие ошибки с совместимостью
ТЕОРИЯ
Иногда требуется управлять мощностью инерционной нагрузки (ИК станция, сетевой обогреватель в комнате/инкубаторе, паяльник), и для этого совсем не хочется использовать высокочастотный ШИМ. В случае питания от сети — делать диммер тоже не очень целесообразно, потому что инерционной нагрузкой можно управлять при помощи низкочастотного ШИМ и обычного твердотельного реле, без создания сложных схем и лишнего усложнения кода проекта детектором нуля. Если опустить частоту ШИМ до 1 Гц, никакого писка мы не услышим (писк слышно в диапазоне 500 Гц — 14 кГц), но нагрузка будет замечательно управляться, особенно если это большой нагревательный элемент. Решил я сделать простенькую библиотеку для генерации программного сверхнизкочастотного ШИМ сигнала.
Сам алгоритм очень прост: обычный таймер на миллис с переменным периодом.
if (millis() - _tmr >= (_flag ? _activePeriod : (_period - _activePeriod))) { _tmr = millis(); _flag = !_flag; digitalWrite(_pin, _flag ^ _dir); }
В этом алгоритме:
- _flag — флаг состояния, bool
- _tmr — переменная времени, uint32_t
- _dir — направление, bool
- _pin — пин реле, byte
- _period — общий период реле, int
- _activePeriod — активный период (длительность импульса), int. Определяется как _period, умноженный на скважность (число от 0.0 до 1.0, соответствует 0-100%)
БИБЛИОТЕКА
- Встроенный таймер на millis()
- Для работы системы нужно просто почаще вызывать tick()
- Установка параметров ШИМ:
- Настройка периода (обратно частоте)
- Настройка длины импульса (скважности) в диапазоне 0-255
- Настройка уровня реле
Поддерживаемые платформы: все Arduino (используются стандартные Wiring-функции)
УСТАНОВКА
- Библиотеку можно найти и установить через менеджер библиотек по названию PWMrelay в:
- Arduino IDE (Инструменты/Управлять библиотеками)
- Arduino IDE v2 (вкладка «Library Manager»)
- PlatformIO (PIO Home, вкладка «Libraries»)
- Про ручную установку читай здесь
ДОКУМЕНТАЦИЯ
Создание объекта
Объект регулятора можно создать тремя способами:
PWMrelay имя(пин);
- создать с указанием пина реле (цифра номер пина)PWMrelay имя(пин, уровень);
- создать с указанием пина и уровня (уровень HIGH и LOW)PWMrelay имя(пин, уровень, период);
- создать с указанием пина, уровня и периода ШИМ (в миллисекундах)
Настройка параметров
Параметры ШИМ можно настроить по ходу работы в любое время:
setPWM(byte duty);
- установка заполнения шим, 0-255 (соответствует 0-100%)setPeriod(int period);
- установка периода ШИМ в миллисекундах. 1000 соответствует 1 Гц и так далееsetLevel(bool level);
- установка уровня реле,HIGH
иLOW
Тик
Метод
tick();
осуществляет все расчёты времени по встроенному таймеру и сам включает/выключает реле, достаточно просто вызывать его в основном цикле loop. Если в лупе у вас замкнутые места или задержки, tick()
можно поместить в прерывание таймера. Период прерываний нет смысла ставить чаще, чем период ШИМ-реле, делённый на 255. PWMrelay(byte pin, bool dir, int period); // пин, уровень реле HIGH/LOW, период void tick(); // тик, вызывать как можно чаще, сам управляет реле void setPWM(byte duty); // установить величину ШИМ, 0-255. При значении 0 и 255 тик неактивен! byte getPWM(); // возвращает величину ШИМ void setPeriod(int period); // установить период ШИМ в миллисек. (по умолч. 1000мс == 1с) int getPeriod(); // получить период void setLevel(bool level); // установить установить уровень реле (HIGH/LOW)
ПРИМЕРЫ
Остальные примеры смотри в папке examples библиотеки, также примеры можно открыть из Arduino IDE/Файл/Примеры
#include "PWMrelay.h" PWMrelay relay(13); // реле на 13 пине // или так // PWMrelay relay(13, HIGH); // реле высокого уровня на 13 пине // PWMrelay relay(13, HIGH, 2000); // реле высокого уровня на 13 пине, период 2 секунды void setup() { Serial.begin(9600); relay.setLevel(HIGH); // можно поменять уровень реле (HIGH/LOW) relay.setPeriod(1000); // можно поменять период, миллисекунды relay.setPWM(20); // задаём сигнал ШИМ 0-255 } void loop() { // вызываем в лупе, данная функция сама управляет реле relay.tick(); }
#include "PWMrelay.h" PWMrelay heater1(4); PWMrelay heater2(5); void setup() { heater1.setPWM(20); // задаём сигнал ШИМ 0-255 heater2.setPWM(120); // задаём сигнал ШИМ 0-255 } void loop() { heater1.tick(); heater2.tick(); }
ПОДДЕРЖАТЬ
Вы можете поддержать меня за создание доступных проектов с открытым исходным кодом, полный список реквизитов есть вот здесь.