Космические значения при использовании attachInterrupt

ENiAC90
Offline
Зарегистрирован: 16.06.2017

Приветствую, Господа. Мои безмятежные представления об осовоении Ардуины впервые наткнулись на камень. 
Ближе к сути — Делаю элементарный тахометр. Классическая схема "Магнит—Датчик Холла". 

Использую простейшее прерывание от того-же AlexGyver (а сложных и не бывает):

 

unsigned long lastflash;
int RPM;

void setup() {
  Serial.begin(9600);  //открыть порт
  attachInterrupt(0,sens,RISING); //подключить прерывание на 2 пин при повышении сигнала
}
void sens() {
  RPM=60/((float)(micros()-lastflash)/1000000);  //расчет
  lastflash=micros();  //запомнить время последнего оборота
    Serial.println(RPM);
}

void loop() {
  if ((micros()-lastflash)>1000000){ //если сигнала нет больше секунды
    RPM=0;  //считаем что RPM 0
  }
   //вывод в порт
  delay(50);  //задержка для стабильности
}

И всё бы хорошо, но у него всё работает и очень красиво и точно показывает RPM, а у меня и еще нескольких комментаторов на Ютубе — заоблачные значения, среди которых преобладают 28896 и 19264.

Господа, одна надежда на Вас. Пните меня в нужную сторону, ибо у меня уже психоз. Гугл уже содрогается от моих запросов по "ардуино", "прерываниям" и "датчикам холла". И ведь даже у буржуев такой промблемы я не замечал.

Большое спасибо за уделенное время.

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

ENiAC90, ну он наверно не питает модуль от 3-го пина в Z состоянии?

ENiAC90
Offline
Зарегистрирован: 16.06.2017

Он питает, я тоже так подключал, но никакой разницы небыло. Поэтому я упростил код, и врубил питание на 5V. А картинку я у него взял.
Кроме того, в промежуточном кадре он показал это подключение:

 

Вот моё подключение:

Оранжевый на D2 подключен, на фото искажено

wdrakula
wdrakula аватар
Offline
Зарегистрирован: 15.03.2016

я сегодня дежурная "мать Тереза"

вот так делай:

Объяснять ничего не буду, нет желания. Сорри.

const uint32_t PrintInterval = 1000; //печать RPM каждую секунду

unsigned long lastflash;
int RPM;

void setup() {
  Serial.begin(9600);  //открыть порт
  attachInterrupt(0,sens,RISING); //подключить прерывание на 2 пин при повышении сигнала
}
void sens() {
static uint32_t ttt = micros();
  RPM=60000000UL/(ttt - lastflash);  //расчет
  lastflash=ttt;  //запомнить время последнего оборота
//НИКОГДА НЕ ИСПОЛЬЗУЙТЕ СЕРИАЛ В ПРЕРЫВАНИИ!
}

void loop() {
static uint32_t om = millis(); //old millis
uint32_t cm = millis();  //current millis
  if ((micros()-lastflash)>1000000){ //если сигнала нет больше секунды
    RPM=0;  //считаем что RPM 0
  }
   //вывод в порт
  if (cm - om > PrintInterval) {
    om = cm;
    Serial.print("RPM = ");
    Serial.println(RPM);
    }

 // delay(50);  //задержка для стабильности...... низахер не нужна
}

 

ENiAC90
Offline
Зарегистрирован: 16.06.2017

Сам терпеть ненавижу, когда новички не изучив матчасть лезут с элементарными вопросами. Посему всю жизнь пользуюсь поиском, и благодаря этим заданым нубским вопросам всегда нахожу все решения. Но сейчас я первый раз написал на форум с вопросом) Мне пришлось преодолеть свою гордость, ибо поиск информации в течении недели добавил мне пару седых морщин под глаза)) А ответа не нашлось.

Огромное спасибо за код, некоторых вещей я не понял, но буду пытаться понять самостоятельно. 
К примеру я не знал, что не нужно использовать Serial в прерывании. Но я изучу почему) Да и delay я знал, что не нужна, но привел код какой был изначально.
К сожалению, код не заработал у меня. RPM выдает -1. Хотя визуально всё должно работать. 

Забыл уточнить, в промежуточном положении магнита, цифровой сигнал с ДХ шарашит прерывания бесконечно. Но ведь я подключил к ЦИФРОВОМУ выходу, почему он уходит в разнос?... Очень напоминает дребезг кнопки. 

Блин, схема ПРОСТЕЙШАЯ, у всех работает! У меня что с цифровым ДХ, что с герконом — полный неадекват)

Уже и притягивал сигнал резистором, думал может "шумит". Один фиг — нифига))

Вы уж простите, господа. Не хотел создавать новую тему, но подумал, что есль получиться найти причину, то это поможет другим ищущим ответ на этот вопрос.

 

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

ENiAC90 пишет:

Забыл уточнить, в промежуточном положении магнита, цифровой сигнал с ДХ шарашит прерывания бесконечно. Но ведь я подключил к ЦИФРОВОМУ выходу, почему он уходит в разнос?... Очень напоминает дребезг кнопки. 

У вас датчик аналоговый, и резистором настраивается чувствительность. Если слишком высокая, то ловить может что угодно.  Светодиод то загорается/гаснет при поднесении магнита?

ENiAC90
Offline
Зарегистрирован: 16.06.2017

Сам датчик имеет цифровой и аналоговый выход. С цифровым имеется весьма мощный сигнал, но шумы нереальные. Если использовать аналоговый — значения становятся точнее, но чувствительность понижается в разы, приходится практически тереть по магниту, чтобы сработало прерывание.  Чувствительность настраивал очень много раз и пробовал разные варианты и комбинации. Если сильно завысить чувствительность, то ловит помехи от рук.

Спасибо за помощь в "обмозговывании")

wdrakula
wdrakula аватар
Offline
Зарегистрирован: 15.03.2016

-1, в контексте вашей формулы, это бесконечность. т.е. деление на ноль.

Значит прерывания приходит так быстро, что 60 миллионов делятся на 0 или очень маленькое число.

Что-то с датчиком у тебя, бро.

ENiAC90
Offline
Зарегистрирован: 16.06.2017

Датчик использую вот такой https://arduino-kit.ru/catalog/id/modul-datchika-holla-_lineynyiy_

В видео у Алекса https://www.youtube.com/watch?v=x2fLvS8Ms9w (ну красиво-жи!) используется такой 

 

Оба имеют цифровые выходы. Оба подключаются к NANO. Причем я пробовал на двух МК, приобретенных в разных магахинах.

Я сразу подумал, что датчик шалит, но при подключении геркона (обычного, велосипедного) по этой схеме:

происходит то-же самое. Нереальное количество прерываний за один проход.

Я пробовал фильтровать так: 
 

void sens() { 
   RPM = round(60/((float)(millis()-lastflash)/1000)); //Сразу считаю RPM

if (RPM != 0) {               //Если RPM текущее не равно нулю (при неправильных срабатываниях)
    
    if ((RPM - RPM_0) > 1000)  //Если нет "космической" разницы с предыдущим значением
   {
     RPM = RPM_1;             //Уравниваем
    }

tm1637.display(((RPM+RPM_0+RPM_1)/3));  //Вывожу среднее из трех последних

if (switch1 == 1) { 
    RPM_1 = RPM; switch1 = 0;
    } else { 
      RPM_0 = RPM; switch1 = 1;
    }

  }
  
  lastflash = millis();  

}

Кое как сие решение работает, но даже не смотря на этот кривой костыль, всё равно проскакивали залётные значения. 

Как понять, что датчик глючный? И в нём ли дело, если с герконом работает так-же?... 

А что если ардуинки гумн.... да не, не может быть!

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

ENiAC90, ардуину можно проверить подав тестовый меандр вместо датчика. Сигнал можно взять с другой ардуины. Датчик (на наличие помех на выходе) можно проверить осциллографом или лог.анализатором.

ENiAC90
Offline
Зарегистрирован: 16.06.2017

Господа dimax и wdrakula! Огромнейшее спасибо вам, что откликнулись! Вы оказались правы. Датчик — отвратительнейшего качества! Я не мог в это поверить, ведь они же продаются сотнями на Алиэкспресс и в наших магазинах. И в интернете нет АБСОЛЮТНО никаких негативных отзывов о их работе, посему я думал, что сам дурак! Сегодня абсолютно случайнейшим образом наткнулся на это видео: 

hqdefault.jpg

https://www.youtube.com/watch?v=Lj3TrTlYzyQ

Я подофигел (хотя бывалых, уверен, таким не испугаешь). Осциллограф сорвал покровы и обнажил качество работы сего модуля. Теперь отчетливо понятно, почему у меня заоблачные значения получались в прерываниях. Но зачем здесь компаратор и подстроечный резистор?... Как говорится, с этим вопросом я жил ровно 2 минуты.

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

Единственное, чем я могу объяснить сходство нереального количества срабатываний геркона и сего ДХ в промежуточном положении магнита — геркон имеет дребезг, и я попробую его завязать через RC цепь с триггером Шмитта (который при подключении питания от ардуины на 14-ю и 7-ю ногу почему-то даёт космический шум в мои колонки) 

Следующим видео у автора было: 

hqdefault.jpg

https://www.youtube.com/watch?v=xnwb-gVASiE

Если бы я купил сразу такой датчик, я бы не получил такой печальный, но нужный опыт.

(Можно-ли попросить модератора изменить название темы на "Остерегайтесь бракованных китайских датчиков. Сумасшедший Датчик Холла." Чтобы не вводить людей в заблуждения, в которое попал я)

Еще раз огромное спасибо вам!