Прерывания и сравнение скорости: то работает, то не работает
- Войдите на сайт для отправки комментариев
Доброго дня всем!
имеется эл. двигатель, два диска с прорезями, на двух валах , соединеных ремнем, что то типа циркулярной пилы. с ардуино уно и двумя оптодатчиками я хочу сравнивать скорости вращения дисков, и в случае заклинивания (или сильного уменьшения оборотов) одного из дисков отключать двигатель, чтоб не порвать ремень.
лихой копипастинг дал такую программу: оптодатчики повесил на аппаратные прерывания которые засекают время прохода прорези диска, и из этого времени расчитывают скорость в оборотах в минуту. если разница в скоростях слишком большая - даем сигнал на отключения мотора. так же для наглядности продублировал сигнал срабатывания оптопары на отдеольные диоды в ардуино.
на больших и средних скоростях все работает нормально, но если диск вращается медленно, или вообще стартует заклиненый - то в половине случаев сигнала отключения нет или есть только когда со второй оптопары приходит сигнал.
дайте совет, что может быть не так? может зря я вообще связался с прерываниями, может надо было делать менее точно на простых таймерах?
Заранее благодарен за помощь
/* реле выставляется в низкое положение, при разнице оборотов больше чем толеранс - включается в высокое */ const int tolerance = 60; //примерный допуск на разницу во времени #define stopSignal 13 //пин для включения/выключения тревоги #define sensorPIN_L 2 // Установка контакта оптопары Л #define sensorPIN_R 3 // Установка контакта оптопары П #define sensorLED_L 8 // светодиод срабатования оптопары Л #define sensorLED_R 9 // светодиод срабатования оптопары П #define HOLES_DISC 9 //число дырок в диске volatile unsigned int pulsesL; volatile unsigned int pulsesR; float rpmL; float rpmR; unsigned long timeOldL; unsigned long timeOldR; float rpmDiff; void counterL() { pulsesL++; } void counterR() { pulsesR++; } void setup() { pinMode(sensorPIN_L, INPUT); pulsesL = 0; timeOldL = 0; attachInterrupt(digitalPinToInterrupt(sensorPIN_L), counterL, FALLING); pinMode(sensorPIN_R, INPUT); pulsesR = 0; timeOldR = 0; attachInterrupt(digitalPinToInterrupt(sensorPIN_R), counterR, FALLING); pinMode(stopSignal, OUTPUT); digitalWrite (stopSignal, LOW); pinMode(sensorLED_L , OUTPUT); pinMode(sensorLED_R , OUTPUT); digitalWrite (sensorLED_L, LOW); digitalWrite (sensorLED_R, LOW); } void loop() { if (millis() - timeOldL >= tolerance) { detachInterrupt(digitalPinToInterrupt(sensorPIN_L)); rpmL = (pulsesL * 60) / (HOLES_DISC); timeOldL = millis(); pulsesL = 0; attachInterrupt(digitalPinToInterrupt(sensorPIN_L), counterL, FALLING); } if (millis() - timeOldR >= tolerance) { detachInterrupt(digitalPinToInterrupt(sensorPIN_R)); rpmR = (pulsesR * 60) / (HOLES_DISC); timeOldR = millis(); pulsesR = 0; attachInterrupt(digitalPinToInterrupt(sensorPIN_R), counterR, FALLING); } if (digitalRead(sensorPIN_L) == LOW){ digitalWrite (sensorLED_L, HIGH); }else{ digitalWrite (sensorLED_L, LOW); } if (digitalRead(sensorPIN_R) == LOW){ digitalWrite (sensorLED_R, HIGH); }else{ digitalWrite (sensorLED_R, LOW); } rpmDiff = abs(rpmL-rpmR); if (tolerance < (rpmDiff)) { digitalWrite (stopSignal, HIGH); } }
С этими параметрами разобраться, на вашем диске 9 отверстий?
Добавить обработку при старте без прерывания т.е. если с ведомого репера не пришел сигнал за какое то время обрубать.
"если диск вращается медленно"
а как при этом выглядит сигнал на выходе датчика? возможно, нужно добавить формирователь на триггере шмитта.
"может надо было делать менее точно на простых таймерах"
возможно, просто pulseIn() может хватить.
С этими параметрами разобраться, на вашем диске 9 отверстий?
Добавить обработку при старте без прерывания т.е. если с ведомого репера не пришел сигнал за какое то время обрубать.
да. сейчас это диск от "болгарки" для бетона. примерно такой:
и оптопара трехпиновая , типа такой
с дополнительным таймером попытаюсь сделать, если осилю. буду пробовать
Проверьте сигнал с датчика. У меня было проблема, когда на малых скоростях вращения в подобной системе появлялся дребезг. Штатные процедуры подавления дребезга помогли.
даже у оптики бывает дребезг чтоли? Ну блин никуда от него не денешься...
даже у оптики бывает дребезг чтоли? Ну блин никуда от него не денешься...
Блики, наверное, давали подобный эффект.
даже у оптики бывает дребезг чтоли? Ну блин никуда от него не денешься...
Тени, полутени. Вибрация всей установки при медленно движущем объекте
даже у оптики бывает дребезг чтоли? Ну блин никуда от него не денешься...
даже у оптики бывает дребезг чтоли? Ну блин никуда от него не денешься...
дифракция, переотражение, отсутствие или не правильная настройка компаратора, переменная фоновая засветка которая суммируется с облучателем, электрические наводки которые тоже могут суммироваться...
А я 10 отверстий насчитал на диске.
Я вывел дополнительно индикацию по оптопарам. При загорании лампочек на оптопарах точно так же дублируются вспышки и на самом контроллере. Так что я исключаю тот факт, что могут быть какие то блики или фоновая засветка. Мне не понятно почему на большой скорости всё работает, а при медленной нет. Прошу помочь по данному вопросу.
Я вывел дополнительно индикацию по оптопарам. При загорании лампочек на оптопарах точно так же дублируются вспышки и на самом контроллере. Так что я исключаю тот факт, что могут быть какие то блики или фоновая засветка. Мне не понятно почему на большой скорости всё работает, а при медленной нет. Прошу помочь по данному вопросу.
Осциллограф есть? сделайте 50 экспериментов с однократным запуском триггера. И осциллограф нужен не самый медленный, с полосой на 50МГц должно хватить.
и на всякий случай вспомните, как быстро ваш глаз реагирует?
50 мгц??? зачем так много? У меня скорость ну максимум 2Гц. Минимум так вообще один оборот в 3 секунды. Моего зрения предостаточно чтоб это увидеть)
Можно подробнее, как именно Вы убедились, что нет дребезга? Вы смотрели осциллографом или выводили диагностику программно, тогда код покажите.
Я вывел на индикацию. Осцилографом не смотрел.
вот сам текст проги
ответил выше.
50 мгц??? зачем так много? У меня скорость ну максимум 2Гц. Минимум так вообще один оборот в 3 секунды. Моего зрения предостаточно чтоб это увидеть)
ГЫ :) вы попутали горячее и тяжелое... убедиться в отсутствии дребезга можно только быстродействующим прибором, а не весами или секндомером в руке. Ищите полную действительную схему вашего модуля оптопары с указанными номиналами деталей, может тогда чего и подскажем, ну или клапа разрешит хрустальные шары...
UPD попробуйте вникнуть в эту статью
А я 10 отверстий насчитал на диске.
Нет, ну не все же умеют считать до 10!
В сериал выведите (pulsesL, pulsesR) или (rpmL, rpmR) и посмотрите что насчитывает.
В сериал выведите (pulsesL, pulsesR) или (rpmL, rpmR) и посмотрите что насчитывает.
а что там можно увидеть? там сперва массив нужно записать с интервалами времени, потом только этот массив данных выводить и при этом останавливать работу с прерываниями на период вывода. и массив нужен из 20-30 значений интервалов времени. И дабы не перегружать вывод тормозить программу иначе потеряешься в массиве информации. И увидишь, что эти интервалы не одинаковые (сильно) - вот только эти знания сами по себе ничем особенным не помогут... ИМХО
А я 10 отверстий насчитал на диске.
Нет, ну не все же умеют считать до 10!
А я 10 отверстий насчитал на диске.
Нет, ну не все же умеют считать до 10!
чего бы умного и мне сморозить....
Я вывел на индикацию.
Код не смотрел, т.к. он неправильно вставлен. Но и так понятно, что дребезга Вы не заметите ни по какой индикации.
Нет осциллографа - выводите время в мили- (или микро-) секундах, так хоть что-то понять можно.
Да, чего дополнять, пусть ТС хоть что-то делать начнёт (хоть код вставит). Кстати, ещё раз использует слово "прога" (как в №15) меня в теме больше не будет. Я не прогер и в прогах не разбираюсь.
Проверьте сигнал с датчика. У меня было проблема, когда на малых скоростях вращения в подобной системе появлялся дребезг. Штатные процедуры подавления дребезга помогли.
я наверное неправильно понимаю суть команды Interrupt. по моему разумению при поступлении сигнала на этот вывод микропроцессор должен все бросать и начинать выполнять определенный код. применение антидребезга с прерыванием лишает эту команду всякого смысла, ибо код исполнится не сразу, а через время антидребезга. в моей практически пустой программе это не критично, но если будут циклы типа While или сложные вычисления , ожидания нажатия кнопки - то и обработка прерывания может задержаться. возможно я не прав, поправьте.
А я 10 отверстий насчитал на диске.
Нет, ну не все же умеют считать до 10!
чего бы умного и мне сморозить....
в моем диске - 9 прорезей (а не отверстий, как правильно заметили) картинку подобрал в гугле первую похожую, на картинке прорези даже не считал. поставить диск можно любой, именно для этого вывет кол-во прорезей в переменную, на не применил цифру в формуле в глубине программы
я наверное неправильно понимаю суть команды Interrupt. по моему разумению при поступлении сигнала на этот вывод микропроцессор должен все бросать и начинать выполнять определенный код. применение антидребезга с прерыванием лишает эту команду всякого смысла, ибо код исполнится не сразу, а через время антидребезга.
В идеальном мире, существующем в голове программиста, который с физикой не работает, всё именно так. Однако, давайте подумаем, что будет происходить с процедурой, вызываемой по прерыванию, в реальном мире: все случайно залетевшие помехи начнут дёргать её беспрестанно. Включили рядом лампочку - прилетел импульс длительностью в 200ns, клацнули кнопкой - получили пачку импульсов. Т.е. счетчик, если он есть в процедуре, с точки зрения внешнего наблюдателя, будет увеличиваться хаотически.
Как можно купировать данную проблему, на ваш взгляд?
Да, чего дополнять, пусть ТС хоть что-то делать начнёт (хоть код вставит). Кстати, ещё раз использует слово "прога" (как в №15) меня в теме больше не будет. Я не прогер и в прогах не разбираюсь.
вы однозначно разбираетесь в програмировании больше меня, сокращение было не с целью оскорбить. наверное это как теплотехника сантехником обозвать ))
загрузка на работе не дает часто сидеть за компом, тем более сосредотачиваться на программировании. сейчас есть компьютер, но нет с собой ардуины.
посмотрите, будет ли работать счетчик импульсов, если его взять из подпрограммы attachInterrupt ??
я наверное неправильно понимаю суть команды Interrupt. по моему разумению при поступлении сигнала на этот вывод микропроцессор должен все бросать и начинать выполнять определенный код. применение антидребезга с прерыванием лишает эту команду всякого смысла, ибо код исполнится не сразу, а через время антидребезга.
В идеальном мире, существующем в голове программиста, который с физикой не работает, всё именно так. Однако, давайте подумаем, что будет происходить с процедурой, вызываемой по прерыванию, в реальном мире: все случайно залетевшие помехи начнут дёргать её беспрестанно. Включили рядом лампочку - прилетел импульс длительностью в 200ns, клацнули кнопкой - получили пачку импульсов. Т.е. счетчик, если он есть в процедуре, с точки зрения внешнего наблюдателя, будет увеличиваться хаотически.
Как можно купировать данную проблему, на ваш взгляд?
для серьезного устройства я бы поставил RC фильтр, с крупным резистором на землю и небольшим конденсатором. но для поделки на циркулярку заморачитаться не стал бы от лени
а какой был правильный ответ?
Вот и я спрашиваю - как, на ваш взгляд, решается дилемма выбора между скоростью и надежностью?
Вот и я спрашиваю - как, на ваш взгляд, решается дилемма выбора между скоростью и надежностью?
для начала необходимо знать происхождение лишних сигналов или пропусков. пока мы только гадаем.
Вот и я спрашиваю - как, на ваш взгляд, решается дилемма выбора между скоростью и надежностью?
для начала необходимо знать происхождение лишних сигналов или пропусков. пока мы только гадаем.
поддерживаю, и не мешало бы знать схему этого конкретного девайса с номиналами элементов. Это я про всякую фильтрацию и гистерезис имею ввиду. абы куда и абы как ставить RC фильтр просто вредно. lm358 не любит низкоомную нагрузку...
Когда исполнится тогда и так, как Вы напишете.
Зачем Вам задерживать код? Запомнили время когда прилетело прерывание и пусть всё дальше работает. Прилетит новое, смотрим, сколько времени прошло и принимаем решение. основной код не тормозим никогда.