Dimmer на STM32
- Войдите на сайт для отправки комментариев
Всем добра!
нужно управлять диммером на СТМ32 контроллере. пишу в ардуино IDE.
накидал скетч первый серьезный, и как не странно не работает :)
схема диммера собственного изготовления такая https://forum.cxem.net/uploads/monthly_2018_04/dimm.png.ad23626ebc703607bc55c16a90c08521.png
только с диодным мостом и pc817
вот скетч
volatile int count = 0; volatile int flag = 0; volatile int dim = 0 //int old_flag = 0 #define Z_PIN PA1 // пин на линии EXTI1 dim #define Triak_PIN PA6 void setup() { pinMode(Z_PIN, INPUT_PULLDOWN); pinMode(Triak_PIN, OUTPUT); // Timer3.pause(); // останавливаем таймер перед настройкой Timer3.setPeriod(40); // время в микросекундах (500мс) Timer3.attachInterrupt(TIMER_UPDATE_INTERRUPT, func_tim_3); // активируем прерывание по таймеру Timer3.refresh(); // обнулить таймер Timer3.resume(); // запускаем таймер attachInterrupt(Z_PIN, func_interrup, FALLING); // инициализация прерывания zero-cross } void loop() { digitalWrite(Triak_PIN, flag); dim = 110; // dim = dim + 1; } void func_tim_3() // обработчик прерывания по переполнению таймера { count = count +1; //digitalWrite(Triak_PIN,1); if (count>= dim) { flag = 1; Timer3.pause(); // останавливаем таймер } else { flag = 0; } } void func_interrup() // обработчик прерывания zero-cross { count = 0; Timer3.refresh(); // обнулить таймер Timer3.resume(); // запускаем таймер }
как должен работать:
1. ловим переход через 0, включаем таймер.
2. таймер тикает через с интервалом 40 микросекунд, а в обработчике увеличиваем счетчик.
3. обработчик таймера сравнивает счетчик и нужное число димирования. если счетчик натикал больше числа дим. то подымает флаг.
4. в лупе при поднятом флаге открываем семистр и отключаем таймер,
5. ждем переход через 0 и снова включаем таймер когда сработает внешнее прерывание.
Цикл повторяется.
вроде ничего сложного и все понятно, но не работает.... питаю плату диммера от 3.3в. если подать 3.3в на семистр , лампа светит. задаю дим число до 146 лампа светит, а если задаю 147 и более то не светит совсем
Прошу помощи.....
ИМХО что то с задержками - пока таймер отсчитывает, приходит прерывание от детектора нуля и таймер обнуляется.
никто не запускал димер на плате стм32 ?
и что-то мне подсказывает что я взял за основу скетч с димера на ардуино, и это координально не правильно, но как сделать по другому пока не пойму....
кто знает отзавитесь
скетч нормальный. я бы только включение и отключение таймера из прерываний выкинул, это совершенно лишнее.
а насчет того, почему dim 147 и выше не работает - думаю Komandir близок к истине. Вы детектируете ноль по логическому уровню на пине? - это очень неточный метод, LOW на пине не совпадает с нулем на синусоиде
да я понимаю что не совпадет, хвостики не в счет. а самое интересное что по такому прицыпу у меня на ардуинке 2 димера работают, один на инкубаторе а второй на брудере уже как 2 года.
а тут в чем засада никк не пойму...
Осциллограф поможет - надо глянуть как выглядит сигнал.
нету ослика:(
вот нашел тут кое что, нашел тему . люди делают на двух таймерах и вроди как все работает в фоновом режиме. даже код дали. только это совсем дебри для меня/
ссылка не реклама https://www.radiokot.ru/forum/viewtopic.php?f=59&t=133128&sid=dd2254d0fca1da5b217ebcdc33a8aa5c&start=60
У СТМ32 очень много вариантов тактирования и в каких попугаях в итоге задается параметр в Timer3.setPeriod(40); не ясно. Причем это может зависеть и от среды, пакета ... ... ...
взято тут https://istarik.ru/blog/arduino/105.html
Оперируя предделителем и переполнением можно получать различные интервалы времени. Однако если нет желания заморачиваться с подсчётами, то можно функции setPrescaleFactor() и setOverflow() заменить одной функцией — setPeriod(), которая сделает всё сама, ей нужно только указать время в микросекундах …
мкс — микросекунда (1000000мкс = 1сек).
за 1 секунду прерывание срабатывает 100 раз (полуволны)
1 000 000 мкс /100 =10 000 тиков
чтобы получить 256 максимальное значение для регулирования надо
10 000 тиков /256 = 39.0.... почти 40. вот и вышло отсюда.
получается таймеру надо по 40 мкс натикать 256 раз чтоб поймать следующее прерывание перехода через 0
я правильно это понимаю?
я правильно это понимаю?
еще важно понимать. что функция setPeriod() настраивает период не точно, а из имеющихся вариантов Прескалера и счетчика.
Чтобы узнать. какой точно получился период вашего таймера, после установки периода запросите параметры
Timer3.getOverflow() и Timer3.getPrescaleFactor() и выведите в Монитор
один добрый человек поделился рабочим кодом для стм32 но с делеями.
попробовал и мой димер не заработал и на нем
я чуть чуть подправил его (обьявление прерываний было другое) вечером уже попробую вывести на экран да еще и с этим кодом поработаю.
а вообще мысль закралась что я димер питаю от 3.3 воль а паял я его для 5 вольтового, может какой-то резистор не отрабатывает как надо.?
кстати код переписал и тоже не работает, лампа светится
Это ж stm. Тут немножко другая идеалогия, отличная от avr. В лупе только запись в переменную задержки диммера любым способом. Сам диммер работает чисто аппаратно. Алгоритм примерно такой. В прерывании датчика пересечения нуля настраиваем два или четыре канала таймера соответственно если датчик на полу и полную волну. Первый и третий канал на задержку диммера в диапазонах 0-10 мс и 10-20 мс второй и четвёртый каналы на задерку диммера плюс длительность импульса запуска. Запускаем таймер однократно с нуля на длительность на единицу больше максимальной уставки каналов. В прерываниях каналов только управляем портом - первый третий уставливаем выход второй четвёртый снимаем. Для простоты процесса таймер тактируем мегагерцем и соответственно в каналы пишем значения от 1 до 10000 или от 10001 до 20000.
проверил плату диммера, запустил от ардуино и запитал от 3.3в.. все отлично работает
значит плата в порядке, пошел разбираться с кодом стм-ки
nik182 о если честно то я ничего не понял из вашего сообщения(кроми того что вся архитектура кода не правильная для стм-ки). хотя вам большое спасибо за труд, что ответили... ;
однако на другом форуме читал следующее что можно сделать работу диммера в фоновом режиме, однако я на стм умею работать ножками дергать, или что-то простое и только в ардуино IDE, вот пытаюсь с таймером немнного разобраться. Но что-то мне подсказывает что в ардуино IDE нет возможности осуществить все что надо для димера.
поправьте меня если я ошибаюсь?
вот что мне интересное попалось поделюсь.
взято тут https://www.radiokot.ru/forum/viewtopic.php?f=59&t=133128
нуи еще http://www.cyberforum.ru/arm/thread2354383.html
автор темы даже код похожий на мой написал)))
Да. Описанный алгоритм взаимодействия таймеров возможен, только надо будет или полуволной датчик пересечения нуля делать или третий таймер припахивать для обеспечения четырёх каналов. Советую поставить генератор кода stm32 cubeMX. Там можно сконфигурировать всю перефирию и сгенерить код, который при добавлении всего одной строчки спокойно компилируется в ардуино иде при установленном аддоне от STM. А драйверами LL можно сделать любые действия с регистрами STM. В любом случае решение этой задачи требует знаний регистров таймеров из мануала. Без их изучения все телодвижения обречены на провал. Я попробую написать, но у меня в планах диммер должен управляться через USB, крутилку резистор, показывать на дисплее угол заданный и температуру, стабилизировать заданную температу объекта. Так что пару недель на это уйдет. Вот что куб сделал для двух таймеров. Посмотреть на названия макросов и подобрать аналогичные для аддона мапла. Сответственно РА1 вход полуволнового датчика пересечения нуля, РА6 выход 500 мкс на тиристор. Если в аддоне мапла не найдется сответственной функции надо эти функции писать на CMSYS или бросить этот путь как невозможный на текущем уровне знаний.
заработал на стм32 вот этот скетч. правда кривой с делеями в прерывании, выложу больше для себя чтоб не потерялся.
спасибо за развернутый ответ,
если честно не все понял, это поподробнее не затруднит Вас разжевать?
я уже так и понял что прийдется лезть в регистры, вчера уже листад даташит на камень стм32.
посоветуйте еще что поставить к кубу, кто-то советует HAL, стоит для начинающего в стм?
Eще докладываю. пол дня мучений.
замерил Timer2.getOverflow() = 2880
Timer2.getPrescaleFactor() =1
вот скетч который тестировал, все поубирал оставил только подсчет тиков таймера в периоде между полуволнами
в итоге это значение прыгает от 0 до 145, почему так не знаю (как-то таймер ведет себя не понятно). если посчитать количество полуволн за секунду получается примерно 100 +-2