Проблемы с прерыванием

Yoga
Offline
Зарегистрирован: 01.08.2015

Доброго всем дня.
У меня такой вопрос, делаю небольшой проект, где требуется подсчет оборотов мотора и последующие вычисления. Имеется небольшой модуль, по сути обычная оптопара, но что-то еще есть, в электронике не очень разбираюсь. Выдает либо аналоговой сигнал, либо цифровой. Так же на моторе у меня сделано отверстие, чтобы замыкать оптопару. 

Дак вот, после поиска пришел к выводу, что это можно и нужно реализовать через прерывание. Когда оптопара закрыта, идет 1, когда она открывается(то есть прошел один оборот) идет 0. Написал простой скетч для теста

#define ReadOpt 3

volatile long int total;

void setup() {
  //выставляем pinMode
  pinMode(ReadOpt, INPUT);
  digitalWrite(ReadOpt, HIGH);
    //Сериал
  Serial.begin(9600);
  Serial.println("Test");
  
    //прерывание
  attachInterrupt(1, interruptRead, FALLING);
}


void loop() {
  
  Serial.println(total);

}

void interruptRead(){
total++;
  }

И вроде бы все хорошо, обороты считаются, но у меня закралось сомнение, что черезчур много считает. Решил в ручную открывать и закрывать оптопару картоном. Дак вот, когда я открываю оптопару и сигнал переходит с HIGH в LOW, прерывание срабатывает 3-4 раза и затем, когда закрываю он еще пару раз вызывает прерывание.

Итог:
1) Прерывание срабатывает почему-то не один раз
2) Прерывание в режиме FALLING срабатывает даже тогда, когда сигнал идет с 0 в 1. 

Что я сделал не так и в сторону чего смотреть? 

Yoga
Offline
Зарегистрирован: 01.08.2015
#define ReadOpt 3

volatile long int total;

void setup() {
  //выставляем pinMode
  pinMode(ReadOpt, INPUT);
  pinMode(6, OUTPUT);
  digitalWrite(6, HIGH);
    //Сериал
  Serial.begin(9600);
  Serial.println("Test");
  
    //прерывание
  attachInterrupt(1, interruptRead, FALLING);
}


void loop() {
  
  Serial.println(total);

}

void interruptRead(){
total++;
  }

Верный код. На 6 ножке весит моторчик.

Puhlyaviy
Puhlyaviy аватар
Offline
Зарегистрирован: 22.05.2013

интересно сколько раз успеет цикл выполниться пока дырка открыта?

тут один чувак с австралии. очень подробно все описал и даже код приложил

http://www.gammon.com.au/forum/?id=11504

 

Yoga
Offline
Зарегистрирован: 01.08.2015

Puhlyaviy пишет:

интересно сколько раз успеет цикл выполниться пока дырка открыта?

тут один чувак с австралии. очень подробно все описал и даже код приложил

http://www.gammon.com.au/forum/?id=11504

 

Ну ведь по идее, цикл должен выполнится один раз, пока дырка открыта. Это мне и нужно, чтобы при открытии оптопара прибавить один оборот.

Почитал статью, что вы скинули. Там ведь идет речь о прерывании по таймеру, нет? Не мой ведь случай.

Puhlyaviy
Puhlyaviy аватар
Offline
Зарегистрирован: 22.05.2013

Yoga пишет:

Ну ведь по идее, цикл должен выполнится один раз, пока дырка открыта. Это мне и нужно, чтобы при открытии оптопара прибавить один оборот.

давайте думать логически

в чем же блин разница между

attachInterrupt(1, interruptRead, FALLING);

и

attachInterrupt(1, interruptRead, CHANGE);

и как с этим жить

Yoga
Offline
Зарегистрирован: 01.08.2015

Давайте :)

Разница в том, что FALLING - вызывает функцию один раз при переходе с HIGH в LOW, а CHANGE - вызывает функцию при любом изменении. 

Falling для моей цели подходит идеально, но почему-то функция вызывает как change при любом изменении сигнала, да и плюс к этому несколько раз.

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Yoga пишет:

в сторону чего смотреть? 

 

В сторону борьбы с дребезгом.

Yoga
Offline
Зарегистрирован: 01.08.2015

На ум приходит сравнивать время срабатываний и если оно больше, допустим, 100мс, то прибавлять один оборот. Но ведь скорость вращения может быть разной, следовательно и время будет разным. То есть в итоге погрешность все равно будет присутствовать.

Это если программно. Быть может есть способ аппаратно это сделать? 

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

Аппаратно то же самое: ФНЧ и триггер Шмитта.

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Yoga пишет:

На ум приходит сравнивать время срабатываний и если оно больше, допустим, 100мс, то прибавлять один оборот. Но ведь скорость вращения может быть разной, следовательно и время будет разным. То есть в итоге погрешность все равно будет присутствовать.

зачем?. Гораздо проще смотреть время с последнего прерывания и если оно меньше, скаем, 20 мс, игнорировать текущее прерывание. Тогда погрешности не будет, т.к. первое прерывание в цепочке дребезга приходит как раз когда дырка начинает закрываться.

20 мс я от балды написал. По уму надо посмотреть осциллографом сколько там времени дребезжит и взять с небольшим запасом.

Yoga
Offline
Зарегистрирован: 01.08.2015

ЕвгенийП, понял вас. И то есть, если правильно подобрать время, то независимо от скорости вращения, прибавлять будет корректно?

Logik
Offline
Зарегистрирован: 05.08.2014

Yoga пишет:

И то есть, если правильно подобрать время, то независимо от скорости вращения, прибавлять будет корректно?

Не будет! Будет четко ловится спад и иногда (при дребезге) наростание. Для обеспечения стабильности можна настроить прерывание по изменению и при правильном времени защиты от дребезга получите удвоеное число оборотов.

jeka_tm
jeka_tm аватар
Offline
Зарегистрирован: 19.05.2013

Puhlyaviy пишет:

интересно сколько раз успеет цикл выполниться пока дырка открыта?

тут один чувак с австралии. очень подробно все описал и даже код приложил

http://www.gammon.com.au/forum/?id=11504

английский не знаю, но думаю по этомй статье реально смогу научиться. спасибо. вроде все более менее понятно на первый взгляд

Gres
Gres аватар
Offline
Зарегистрирован: 26.03.2013

Yoga пишет:

С подтягивающими резисторами у меня не все однозначно получалось. Попробуйте убрать эту строку, а подтяжку, если она нужна выполнить аппаратно.

Yoga
Offline
Зарегистрирован: 01.08.2015

немного не понял, о какой строчке идет речь?

Gres
Gres аватар
Offline
Зарегистрирован: 26.03.2013

Yoga пишет:

немного не понял, о какой строчке идет речь?

Я про первый пост, 8 строка скетча.

Сейчас увидел, что в следующей версии(следующий пост) Вы ее уже убрали.