Добрый день! Имеется двигатель с инкрементным датчиком HC-020K: Двигатель управляется с помощью Motor Shield. Плата управления - Arduino Uno. Хочу сделать так, чтобы двигатель сделал 5 оборотов в одну сторону, а после - начал вращаться в обратную сторону до бесконечности. Писал скетч на прерываниях: Код (Text): int E2=6; int M2=7; volatile int i = LOW; void setup() { pinMode (M2, OUTPUT); pinMode (2, INPUT_PULLUP); attachInterrupt(0, gogogo, FALLING); } void loop() { analogWrite(E2, 125); if (i>5) { digitalWrite(M2, LOW); } else { digitalWrite(M2, HIGH); } } void gogogo() { i++; } Подключил 1-й канал осциллографа к ноге 2 (прерывание №0), а второй - к ноге 7 (направление движения двигателя). В итоге, переключение M2 с LOW на HIGH происходит не после 5 импульсов, пришедших на пин прерывания (отслеживаю и осциллографом, и по числу просветов на насадке для вала двигателя), а после двух! Даже если задать вместо 5 что-то большее: 35, 55 - все равно 2 импульса и переключение. В чем может быть проблема?
Спасибо за ответ! Думаете, что дело в дребезге? Тогда почему именно после 2, а не 5 (как в скетче) импульсов происходит переключение? На осциллографе картина довольно устойчивая. С конденсатором попробую сегодня сделать.
хобби энкодеры всегда звенят. ну или почти всегда. я не спец в ардуине, но я так понимаю FALLING - вызывает прерывание по спаду? Если да, то вроде все правильно в софте, но повторюсь- возможно, я не в курсе неких тонкостей ардуины. кстати void gogogo() { i++; } докрутит i до максимума переменной Int - она какая в ардуине- и i cтанет отрицательным? Обычно если знаковое, то int от -32 к до +32 к примерно. я бы вставил что-то вроде if( i>6) i=6
Да, FALLING - вызов прерывания при спаде. Так и есть: в Arduino int = от -32,768 до 32,767. Но разве это важно? Я всего лишь 5 импульсов хочу поймать, а программа обрывается только на 2-х. Попробовал параллельное включение конденсатора - не помогло. Сделал попытку убрать дребезг программно в AVR Studio - тоже без результата
Та же самая хурма... Вот что обнаружил, включив вывод i на сериал порт: 1 метка (реальная и на осциллографе) = 3 меткам в МК. Т.е. поэтому я проезжаю 2 метки (реальные), мк считает их как 6 и условие i>=5 выполняется. Я так полагаю, это очень жесткий дребезг. Кондер не помогает, подтяжка - тоже. Какие есть советы?
метод последовательных приближений рулит. Это не дребезг, дело скорее всего в софте. Если спад вызывает четко три прерывания - дело точно в софте. Тут надо четко просмотреть все строки кода, но я тут пас - в ардуинах не силен.
Да, ряд проверок и перепроверок с разными источниками сигнала показал, что это не дребезг: по непонятным причинам МК обрабатывает 1 сигнал сразу по двум фронтам - вне зависимости от того, задаем мы RISING или FALLING. Как это понимать - я без идей
Дребезг может и присутствует, но в данном случае дело не в нем. Посмотрите на условный оператор: Код (C++): if (i>5) { digitalWrite(M2, LOW); } else { digitalWrite(M2, HIGH); } При первом вызове функции 'loop()' значение переменной 'i' будет меньше 5, и поэтому в пин 'M2' запишится HIGH. Если Вы хотите, что бы переход с LOW в HIGH произошед через 5 импульсов, измените условие на 'i < 5'. Но это не все. В сових экспериментах заметил одну особенность. При рестарте Arduino всегда вызывается обработчик прерывания один раз не зависимо от типа (FALLING, RISING, CHANGE). Почему так происходит пока не разобрался. Следовательно условие должно быть 'i < 6'.
Сегодня как раз экспериментировал с прерываниями. RISING точно вызывается когда нужно. При старте нет вызова
попробуйте сбрасывать флаг этого прерывания перед тем, как его включить. В ассемблере это регистр EIFR. У меня не ардуино, но всегда когда включаешь прерывания хорошо этот флаг сбрасывать, чтобы не сидел флаг прерывания.
При рестарте Arduino всегда вызывается обработчик прерывания один раз не зависимо от типа (FALLING, RISING, CHANGE)...... в вашем бы случае я настоятельно рекомендовал бы смотреть в даташит на мк который установлен на ардуину... есть рус мануал на мегу128... вот вам выдержка от туда к примеру...(биты ISCn регистр EICRA отвечают за характер срабатывания прерывания..низкий ....высокий...изменение уровеня сигнала). ...Если разрешено прерывание по уровню, то оно будет генерироваться непрерывно до тех пор, пока на входе присутствует низкий уровень... Перед изменением бит ISCn1/ISCn0 необходимо запретить работу прерывания путем очистки бита разрешения прерывания в регистре EIMSK. В противном случае прерывание может возникнуть после изменения данных бит.