Инкрементный датчик и прерывания

Daemon2017
Offline
Зарегистрирован: 08.10.2013
Добрый день!



Имеется двигатель с инкрементным датчиком HC-020K:
 
Двигатель управляется с помощью Motor Shield. Плата управления - Arduino Uno.



Хочу сделать так, чтобы двигатель сделал 5 оборотов в одну сторону, а после - начал вращаться в обратную сторону до бесконечности. Писал скетч на прерываниях:

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 импульса и переключение.



В чем может быть проблема?

 

dimax
dimax аватар
Offline
Зарегистрирован: 25.12.2013

Daemon2017, в 4 строке не очень корректно, low- для булевых переменных. Впрочем к делу отношения не имеет. В скече нет никаких зацепок, выведете в сериал значение i и смотрите какое оно фактически, когда сработало условие.

arduinec
Offline
Зарегистрирован: 01.09.2015

Daemon2017 пишет:

В итоге, переключение M2 с LOW на HIGH происходит не после 5 импульсов, пришедших на пин прерывания

В скетче digitalWrite(M2, HIGH) выполняется при i<5, то есть практически сразу.

Daemon2017
Offline
Зарегистрирован: 08.10.2013

dimax пишет:

Daemon2017, в 4 строке не очень корректно, low- для булевых переменных. Впрочем к делу отношения не имеет. В скече нет никаких зацепок, выведете в сериал значение i и смотрите какое оно фактически, когда сработало условие.

Спасибо за совет!

Вот что обнаружил, включив вывод i на сериал порт: 1 метка (реальная и на осциллографе) = 3 меткам в МК.
Т.е. поэтому я проезжаю 2 метки (реальные), мк считает их как 6 и условие i>=5 выполняется.
Я так полагаю, это очень жесткий дребезг. Или я ошибаюсь?
 
Кондер не помогает, подтяжка - тоже. Какие есть советы? Впервые такое вижу.
Daemon2017
Offline
Зарегистрирован: 08.10.2013

arduinec пишет:

Daemon2017 пишет:

В итоге, переключение M2 с LOW на HIGH происходит не после 5 импульсов, пришедших на пин прерывания

В скетче digitalWrite(M2, HIGH) выполняется при i<5, то есть практически сразу.

В каком смысле? О.о 

arduinec
Offline
Зарегистрирован: 01.09.2015

Daemon2017 пишет:

arduinec пишет:

Daemon2017 пишет:

В итоге, переключение M2 с LOW на HIGH происходит не после 5 импульсов, пришедших на пин прерывания

В скетче digitalWrite(M2, HIGH) выполняется при i<5, то есть практически сразу.

В каком смысле? О.о 

Цитата из скетча:
Если (i>5) то digitalWrite(M2, LOW)
иначе digitalWrite(M2, HIGH) - то есть при i<=5

Может имелось ввиду переключение M2 с HIGH на LOW ?
 

Daemon2017
Offline
Зарегистрирован: 08.10.2013

arduinec пишет:

Daemon2017 пишет:

arduinec пишет:

Daemon2017 пишет:

В итоге, переключение M2 с LOW на HIGH происходит не после 5 импульсов, пришедших на пин прерывания

В скетче digitalWrite(M2, HIGH) выполняется при i<5, то есть практически сразу.

В каком смысле? О.о 

Цитата из скетча:
Если (i>5) то digitalWrite(M2, LOW)
иначе digitalWrite(M2, HIGH) - то есть при i<=5

Может имелось ввиду переключение M2 с HIGH на LOW ?
 

Так это же без разницы: для M2 в одну сторону вращаться - будет HIGH, а в обратную - LOW. 

Беда в другом: в датчике.

Ряд проверок и перепроверок с разными источниками сигнала показал, что это не дребезг: по непонятным причинам МК обрабатывает 1 сигнал сразу по двум фронтам - вне зависимости от того, задаем мы RISING или FALLING. 



Как это понимать - я без идей:(

std
Offline
Зарегистрирован: 05.01.2012

Что будет если дописать перед i++ в прерывании чтение пина:

void gogogo(){
  if(digitalRead(2)) i++;
}

тогда должно считаться только если есть единица, то есть второй фронт должен пропуститься.

arduinec
Offline
Зарегистрирован: 01.09.2015

std пишет:

Что будет если дописать перед i++ в прерывании чтение пина:

void gogogo(){
  if(digitalRead(2)) i++;
}

тогда должно считаться только если есть единица, то есть второй фронт должен пропуститься.

Нет нужды, так как прерывание вызывается при изменении уровня (с HIGH на LOW в данном случае).

http://arduino.ru/Reference/AttachInterrupt

arduinec
Offline
Зарегистрирован: 01.09.2015

Daemon2017 пишет:

Так это же без разницы: для M2 в одну сторону вращаться - будет HIGH, а в обратную - LOW. 

То есть датчик может определять направление вращегния? С одной опто-парой?

Daemon2017
Offline
Зарегистрирован: 08.10.2013

std пишет:

Что будет если дописать перед i++ в прерывании чтение пина:

void gogogo(){
  if(digitalRead(2)) i++;
}

тогда должно считаться только если есть единица, то есть второй фронт должен пропуститься.

Спасибо! Хорошая идея - разновидность программной фильтрации дребезга :) Сегодня вечером попробую и отпишусь.

Как доберусь до осциллографа - хочу включить максимальный зум и перепроверить: нет ли там дребезга в конце каждой ступеньки.

Хочу еще RC цепь вставить для борьбы с дребезгом.

Daemon2017
Offline
Зарегистрирован: 08.10.2013

arduinec пишет:

Daemon2017 пишет:

Так это же без разницы: для M2 в одну сторону вращаться - будет HIGH, а в обратную - LOW. 

То есть датчик может определять направление вращегния? С одной опто-парой?

Нет, не может. Двигатель используется как пример - можно было бы использовать не изменение направления его движения, а, скажем, вкл/выкл светодиода.

dimax
dimax аватар
Offline
Зарегистрирован: 25.12.2013

Daemon2017, это может быть и не дребезг, а какая-то мелкая наводка, текущая непойми откуда. Попробуйте в качестве эксперимента поменять логику срабатования прерывания, ловить не FALLING,  а RISING. Соответссно в сетапе подтяжку не делать. Если нужно -сделать стяжку к земле резистором. Но по идее с вашего датчика это не нужно, у него должны быть чёткие лог. уровни с низкоимпендансным выходом.

std
Offline
Зарегистрирован: 05.01.2012

dimax, кстати да

Deamount
Offline
Зарегистрирован: 07.05.2012

Daemon2017, решили проблему? в чём был косяк? хочу использовать такие модули... надёжные ли они?

Daemon2017
Offline
Зарегистрирован: 08.10.2013

Deamount пишет:

Daemon2017, решили проблему? в чём был косяк? хочу использовать такие модули... надёжные ли они?

После того, как я вставил RC-цепь, надежные :)