Защита от дребезга дискретных сигналов
- Войдите на сайт для отправки комментариев
Вс, 11/01/2015 - 16:49
Допустим есть массив оперативных сообщений на 100 элементов, куда пишутся все изменения дискртеных сигналов. Так мало потому что ОЗУ в контроллере больше нет... Есть несколько датчиков, которые начинают дребезжать...тем самым благодаря этому дребезку массив очень быстро переполнится и контроллер "повиснет"(( Первое что приходит в голову - переставать писать в массив когда подходим к его границе, но тогда мы теряем часть событий, это не есть хорошо... Второй вариант сделать какой-нибудь фильтр через который пропускать DI сигналы, но как сделать совсем непонятно(( Помогите советом, что можно сделать в такой ситуации :)
Подберите конденсатор такой емкости, чтобы дребезг глушился , но фронт полезного сигнала не заваливатся более, чем ( скажем) на 15% от минимальной длительности полезного импульса... И поставте его между сигналом и GND.
Проще сделать програмно да и надежнее - фиксировать нужно только те изменения сигнала которые стабилизировались в течении заданного времени. Т.е. Вы не должны реагировать на любое изменение сигнала, а только на то изменение которое стабильно (не меняется) в течении заданного времени. Примеров реализации масса. Я использую счетчики на таймере, можно использовать mills()
axill, а это хорошая мысль))
axill, посмотрел я на форуме мельком как народ отслеживает промежуток времени(tmp=mills(); mills() - tmp > N мсек), а что будет если переменная tmp переполнится? Пусть через 10-20 суток, но она переполнится, а нам нужна система работающая в режиме 24/7))
не знаю деталей вашей задачи, но против дребезга обычно применяют интервал времени от десятков до сотен милисекунд в течении которых значение сигнала должно стабилизированться
вероятность, что на момент замера интервала такой длительности придется сам момент переполнения на мой взгляд ничтожно низкая. Самое хужшее что произойдет - в ваш массив запишется одно лишнее значение или наоборот одно не запишется (смотря как вы код напишите)
я иногда использую более простой способ програмной борьбы с дребезгом если не используются прерывания. Как только поймал изменение статуса, делаю delay(100) и после такой задержки проверяю совпадает ли статус с тем, который был перед задержкой. Для кнопок это вполне нормально работает (задержка подбирается от 100 до 500). Но нужно по задаче смотреть.
Переменная tmp может переполняться, и значение mills( ) тоже, а разность ( mills( ) - tmp ) всё равно всегда будет правильной - такой вот фокус.
Datak, разность само собой что не переполнится...А вот что произойдет когда tmp переполнится. Для того чтобы система работала в режиме 24/7 может быть стоит использовать функции получения времени(восвращающие время, а не мс с момента запуска контроллера)?
shplint, а какие у вас конкретно датчики? Может просто не нужно их часто опрашивать?
shplint, ты же написал, что этот способ используется для отсчёта нужных промежутков времени.
Так и есть, и время старта контроллера тут вообще не важно. Измеряется именно промежуток между сохранением значения в tmp, и текущим временем, полученным из millis( ).
И такой способ будет работать правильно для любых интервалов времени, почти до максимального значения millis( ) и, соответственно, tmp.
"Почти" - потому что при интервалах очень близких к максимальному есть риск пропустить нужное значение разности, если опрос millis( ) выполняется не достаточно часто.
А правильно всё получается потому, что при вычислении разности тоже может возникнуть переполнение, и оно всегда правильно и однозначно исправляет "ошибку" переполнения счётчиков.
Попробуй сам, хотя бы на бумаге. Чтобы считать было проще, тренироваться советую на байтах - смысл от этого не меняется.
Вот здесь есть отличный топик (http://arduino.ru/forum/programmirovanie/rabota-s-knopkami-v-pomoshch-novichku), там хорошо описаны способы подавления дребезга контактов. Можно подавлять дребезг без функции millis() (в этом топике это описано). Ну а если использовать millis(), то по истечении 50 дней таймер функции достигнет максимального значения, и если у вас Arduino на мк Atmega328(Arduino Uno), то можно сделать ватчдог(про это есть статья на хабрахабре), возможно ватчдог поддерживают и дркугие мк, но я проверял только Уно(поддерживает) и Мегу(почему-то не работает). А если боитесь, что переменная tmp перезаполнится, то возмите переменную типа unsigned long, памяти этой переменной чуть-чуть не хватает до полных пятидесяти дней(естественно в миллисекундах, потомучто millis() возвращает миллисекунды), вы сами посчитайте, сколько в миллисекундах будет 50 дней и какое максимально число можно записать в unsigned long, и сравните. Так же существует библиотека bounce.