Официальный сайт компании Arduino по адресу arduino.cc
Счетчик количества сигналов
- Войдите или зарегистрируйтесь, чтобы получить возможность отправлять комментарии
Чт, 27/10/2016 - 19:34
Доброго времени суток!
Подскажите, пожалуйста, новичку как запрограммировать счетчик количества сигналов на входе: т.е на несколько входов с рандомной и не постойнной частотой будут приходить сигналы, нужно посчитать количество пришедших сигналов на каждый вход и выводить сигнал на экран компьютера...
Я попытался написать скетч, но сегодня начал анализировать работу и понял, что ошибка моя в том, что я проверяю в "сработанном" ли состоянии входной сигнал, а сигнал может просто быть длительно подан и при этом мой счетчик будет постоянно считать, т.е работать скетч будет не верно...
Прошу подсказать, как правильно сделать счетчик импульсов для нескольких входных сигналов.
int vhod_A = 13; int vhod_B= 8; /*входы для принятия сигналов мигания того или иного выхода счетчика.*/ void setup () { pinMode (vhod_A, INPUT); pinMode (vhod_B, INPUT); Serial.begin (9600); } void loop() { kol_A=0; kol_B=0; If (digitalRead (vhod_A) == HIGH) { kol_A++; } If (digitalRead (vhod_B) == HIGH) { kol_B++; Serial.println (“kol_A”); Serial.println (“kol_B”); }
Ну, если у Вас только два входа, повесьте их на прервания по RISING и считайте на здоровье.
входа всего будет 4... спасибо за информацию, посмотрю как использовать RISING...
Будет ли работать скетч, если его подправить так:
Нет, конечно, с чего бы это digitalRead возвращал что-либо отличное от HIGH и LOW.
если не пользоваться прерываниями, то Вам просто надо отдельно обрабатывать появление сигнала и ео исчезновение.
входа всего будет 4... спасибо за информацию, посмотрю как использовать RISING...
Будет ли работать скетч, если его подправить так:
почитайте
http://arduino.ru/Reference/AttachInterrupt
Попробуйте так
vosara. C флагом не очень удачно получилось. Не когда на входе O то счета не будет. А вот если 1 , то считать будет не сигналы а проходы loop(). Точнее 2 прохода +1 на счетчик.
qwone - Да Вы правы просмртрел исправил
Спасибо за ответы!
при помощи attachInterrupt() можно на плате UNO сделать счетчик только для 2х входов , как я понял из описания.
Спасибо большое vosara за скетч, проверю в ближайшие дни работоспособность счетчика, основанного на логике данного скетча.
Любопытно, какую максимальную частоту сможет "уследить" ардуино...
Попробовал залить скетч и что-то пошло не так...
Немного усложнил задачу - добавил дополнительное условие: при условии достижения счетчика (kol_A) мигания до 10 - записываем новое значение - количество детятков "миганий" (импульсов на входе), причем если мы запросим вводом любого значения в окно программы - выдавать количество десятков импульсов, полученных на входе...
Скетч добавляю.
1) Подаю 3,3 вольта с выхода ардуинки перемычкой на вход 5.
ПНапример, по моей логике, например, если я "закорочу" 3,3 В и 5вход 15 раз - должно на экране показать значение 1,5..
Выводит неверные значения - в чем ошибка, как исправить, подскажите, пожалуйста?
2) второй вопрос: как сделать чтобы выводилось значение на экран только однократно, а не постоянным потоком сообщений в диалоговом окне?
1) Подаю 3,3 вольта с выхода ардуинки перемычкой на вход 5.Например, по моей логике, например, если я "закорочу" 3,3 В и 5вход 15 раз - должно на экране показать значение 1,5.Выводит неверные значения - в чем ошибка, как исправить, подскажите, пожалуйста?
Вы что дурку гоняете. На вход надо подавать логический сигнал, а не напряжение 3,3V. Логический сигнал это 1 (5V) логический 0 (0V , точнее GND) . И вот у вас идет счет сколько раз был переход с 1 в 0. Не можете перемычкой, повесте кнопку с подтяжкой резистором на 5V/
Спасибо большое за ответ!
возможно "гоняю дурку")))) (пишу свою первую программу для ардуино), но при этом какие-то значения же выдает программа, но только не те, которые должна..
П.С. попробовал "закорачивать" 5В и вход 5 - аналогичная картина, не верные значения..
по поводу логического 0 - т.е логический ноль - это соединение 5 входа в GND, а не просто разрыв цепи (не просто раскорачивание 5В и входа №5)?
ну да 0 это когда на землю. А вообще надо 5V -> резистор 10 кОм- > на вход 5 и вход 5-> кнопка -> GND. На кнопку нажимаешь. сигнал подаешь на вход.
Ну или так
"2) второй вопрос: как сделать чтобы выводилось значение на экран только однократно, а не постоянным потоком сообщений в диалоговом окне?"
Строчки с 29 по 32 меняем
Я не совсем понял Вашу задачу но попробуйте такой код (хотя подтяжку нужно обязательно, так ка Вам подсказали выше)
Эти два условия, как я понимаю, противоречат друг другу, поэтому не будет работать второй цикл "if", т.к один цикл находится внутри другого...
Поэтому второй вопрос (как сделать вывод информации однократным) остался пока что открытым..
П.с. пока что не пробовал правильно подключить плату через сопротивление и кнопку, возможно, это поможет выводить значение с десятыми долями (как , например, я выше писал в примере 1,7 при количестве входных сигналов =17)
п.п.с. можно ли сделать так: если с клавиатуры вводим 1, то выводим в окне значение "к" и сразу же "присваиваем" введенному значению !=1 ?
также переставил значение в конец сскетча - так будет более правильно, как мне кажется
Однократный вывод я описал в №13пост а в 14 это реализовано. Вы что не смотрели? По поводу счетчика: kol_A - у Вас единицы а к- десятки, как их обьеденить это просто математика - умножте додайте разделите и получите при 17 тиках 1,7
1) Подаю 3,3 вольта с выхода ардуинки перемычкой на вход 5.Например, по моей логике, например, если я "закорочу" 3,3 В и 5вход 15 раз - должно на экране показать значение 1,5.Выводит неверные значения - в чем ошибка, как исправить, подскажите, пожалуйста?
Вы что дурку гоняете. На вход надо подавать логический сигнал, а не напряжение 3,3V. Логический сигнал это 1 (5V) логический 0 (0V , точнее GND) . И вот у вас идет счет сколько раз был переход с 1 в 0. Не можете перемычкой, повесте кнопку с подтяжкой резистором на 5V/
вообще-то для TTL 5V логики логический ноль это напряжение от 0,8 до 1,2 вольта, логическая единица, от 2,4 вольта до 5 (4,8) вольт
вообще-то для TTL 5V логики логический ноль это напряжение от 0,8 до 1,2 вольта, логическая единица, от 2,4 вольта до 5 (4,8) вольт
И что вы остановились. Раскажите про устройство входных и выходных каскадов логическим микросхем, про втекающие и вытекающие тока и также многое другое в 10 тысяч знаков. Спросите зачем? Просветите человека, подающего сигнал с 3,3В. Я просто прикинул объем информации который надо освоить ТС, и на который он тупо "забъет". Может вы продолжите "просвещать новичков", которые не знают что такое Гугл и как надо "добывать информацию".
вообще-то для TTL 5V логики логический ноль это напряжение от 0,8 до 1,2 вольта, логическая единица, от 2,4 вольта до 5 (4,8) вольт
И что вы остановились. Раскажите про устройство входных и выходных каскадов логическим микросхем, про втекающие и вытекающие тока и также многое другое в 10 тысяч знаков. Спросите зачем? Просветите человека, подающего сигнал с 3,3В. Я просто прикинул объем информации который надо освоить ТС, и на который он тупо "забъет". Может вы продолжите "просвещать новичков", которые не знают что такое Гугл и как надо "добывать информацию".
Не запутывайте человека, логические 0 и 1 это не 5V и GND я об этом. В какой-то момент он всё равно полезет с тестером по ножкам и будет сильно удивлён, а знание направления токов убережёт от схемотехнических ошибок, это я вам как наладчик станков с чпу 8 разряда по сетке СССР говорю )))
Решил начать с малого: для начала попробовать собрать "счетчик десятков" через RISING.
скетч:
Получилось все, если не считать малого:
выводит значения не " +0,1 ", а "+0.2...0,5" - я так понимаю, из-за дребезга кнопки... Схему в принципе собрал с учетом советов в данной ветке "надо 5V -> резистор 10 кОм- > на вход 5 и вход 5-> кнопка -> GND.", добавил еще один резистор между выводом 3 и землей резистор в 10 кОм (правильно ли подключил подтягивающий резистор?)
Подскажите, пожалуйста, как избавиться (возможно программно или при помощи верного подключения схемы) от излишних прибавлений (дребезга контактов)?
Еще раз всем спасибо за помощь и наставления!
Если импульсы должны обязательно менять состояние - то вешай флаги (можно в прерываниях) и отключать при смене состояния, всё зависит от частоты импульсов.
Так же можно и на аналоговых входах.
Если в конечной схеме дребезга не будет, то вместо кнопок запрограмьте во вторую ардуину генератор импульсов.
Здравствуйте!
Решил проблему с дребезгом. Установил выдержку времени и дополнительную проверку на наличие сигнала на входе. Итоговый скетч получился такой:
Всем спасибо за консультации по данному вопросу, очень помогли!
Возник еще один вопрос, будьте добры, подскажите..
Если контроллер будет выполнять какую-либоо функцию (например, отправлять смс - занимает около 4,5 секунды, т.к имеются delay(500) 5 раз и в конце отправки delay (2000) ) в момент когда произойдет прерывание, то какова логика работы ?
1) Остановится отправка смс и программа перейдет в цикл RISING, затем продолжит отправку смс
2) Остановится отправка смс и программа перейдет в цикл RISING, затем продолжит не отправку смс, а пойдет программа по общему циклу loop сначала
3) НЕ остановится отправка смс, но программа увидит прерывание и перейдет в цикл RISING сразу после заверщения отправки смс
4) НЕ остановится отправка смс, и это прерывание программа не увидит
5) Другой вариант (подскажите какой)
Благодарен вам за помощь в ответе на вопрос
Не знаю, что есть "цикл RISING", но голосую за вариант № 1.
Аргументирую : https://sites.google.com/site/vanyambauseslinux/arduino/ispolzovanie-preryvanij-arduino
"При возврате из функции, вызванной по прерыванию, происходит так называемый возврат из прерывания, и управление передаётся тому шагу программы, который должен был быть выполнен следующим до прерывания."
Спасибо за ответ и ссылку, почитал стало понятнее (функция внешнего прерывания является в приоритете над другими функциями).
Да, спасибо за поправку, не цикл RISING, а функция attachInterrupt()
Но осталось небольшое сомнение, будет ли программа переходить к функции attachInterrupt(), если программа находится в "режиме ожидания" (т.е если уже успело задаться delay(500), но прошло еще только 300 мс, например, и появилось внешнее прерывание) , тогда программа перейдет к функции прерывания, а затем вернется к delay и выждет оставшиеся 200 мс? или же сначала выполнит до конца delay(500), а затем уже перейдет к ф-ции внешнего прерывания?
Спасибо за ответ и ссылку, почитал стало понятнее (функция внешнего прерывания является в приоритете над другими функциями).
Да, спасибо за поправку, не цикл RISING, а функция attachInterrupt()
Но осталось небольшое сомнение, будет ли программа переходить к функции attachInterrupt(), если программа находится в "режиме ожидания" (т.е если уже успело задаться delay(500), но прошло еще только 300 мс, например, и появилось внешнее прерывание) , тогда программа перейдет к функции прерывания, а затем вернется к delay и выждет оставшиеся 200 мс? или же сначала выполнит до конца delay(500), а затем уже перейдет к ф-ции внешнего прерывания?
У Вас каша в голове.
Программа никогда не переходит к функции attachInterrupt, кроме как естественным последовательным путём.
Переходит к функции обрабочику.
По поводу же Ваших сомнений - они тоже следствие каши. Запомните просто правило:
Когда происходит прерывание (если они разрешены), то программа, чтобы она не делала, немедленно прерывается и исполняется обработчик прерывания. Сразу же после завершения исполнения обработчика, программа продолжает своё исполнение в точности с того места где прервалась.
Всё! Больше там нет ничего и не надо ничего дополнительного выдумывать.
А теперь сами ответьте на свои смонения.
Запомните просто правило:
Когда происходит прерывание (если они разрешены), то программа, чтобы она не делала, немедленно прерывается и исполняется обработчик прерывания. Сразу же после завершения исполнения обработчика, программа продолжает своё исполнение в точности с того места где прервалась.
Понял, доступно объяснили, Правило запомнил. Спасибо!))
Отстраиваюсь от дребезга кнопки при blink'ах и не получается добиться правильной работы счетчика количества сигналов пришедших на второй пин ардуино уно (скетч в сообщении #23 не верно считает). Сделал новый кусок скетча, который отстраивает от дреезга кнопки (использует не работоспособность миллис в цикле блинк и отстраивается 100 миллисекундами от дребезга). НО остался "глюк" программы - иногда проскакивает добавление к переменной "К" в момент перехода кнопки из HIGH в LOW - с чем это может быть связано (возможно, это происходит при перещелкивании кнопки с задержкой в состоянии HIGH менее 100 мс?)? Подскажите, пожалуйста, в чем может быть ошибка (скетч прикрепляю)?
Принципиальная ошибка.Ну кто так организовывает антидребезг.
Принципиальная ошибка.Ну кто так организовывает антидребезг.
У меня в скетче то же самое, Вы слагаемые лишь местами поменяли (и выдержку меньше взяли). Загрузив Ваш скетч, проблема (иногда добавляет единицу при размыкании кнопки - это не совсем дребезг получается, т.к добавляется стабильно ровно 1 при замыкании кнопки. А проблема именно в том, что иногда добавляется единица при размыкании) осталась, к сожалению. В чем может быть еще загвоздка (подключение как в сообщении #12 - фото добавляю)?
Это полный П**Ц. Ну у вас не кнопка, а ПЕРЕКЛЮЧАТЕЛЬ. И дребезг у него не только при нажатии, но и отжатии. И только полный Д***Н(зачеркто) "новичок" использует при этом прерывание, а не просто опрос.
Спасибо за ответ (отдельное спасибо- за критику ))))
Буду подключать внешнее реле с оптронами и пока не знаю как оно будет считаться (как кнопка или как переключатель) , т.к еще реле не пробовал подключать , хотел испытать сначала на кнопке (вернее на переключателе)
Ну и с прерыванием. Которое тут как собаке 5 нога.
ПС: глючная конструкция.
В этом случает я использую такую конструкцию полный скеч здесь https://yadi.sk/d/TKzsHCyL3Bbehz
А головной файл без довеска такой.
Спасибо большое за скетчи!
Где можно подробнее почитать про использованную в последнем скетче библиотеку (интересно как будет вести себя программа при наличии двух переключателях и одновременном их переключении - будут выполняться функции для 2х переключателей поочередно(если да, то в каком порядке - который раньше объявлен в программе? если нет, то как поведет себя программа)?
Ну вы загнули. Библиотека самопал. Одновременно кнопки не сработают никогда. Может они и сработают, но опрос будет не одновременно. Так что та что 1 опросили , та и первая будет. Опять же алгоритм псевдопараллельный. Это значит, что если поставите тормоза в виде делай на 1 день, или час, то работа зависнет на этот же час.
Вот еще вариант Полный скетч здесь https://yadi.sk/d/WT0l3qE23AKXKx , а головной файл сюда кину.
ПС: Повторяю , этот код псевдопаралельный. А это значит, что можно совмещать нескольно независимых программ написаных в таком стиле на 1 Ардуине. Что убыстряет разработку рабочих программ. Правда надо правильно написать и отладить такие куски.