Одиночный импульс

eXL
Offline
Зарегистрирован: 23.07.2017

Может кто подскажет, как выдать на ногу короткий импульс. Предположим на 3 пине назначенном входом стояла единица и сменилась на ноль, при таком событии нужно выдать положительный импульс 1 сек. на 10 пине назначенном выходом.

Клапауций 112
Клапауций 112 аватар
Offline
Зарегистрирован: 01.03.2017

eXL пишет:

Может кто подскажет, как выдать на ногу короткий импульс. Предположим на 3 пине назначенном входом стояла единица и сменилась на ноль, при таком событии нужно выдать положительный импульс 1 сек. на 10 пине назначенном выходом.

при изменении логического состояния пина 3 с единицы на ноль.

eXL
Offline
Зарегистрирован: 23.07.2017

Клапауций 112 пишет:

при изменении логического состояния пина 3 с единицы на ноль.

Не понял ?

Клапауций 112
Клапауций 112 аватар
Offline
Зарегистрирован: 01.03.2017

eXL пишет:

Не понял ?

ок. вторая попытка:

Клапауций 112 пишет:

при изменении логического состояния пина 3 с единицы на ноль.

 

 

Jeka_M
Jeka_M аватар
Offline
Зарегистрирован: 06.07.2014

Можно двумя способами:

1) Поллинг. Периодически в цикле опрашиваете пин с помощью digitalRead() и по условию if выполняете нужное действие.

2) Прерывание. Настраиваете с помощью attachInterrupt() в режим FALLING. В обработчике прерывания выполняете нужное действие.

Клапауций 112
Клапауций 112 аватар
Offline
Зарегистрирован: 01.03.2017

Jeka_M пишет:

Можно двумя способами:

1) Поллинг. Периодически в цикле опрашиваете пин с помощью digitalRead() и по условию if выполняете нужное действие.

2) Прерывание. Настраиваете с помощью attachInterrupt() в режим FALLING. В обработчике прерывания выполняете нужное действие.

чем эти два способа отличаются от предложенного мной?

eXL
Offline
Зарегистрирован: 23.07.2017

Jeka_M пишет:

Можно двумя способами:

1) Поллинг. Периодически в цикле опрашиваете пин с помощью digitalRead() и по условию if выполняете нужное действие.

 

Вот так я и пробую делать, получается не один импульс, а в цикле, пока работает программа. 8-(

Jeka_M
Jeka_M аватар
Offline
Зарегистрирован: 06.07.2014

Значит программа неправильно написана.

Jeka_M
Jeka_M аватар
Offline
Зарегистрирован: 06.07.2014

Клапауций 112 пишет:

чем эти два способа отличаются от предложенного мной?

Когда писал ответов в теме ещё не было.

eXL
Offline
Зарегистрирован: 23.07.2017

Jeka_M пишет:

Значит программа неправильно написана.

Я понимаю что не правильно, вот и спрашиваю как сделать правильно ?

Я еще только пытаюсь изучать программирование, так что может быть какая-то самая простейшая ошибка,

а я заблудился.

delay(2000) ;
  digitalWrite(8, HIGH) ; //выход управления нагревом вкл.
  digitalWrite(10, LOW) ; //выход управления таймером выкл.
  digitalWrite(12, HIGH) ; //выход индикации включения нагревателя вкл.
  if (digitalRead(3) == LOW) ;  // термостат достиг нужной температуры и выключился
  {
  digitalWrite(10, HIGH) ;  // выдаем импульс
  delay(500) ;              // 0,5 секунды
  digitalWrite(10, LOW) ;   // на включение таймера
  }

Клапауций 112
Клапауций 112 аватар
Offline
Зарегистрирован: 01.03.2017

Jeka_M пишет:

Клапауций 112 пишет:

чем эти два способа отличаются от предложенного мной?

Когда писал ответов в теме ещё не было.

ок.

Клапауций 112
Клапауций 112 аватар
Offline
Зарегистрирован: 01.03.2017

eXL пишет:

Я понимаю что не правильно, вот и спрашиваю как сделать правильно ?

нужно завести две переменные:

предыдущее состояние пина 3 = digitalRead(3);

настоящее состояние пина 3 = digitalRead(3);

и сравнивать их в цикле, в случае неравенства выполнять нужное тебе действие и обновлять предыдущее состояние до настоящего - так что-то будет исполняться один раз и при изменении состояния пина 3.

если тебе нужно что-то делать, когда логическое состояние пина 3 равно ноль, то добавляешь это условие к вышеописанной проверке.

*делаи в топку.

Jeka_M
Jeka_M аватар
Offline
Зарегистрирован: 06.07.2014

Либо завести одну переменную-флаг (напр. flag=0) и хранить в ней состояние срабатывания. Но сделать два условия if. В условии_1 ожидаем низкий уровень (LOW) на пине 3 и сброшенный флаг (flag==0). Если условие_1 выполнено - подаем импульс и устанавливаем флаг (flag=1). А в условии_2 ожидаем высокий уровень (HIGH) на пине 3 и установленный флаг (flag==1). Если условие_2 выполнено - сбрасываем флаг (flag=0).

P.S. В одном условии if можно сравнивать сразу несколько значений (Логические операторы).

Клапауций 112
Клапауций 112 аватар
Offline
Зарегистрирован: 01.03.2017

если хочется готового, то юзаешь переменную state_inactivity_Up настроив duration_inactivity_Up(1000) - digitalWrite(10, test.state_inactivity_Up());

#403

mag155
Offline
Зарегистрирован: 21.12.2017

Доброго времени суток! Как поймать короткий импульс (в одну мелисикунду ) запустит счетчик и по истечению счетчика дать импульс на выход ? И так ловить несколько импульсов на разных входах ?

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

По прерываниям.

mag155
Offline
Зарегистрирован: 21.12.2017

По прерываниям делал на уно два входа прерывания. Проблема первая не хватает одного входа прерывания, проблема вторая импульсы приходят один за другим. И при максимальной задержке после первого импульса, уже прилетает третий. То есть второй просто пропускаем. Думаю может взять три отдельных ардуино мини типа по одной на импульс как считаете ?

sadman41
Offline
Зарегистрирован: 19.10.2016

Не знаю, чем вам это поможет, но: https://playground.arduino.cc/Main/PinChangeInterrupt

И уберите delay() из кода, чтобы не пропускать второй. 

DetSimen
DetSimen аватар
Offline
Зарегистрирован: 25.01.2017

155, открой для себя PCINT.

mag155
Offline
Зарегистрирован: 21.12.2017

Окей будем изучать .

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

mag155 пишет:
По прерываниям делал на уно два входа прерывания. Проблема первая не хватает одного входа прерывания,

Это не проблема. На Уно можно ловить прерывания на каждом из 20 входов.

Цитата:

проблема вторая импульсы приходят один за другим. И при максимальной задержке после первого импульса, уже прилетает третий. То есть второй просто пропускаем.

С одной стороны - чудес не бывает. И у контроллера есть некоторое минимальное время реакции на обработку прерывания. Если интервал между импульсами меньше этого времени, то в работу устройства неизбежно будут вноситься искажения. Насколько существенные - зависит от задачи.

Но настораживает употребленный Вами термин "задержка" в контексте обсуждения прерываний, особенно с определением "максмиальная". Поэтому первое подозрение, что Вы неправильно написали обработчик прерывания, а именно, внесли в него искусственную задержку.

Цитата:

Думаю может взять три отдельных ардуино мини типа по одной на импульс как считаете ?

Это зависит от задачи. С одной стороны, при этом Вы сможете гарантировать отсутствие потерь импульсов, но с другой - реакция на импульсы может получиться замедленной (если в одном месте необходимо иметь информацимю обо всех трех. В противном случае задача об обработке трех импульсов вообще не стоит).

mag155
Offline
Зарегистрирован: 21.12.2017

Здача в том чтобы получать три импульса ( трех фазной сети по импульсу каждой из фаз ) и выдавать соответствующей фазе импуль на свой выход . НО когда мы поймали  первый импульс мы должны мочь регулировать время срабатывания соответсвующего выхода ( поймали. подождали. дали импульс на свой выход и так со всеми тремя ) Но самое интиресное то что для минимальной мощности задержка по первому импульсу по времени будет больше чем время прихода второго импульса тоесть в идеале эти три импульса и их задержки должны работать не зависимо друг от друга. А если я правильно понимаю контроллер не может обрабатывать одновременно три задачи только последовательно. Тоесть таймеры здесь тоже не помогут . Но я могу заблуждатся так что если есть идеи поделитесь а то зашел в тупик ??? 

Efim
Offline
Зарегистрирован: 04.05.2018

mag155

Как вы определяете импульс на фазе? Точнее какими средствами вы это делаете?

А лучше опишите устройство которое пытаетесь сделать. И что оно должно делать.

sadman41
Offline
Зарегистрирован: 19.10.2016

Без кода тут вообще нечего говорить. Что там в обработчике происходит - известно только писателю (в лучшем случае). Может он туда делеев напихал, а теперь спрашивает почему пропускаются прерывания.

SLKH
Offline
Зарегистрирован: 17.08.2015

mag155 пишет:

Здача в том чтобы получать три импульса ( трех фазной сети по импульсу каждой из фаз ) и выдавать соответствующей фазе импуль на свой выход . НО когда мы поймали  первый импульс мы должны мочь регулировать время срабатывания соответсвующего выхода ( поймали. подождали. дали импульс на свой выход и так со всеми тремя ) Но самое интиресное то что для минимальной мощности задержка по первому импульсу по времени будет больше чем время прихода второго импульса тоесть в идеале эти три импульса и их задержки должны работать не зависимо друг от друга. А если я правильно понимаю контроллер не может обрабатывать одновременно три задачи только последовательно. Тоесть таймеры здесь тоже не помогут . Но я могу заблуждатся так что если есть идеи поделитесь а то зашел в тупик ??? 

Фазоимпульсное управление нагревателем? http://arduino.ru/tutorials/BlinkWithoutDelay

Efim
Offline
Зарегистрирован: 04.05.2018

Возможно делитель частоты хочет изготовить) 

mag155
Offline
Зарегистрирован: 21.12.2017

Устройство простое трех фазный выпрямитель.

Вот написал без прирывания работает тоесть успевает. Теперь думаю таймер на миллис потом все это в функцию еоторую буду вызывать прерыванием ?

if(digitalRead(6)==HIGH)
 {
 digitalWrite(8,HIGH);
 }
else {
 digitalWrite(8,LOW);
 
 }
if(digitalRead(4)==HIGH)
 {
 digitalWrite(9,HIGH);
 }
else {
 digitalWrite(9,LOW);
 }
if(digitalRead(5)==HIGH)
 {
 digitalWrite(10,HIGH);
 }
else {
 digitalWrite(10,LOW);
 }

 

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

Если все работает, зачем что-то дописывать?

 

PS. И - да, если речь идет о промышленной сети 50 Гц, то расстояние между пиками порядка 5-7 мс. Если прерывание не успевает, значит, оно неправильно написано.

mag155
Offline
Зарегистрирован: 21.12.2017

Чета запарился совсем 

void blink()
{
 
if(digitalRead(6)==HIGH){
 led1OnTime = micros();
if( micros()- led1OnTime > interval) {

 digitalWrite(8,HIGH);
}
  }
else {
 digitalWrite(8,LOW);
 
 }

Как дописать миллис граматно ?

mag155
Offline
Зарегистрирован: 21.12.2017

Не стабильно так работает 

mag155
Offline
Зарегистрирован: 21.12.2017

Попил кофе и вот че получилось 

if(digitalRead(6)==HIGH){
 if (micros() - timing >1000 ){ 
  timing = micros();
 digitalWrite(8,1);
}
  }
else {
 digitalWrite(8,LOW);
 
 }

Только че то в функции не хочет работать ???

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

Программа всегда работает так, как ее написал программист. Но не всегда это совпадает с тем, как он хотел ее написать.

mag155
Offline
Зарегистрирован: 21.12.2017

Написал для теста не дилей вот так 

void blink()
{


if(digitalRead(6)==HIGH){

 delayMicroseconds(Dimmer);
 digitalWrite(8,1);


}
else {

 digitalWrite(8,LOW);

 }

Как вместо дилей вкинуть миллис потому как стандартно не хочет миллис тут работать ?

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

Чтобы использовать millis с пользой, нужно в корне менять идеологию рпаботы программы.

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

mag155
Offline
Зарегистрирован: 21.12.2017

Напишите примерчик хотя бы в общих чертах пожалуйста.?

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

Посмотрите blink without delay

mag155
Offline
Зарегистрирован: 21.12.2017

Ок благодарю

mag155
Offline
Зарегистрирован: 21.12.2017

Вы имеете в виду записать условием типа если Выкл то вкл ?

sadman41
Offline
Зарегистрирован: 19.10.2016

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

mag155
Offline
Зарегистрирован: 21.12.2017

Дак у меня на вход прерывания приходят три импульса нужно еще определять какой импульс вызвал прерывание .?

mag155
Offline
Зарегистрирован: 21.12.2017

В обработчике я так понял определяем какой импульс ставим флаг потом в лупе ждем и даем импульс.?

sadman41
Offline
Зарегистрирован: 19.10.2016

На вход какого прерывания приходит три импульса? У вас что, все zero-cross на один вход заведены?

mag155
Offline
Зарегистрирован: 21.12.2017

У меня через диодное или все три прирывания заведены на один вход нулевой вход прерывания . Еще эти же три импульса заведены каждый на свой вход. Идея такая чтоб любой из импульсов вызывал прерывание а уже в обработке прерываний определяем по какому из трех входов прошло прерывание ждем и даем импульс.

mag155
Offline
Зарегистрирован: 21.12.2017

Я так понимаю нужно в обработчике определять по какому входу импульс и подымать свой флаг. В лупе ждать потом определять какой флаг поднят и давать импульс. Как считаете ?

sadman41
Offline
Зарегистрирован: 19.10.2016

Оригинальная схемотехника, конечно, но в целом делайте, как получается - поднимайте свой флаг для каждого и давайте в лупе импульс. Хотя, конечно, с PCINT было бы побыстрее все, чем с digitalRead(). Но - начните с малого, потом улучшайте.

mag155
Offline
Зарегистрирован: 21.12.2017

С PCINT не разу не работал но планирую разобраться. Я так понял что смысл там похож на прерывания .?

mag155
Offline
Зарегистрирован: 21.12.2017

Еще вопрос такой в прерывании не работает миллис. Но почему нельзя использовать миллис в функции напрямую без loop .?

sadman41
Offline
Зарегистрирован: 19.10.2016

Почему похож? Это и есть механизм обработки прерываний, только обработчик вызывается при любом изменении любой ноги во всем порту (PORTD, например). Остается только битовой операцией отследить пришел ли импульс на нужную ногу. 

sadman41
Offline
Зарегистрирован: 19.10.2016

mag155 пишет:
Еще вопрос такой в прерывании не работает миллис. Но почему нельзя использовать миллис в функции напрямую без loop .?

Потому что millis() - это функция, возвращающая значение некоей внутрисистемной переменной языка Wiring. А  увеличивается значение этой переменной по прерыванию, вызываемому аппаратным таймером. В любом обработчике прерываний остальные прерывания не выполняются. Поэтому пока выполняется любой обработчик - значение millis() не будет меняться. Вне обработчика используйте ее хоть в лупе, хоть в сетапе, хоть в любой другой функции.

mag155
Offline
Зарегистрирован: 21.12.2017

Аааа то есть если я бы привязал свою функцию к примеру к кнопке все бы работало а так как она привязана в прерыванию миллис и не работает. Я понял благодарю за разъяснение.

nik182
Offline
Зарегистрирован: 04.05.2015

Генерить в loop импульсы для тиристорного выпрямителя тупиковый путь. При обработке кнопок или других действиях будут сбои. Надо по импульсу пересечения нуля одной фазой заряжать таймер на время задержки зажигания тиристора и в прерывании таймера выставлять ногу и заряжать таймер на длительность открытия тиристора (обычно 50 мкс для оптосиммисторов управления) по окончании снимать ногу и выставлять таймер на 6.6 мс и опять импульс 50 мкс на вторую ногу и через 6.6 мс на третью.Затем всё сбрасывать и ждать следующего пересечения с нулём. Ждать паресечения с нулём всех трёх фаз не обязательно. Фазы смещены с хорошей точностью на 6.(6)мс. И импульсы зажигания также. 

В прерывании millis() выдаёт значение. Глючить начинает, если чужое прерывание длинее 8 мкс.