В предыдущих постах
https://pikabu.ru/story/arduino_i_upravlenie_moshchnoy_nagru...
https://pikabu.ru/story/arduino_i_upravlenie_moshchnoy_nagru...
Было рассмотрено управление мощной нагрузкой в бытовой сети переменного тока с применением алгоритма Брезенхема. Чем эта тема показалась интересной? Да тем, что таким образом можно плавно управлять любым нагревателем. Это может быть электроплита, нагреватель для воды или отопление. Несмотря на то, что речь шла лишь об идее, меня подвергли достаточно серьезной критике, в основном, из-за кода. Поэтому я решил выложить несколько вариантов исправленного кода, который был проверен на работе устройства с ПИ-регулятором. Кроме того, я смотрел время выполнения и временные ошибки/сдвиги, возникающие при его работе. Смысл кода таков - получаем данные о мощности с ПИ-регулятора в % мощности (0-100), передаем команды на плату симистора (или твердотельное реле SSR):
1. Тот самый проверочный код, который я использовал изначально, с deley(). Устройство работает отлично, точность +-0,25 градусов. Каждую секунду отстает на 3мс.
2. Второй вариант, без deley(), с двумя таймерами на millis() (10мс и 1 сек). То же самое, +-0,25 градусов, отстает на 3мс каждую секунду.
https://ideone.com/jPiEHA
3. Третий вариант. Один таймер на millis() (10 мс). Собственно, никаких изменения в работе.
https://ideone.com/9GPxpU
4. Немного экзотики - с помощью библиотеки <TimerOne.h>. Все работает так же, только каждую секунду почему-то обгоняет millis() на 1мс.
https://ideone.com/Www1kw
Таким образом, практика показывает, что поскольку временные сдвиги незначительны и особой роли не играет то, что раз в 3-4 секунды будет на одну полуволну меньше. Безусловно все варианты, кроме первого - предпочтительнее, так как контроллеру можно еще что-то поручить, кроме формирования сигнала для симистора.
Кроме того, было предположение, что даже включение и выключение симистора происходит только при прохождении через 0, все равно, работа такого аппарата будет плохо влиять на сеть и другие бытовые приборы, включенные в нее. Было предложено не распределять полуволны равномерно по алгоритму, а просто раз в секунду включать и выключать, выдавая от 1 до 100 полуволн подряд. Ну что ж. Давайте и такой вариант попробуем.
5. Сначала вариант, который занимается только сигналом, простаивая в остальное время. Работает неплохо, почему-то обгоняет millis() на 1мс. Но это решается установкой временной отсечки на 1мс меньше. Точность уменьшилась. Теперь ПИ-регулятор выдает +-0,5 градуса. Возможно его нужно немного "ограничить".
https://ideone.com/ncetkP
6. Тоже вариант с длинным импульсом, но уже запускаемый по millis() каждую секунду. Длительность импульса тоже по millis(). По точности поддержания температуры то же самое, а по временным отсечкам работает четко.
https://ideone.com/WEbo3O
Было и еще предложение для "длинного" импульса использовать длинный ШИМ с периодом в 1 секунду. Но это уже лишнее. Кстати, я пробовал сделать с длинным импульсом также с помощью таймеров библиотек MsTimer2 и TimerOne. Но странное дело. Высокий уровень то появляется на пинах, то нет. Причем хаотично. Не стал разбираться, и так вариантов много, а библиотеки - зло.)
Теперь, думается каждым может себе выбрать вариант управления по своему вкусу. Еще немного удивился, многие меня критиковали, даже ругали, но свой вариант кода предложил лишь @nstorm , за что ему спасибо.