Подсчёт количества оборотов. Датчик препятствия
- Войдите на сайт для отправки комментариев
Друзья, help!
Есть примитивная задача по подсчёту количества оборотов ролика (колеса, двигателя, тут не принципиально) с помощью датчика препятствия. Ролик не вращается статично на одном месте, а совершает дополнительно линейное перемещение, в связи с чем в моём случае неудобно использовать датчик холла. Ниже код, который работает с датчиком холла, но не работает с оптическим. Оптический прибавляет не одну единицу, а может сразу 2, 3 или 4. Судя по всему имею эффект "дребезга", но это не точно. Помогите решить проблему, буду очень признателен!
Также хочу добавить, что часто вращения довольно высокая, около 300 об/мин.
П.С. Форум курил, честное слово.
Moderator : пожалуйста, вставьте код правильно (возможно, новым сообщением в тему),
Знаете, есть ещё более примитивная задача - правильное помещение кода в свой пост. Начните с нее.
А что происходит в коде, вот это жонглирование x y z - оно для чего вам?
Особенно доставляет вот это:
Типа "я сказал единица - значит, единица!" :)))
На самом деле не думал, что возникнут вопросы. Извиняюсь. Х и Y это состояние входа, наличие (отсутствие) сигнала с датчика. Присвоение значения Y = 1 сделано для того, чтобы программа не добавляла постоянно единицы до тех пор, пока не пропадет сигнал (разомкнется ключ). Z - counter (счётчик)
Друзья, не тратьте пожалуйста время на рофлы. Я в этой теме как свинья в апельсинах. Поясните просто, как обеспечить корректную работу счетчика на базе оптопары.
На attachInterrupt() по FALLING подвесится и делать ++ переменной.
Пробовал с прерыванием. Вот код, с датчиком холла всё ок, работает корректно, ставлю оптический - начинает прибавлять не единицы, а 200, 300, 500 и т.п. Ткните носом пож, что не так?
Ну, тут не все OK, конечно. Volatile потеряно и атомарное чтение. Но, мне кажется, что конструкция допускает паразитную засветку оптического датчика.
Окай, прописываю volatile int counter, ничего не меняется. Холл нормально прибавляет значения, а оптический 200,300,500. Как побороть эту паразитную засветку и почему при этой засветке он прибавляет сотни?
Есть положительная динамика при применении флажков. Но! Вместо +1, он почему-то прибавляет 2, а датчик холла прибавляет единицу как положено ((((((
Я не телепат, не вижу что за конструктив у вас там.
Да сейчас нет никакого конструктива. У меня в руках ардуинка и датчик, больше ничего. Тупо замыкаю ключ в попытках получить корректное прибавление к счётчику.
Оптический замыкаете?
Угу
А если так
Как механический контакт замыкают - понимаю. Как оптический - не очень.
Не-а, при замыкании +2 в счётчике идёт. Всё также.
Так может у вас датчик такой? Формирует два импульса, вместо одного. Если это поведение стабильно, то делите результат на 2 да и все.
Хотя я тоже не понимаю какой ключ, и как вы замыкание? Вы в реальных условиях все это как-то испытывали?
Ещё одно, стоит почитать вот это https://stackoverflow.com/questions/30420758/counter-vs-counter-counter1 и без надобности не писать умные конструкции типа counter++
Стоит таки быть проще и написать counter = counter + 1
Не охота анализировать как оно отрабатывает в данном случае, под прерываниями, но написав попроще, не придется потом долго разбираться где ошибка. (Я не настаиваю, что в данном случае ошибка, просто предостеригаю, сам попадал в такое).
Мужики, ну замыканием я называю срабатывание датчика и отправку сигнала с логического выхода на pin2. Нет блин, сижу ножницами плюс и минус замыкаю.
Короче если делить на два, или к примеру прибавлять 0.5, то в порте отображается 0, причём дважды после срабатывания датчика.
Судя по всему он отправляет сигнал дважды при срабатывании, первый раз при появлении препятствия и второй раз при его отдалении. На плате UNO есть Led индикатор RX, на нём видно, как дважды отрабатывает сигнал.
Как у вас отрабатывает поправленный мною код?
Попробуйте заменить counter++ на обычный counter = counter + 1
Я чуть выше на счёт этого свой комментарий дополнил.
В данном случае от ++ опасности нет, так как значение переменной перед инкрементом не используется.
Присядьте осциллографом на выход оптического датчика. Если он двоит-троит случайным образом, то никаким кодом это не исправишь.
++ или counter+1 - разницы нет. Меняя местами действия в loop ничего не меняется. Датчик отправляет сигнал при изменении логического 0 на 1 и второй раз при изменении с 1 на 0, т.е. дважды. Что за магия, шайтан...
Как он выглядит?
Обычный датчик препятствия, YR-63
Ну в таком случае, засчитывайте единицу по каждому второму импульсу, вот http://arduino.ru/Reference/Modulo
if (counter % 2 == 0) {
// Прибавляем к какой-то другой переменной 1
}
А тупо делить int, или умножать на не целое просто нельзя. Логика простая - дробные будут отброшены. Поэтому int 1/2 = 0, а 3/2 = 1.
Где-то у меня такой валялся... Дупления не замечал за ним. Хотя, я только в качестве концевика его использовал, канеш.
Делимость на два ещё можно проверить через (false == x&1)
Мужчины, будьте благородны, укажите что на что в коде поменять, не очень доходит.
Sadman, если есть такой датчик, умоляю, попробуйте подрубить его.
Э нет! Тут так это не работает. Попробуйте таки сами разобраться что в коде менять. Или хотя бы попробуйте. Пока свой вариант не выложите, никто за вас писать не будет. Как два импульса за один считать вам уже два раза подсказали.
Вобщем, у меня FC-03. По схеме похож, по конструктиву - нет.
Лаааадно, завтра попробую разобраться, жена палкой гонит спать. Спасибо мужчины в любом случае. И это, хотел добавить, в мониторе порта счётчик идёт не 2,4,6,8,10, а последовательно 1,2,3,4,5 и т.д, только вот при срабатывании датчика получаю +1 и следом ещё раз +1. При изменении логического 0 на 1 и обратно при изменении с 1 на 0. Надеюсь понятно.
FC 03 такой же на базе оптопара. По идее разницы для эксперимента не должно быть, «я так думаю»!))
Лаааадно, завтра попробую разобраться, жена палкой гонит спать. Спасибо мужчины в любом случае. И это, хотел добавить, в мониторе порта счётчик идёт не 2,4,6,8,10, а последовательно 1,2,3,4,5 и т.д, только вот при срабатывании датчика получаю +1 и следом ещё раз +1. При изменении логического 0 на 1 и обратно при изменении с 1 на 0. Надеюсь понятно.
Ну, теперь понятно, что вы голову морочите.
Я надеюсь вы понимаете разницу между получаю count + 2, и тем, что вы только что написали?
Но так или иначе, решение для двух импульсов вам подсказали выше.
Сдаюсь. Не могу додумать, как в счётчик загнать каждый второй импульс. Вторую переменную сделал (количество импульсов), с обнулением и флажками запутался. Дайте еще подсказку, пжлст!
Намудрил тут, рукалицо
Ну почему же рукалицо, вполне рабочий вариант. Вот только заменить
if (counter=2) {
на
if (counter==2) {
Ок, поставил дополнительное "=" перед 2 и 0, теперь counter2 доходит до значения 1 и счёт останавливается.
Т.е. операцию присвоения от операции сравнения Вы не отличаете...
Т.е. операцию присвоения от операции сравнения Вы не отличаете...
Болван. Убрал одно "=" перед 0.
Господа, спешу поделиться радостью, решение найдено. Ниже рабочий скетч. Нужно было всего лишь изменить сравниваемое значение с counter с 2 до 4. Судя по всему датчик посылает 4 импульса при переходе с логического 0 на 1 и 1 на 0. Провел полевые испытания и закралось подозрение, что датчик выполняет пропуски при высоких оборотах. Есть ли этому причины в коде? И как его возможно упростить?
Странный датчик какой-то
"Упростить" так:
Ну, для начала, имхо, я бы инкриментацию count все таки перенес бы в обработчик прерываний. Во вторых, я бы не выводил каждое показание в serial, тем более на такой низкой скорости как 9600. Потому как пока у вас выводится в сериал, у вас флаг мог падать несколько раз, а вы этого не замечаете. (Вообще, почему-то все новички забывают, что serial так же кушает ресурсы МК. Сам таким был.)
В сериал можно выводить например в конце всего замера. Чтобы точно убрать его влияние.
Логика такая: запоминаем значение millis() (создаём таймер), в обработчике прерывания подымаем флаг (так как у вас сейчас, но использовать будем для другого), в основном цикле - если флаг поднят опускаем и обновляем значение таймера новым millis(). Дальше по циклу - если millis() - таймер => 1000 то выводим значение в сериал.
Таким образом - в сериал будут выводится окончательные значения, ровно через секунду после последнего замера. И вывод в сериал не будет вам тормозить весь скетч.
Странный датчик какой-то
"Упростить" так:
Ну и? И чему человек так научится? Если даже я (уже вроде не полный профан) не до конца всю эту вашу кухню без словаря разберу?
Давайте затрем пока не видел. Потом когда сам дойдет, тогда и подарите.
Напишите по-своему, в чём проблема? Посмотрим, у кого непонятней выйдет ))
Поздно затирать. Закомментили уже.
В сущности - тут нет ничего такого, чего бы он уже сам не писал ранее. Я только местами поменял и переобозвал переменные, вот и всё.
Я не про понятность, а о том, что вы готовое дали, а я выше алгоритм предложил. Если челу, который присваивание и сравнение путает, дать готовое, он не научится сам думать. Потому и предлагаю. Как сам до чего то дойдет, то тогда это и подарите. А пока потереть лучше.
Да, действительно, я дурак, закоментил.
Надеюсь ТС хоть попробует ваш подарок разобрать и понять. И на меня пускай не обижается. Я ведь наоборот ему лучшего желаю. :)
Я же написал, что поздно. Не комментили бы - стёр. А так всё, аллес гемахт.
Впрочем, там ещё немного ускорить можно - пусть думает ))
Я одно не могу понять, почему такая тривиальная задача превратилась в Бог знает что? Это же самый обыкновенный датчик, на базе которого тот же Гайвер делал тахометр. Как он блин у него тогда работал... Завтра поеду в магаз и куплю ещё один датчик, а заодно и аналоговый возьму. За скетч спасибо конечно, но в нем я толком ничего не понял, хотя структура знакома.
ПС. За наставление на путь самурая благодарю, учение свет. Только у меня нет сейчас на это времени, да и ардуино я в руках неделю держу.
ПС2. Да и тем более мужчины, мне в какой-то степени жаль отнимать ваше время на эти, как мне кажется, совсем не интересные для вас разъяснения. Думал тут нужно было внести небольшую правку, а вот видите как вышло.
Все равно не в коня корм, можно не переживать ))
Короче, рылся в поисках инфо и наткнулся на проект Гайвера «колесный измеритель расстояния». Проект строился на без этого датчика. На 3.50 мин он значит говорит, что у этого датчика есть мерзкая особенность, при медленном вращении он срабатывает дважды. Ну а на 8.40 мин он говорит, мол в *опу этот датчик, причём так красноречиво )))) Угарнул конечно.
https://youtu.be/LE-3Z7RaSww