Позволяет ли Ардуино на одном прерывании отслеживать оба фронта?
- Войдите на сайт для отправки комментариев
Чт, 11/07/2019 - 08:01
Как пример:
void setup () { // Всяк разные установки и объявления attachInterrupt(0, SWITCH_ON, RISING); attachInterrupt(0, SWITCH_OFF, FALLING); } void loop () { // Тело программы } void SWITCH_ON () { digitalWrite(pinOut, HIGH); } void SWITCH_OFF () { digitalWrite(pinOut, LOW); }
Может ли один и тот же пин прерывания отслеживать передний и задний фронты управляющего импульса? Не нашел (подскажите). Или неправильно искал (ткните носом в ссылочку, где почитать).
Заранее спасибо!
По моему 5 строка отменяет четвертую....
Может быть надо в самом прерывании менять фронты?
Или если не контролировать куда изменился сигнал то просто
CHANGE ?
Sonologist, так нельзя. Либо паралелить 2 пина, либо в режим CHANGE и в теле прерывания перечитать порт, и узнать что его вызвало.
По моему 5 строка отменяет четвертую....
Вот как раз про это я и спросил.
Sonologist, так нельзя. Либо паралелить 2 пина, либо в режим CHANGE и в теле прерывания перечитать порт, и узнать что его вызвало.
Правильно ли я понял, что после события CHANGE надо проверить состояние пина: если оно HIGH, то пришедший CHANGE был передним фронтом, если LOW- то задним. И в зависимости от этого плясать? В принципе - тоже вариант.
Правильно ли я понял, что после события CHANGE надо проверить состояние пина: если оно HIGH, то пришедший CHANGE был передним фронтом, если LOW- то задним. И в зависимости от этого плясать? В принципе - тоже вариант.
ну да, вариант - но можно не успеть
Да, только к сожалению, проверять надо не сразу после вызова прерывания, а с небольшой задержкой. Сигнал на ноге после фронта может болтается несколько сотен наносекунд и этого хватает чтобы ошибиться со значением. digitalRead уже хватает на нормальное чтение, а вот прямого чтения из регистра PINx иногда нет.
ну да, вариант - но можно не успеть
В моем случае "не успеть" не проблема. Поясню. Имеется детектор перехода через ноль. Обычно его импульс стараются сделать как можно тоньше и как можно ближе к истинному переходу через ноль. У меня же задача при приходе переднего фронта успеть просчитать, надо ли пропускать в нагрузку очередной полупериод или нет. Чтобы времени было достаточно, детектор нуля надо сделать как раз весьма не идеальным. То есть, чтоб передний фронт заметно опережал истинный переход через ноль. А по фронту спада (он точно так же заметно отстает от перехода через ноль) вырубить управляющий импульс триака. На следующем переходе через ноль триак сам заткнется. Так что, если импульс детектора будет длиной (шириной) 1-2 мсек, времени на расчеты хватит с головой.
Да, только к сожалению, проверять надо не сразу после вызова прерывания, а с небольшой задержкой. Сигнал на ноге после фронта может болтается несколько сотен наносекунд и этого хватает чтобы ошибиться со значением. digitalRead уже хватает на нормальное чтение, а вот прямого чтения из регистра PINx иногда нет.
Тут вопрос решен уже. Я беру сигнал не непосредственно с детектора нуля, а с триггера на его хвосте, то есть дребезг убран аппаратно: идеальный меандр.
Идеально меандра небывает. У Вас есть емкость монтажа, индуктивность проводников и выходное сопротивление генератора меандра. Хорошим осцилографом видно что в таких условиях на фронте импульса всегда есть очень высокочастотные колебания. На этот эффект я как раз и нарвался, когда исследовал почему моргает лампочка за тирристорным регулятором на тиньке, если в прерывании всести проверку на уровень сигнала после фронта.
В моем случае "не успеть" не проблема. Поясню. Имеется детектор перехода через ноль. Обычно его импульс стараются сделать как можно тоньше и как можно ближе к истинному переходу через ноль. У меня же задача при приходе переднего фронта успеть просчитать, надо ли пропускать в нагрузку очередной полупериод или нет. Чтобы времени было достаточно, детектор нуля надо сделать как раз весьма не идеальным. То есть, чтоб передний фронт заметно опережал истинный переход через ноль. А по фронту спада (он точно так же заметно отстает от перехода через ноль) вырубить управляющий импульс триака. На следующем переходе через ноль триак сам заткнется. Так что, если импульс детектора будет длиной (шириной) 1-2 мсек, времени на расчеты хватит с головой.
Если мы говорим о сетевом напряжении, то там все настолько медленно, с точки зрения процессора, все меняется, что воротить какие-то сложные вещи смысла нет. Обычной оптопары и прерывания по LOW достаточно что бы все успеть. Тем более, что прерывание срабатывает чуть раньше, чем на самом деле переход через ноль случается.
Я делал так
В прерывании читал 5 раз подряд состояние пина, если все разы 0, то запрещал прерывания от сети на 10мс и делал рассчет по Брезинхему - запускать или не запускать симистор.
Для разрешения прерывания обратно через 10мс я использовал 1мс таймер. По началу я им же пользовался для ограничения длинны импульса открывания симистора. Но потом поэкспериментировал и забил. Просто держу его HiGH до конца полуволны.
Идеально меандра небывает. У Вас есть емкость монтажа, индуктивность проводников и выходное сопротивление генератора меандра. Хорошим осцилографом видно что в таких условиях на фронте импульса всегда есть очень высокочастотные колебания. На этот эффект я как раз и нарвался, когда исследовал почему моргает лампочка за тирристорным регулятором на тиньке, если в прерывании всести проверку на уровень сигнала после фронта.
Да идеального не бывает, но то, что я сейчас имею вполне себе адекватно отрабатывает. Слава Богу :)
Если мы говорим о сетевом напряжении, то там все настолько медленно, с точки зрения процессора, все меняется, что воротить какие-то сложные вещи смысла нет....
...Я делал так
В прерывании читал 5 раз подряд состояние пина, если все разы 0, то запрещал прерывания от сети на 10мс и делал рассчет по Брезинхему - запускать или не запускать симистор.
Для разрешения прерывания обратно через 10мс я использовал 1мс таймер. По началу я им же пользовался для ограничения длинны импульса открывания симистора. Но потом поэкспериментировал и забил. Просто держу его HiGH до конца полуволны...
Я использовал два фронта по совету соконфетников. В сетапе воткнул "attachInterrupt(0, TRIAC, CHANGE);"
а в коде функции прерывания смотрел, высокий уровень на входе или низкий. Таким образом было понятно, какой чендж восходящий, какой - нисходящий. Соответственно, по восходящему решал, надо ли следующий полупериод протолкнуть в нагрузку или нет, а по нисходящему в любом случае вырубал импульс управления триаком. Понимаю, что по неопытности сделал все слишком "в лоб", можно было, наверное, извернуться изящнее. Но пока так. Ночь девайс проработал без сбоев, зависаний и т.д. Код (может, кому понадобится?):
Есть оптроны с двумя светодиодами, например PC814. Вот их обычно и применяют для детектирования нуля. Если Вам нужно максимально быстрый код, то учтите, что команды digitalWrite () занимают 6 -8 мкс, лучше управлять пинами через PORTx= -всего-то пара тактов.. Аналогично digitalRead выполняются за 4-6 мкс, а PINx - за пару тактов, или за так, не помню точно.
Есть оптроны с двумя светодиодами, например PC814. Вот их обычно и применяют для детектирования нуля. Если Вам нужно максимально быстрый код, то учтите, что команды digitalWrite () занимают 6 -8 мкс, лучше управлять пинами через PORTx= -всего-то пара тактов.. Аналогично digitalRead выполняются за 4-6 мкс, а PINx - за пару тактов, или за так, не помню точно.
Все правильно. Я уже прочитал про такое. Но в моем случае речь идет о периодах 1-3 мсек, поэтому можно пока обойтись посконными методами, максимально быстрый код не нужен :) Про 814 я тоже в курсе, но лень было ехать в чипдип, когда в ящике валяется десятка полтора 4N25 и столько же диповских мостиков. ..
Зачем вообще в таком устройстве (нагревателе), у которого инерция опупительная , отслеживать переход через 0 ?
Там ШИМ на digitalWrite'ах 2секундный точно так же будет работать.