Чтение сигнала тахометра, нужна помощь

V2oD2o
Offline
Зарегистрирован: 24.11.2015

Всем привет, имеется код:

01volatile float time = 0;
02volatile float time_last = 0;
03int rpm = 0; 
04bool update=false;
05 
06void setup()
07{
08  Serial.begin(9600);
09  attachInterrupt(0, interrupt, RISING);
10}
11 
12void loop()
13{
14  delay(500);
15  if (update==true && (60*(1000000/(time*2))<9000)) { rpm = 60*(1000000/(time*2)); }
16  update=false;
17  Serial.print("RPM-");Serial.print(rpm);Serial.print(" time-");Serial.println(time);
18}
19 
20void interrupt()
21{
22   time = (micros() - time_last);
23   time_last = micros();
24   update=true;
25}

Вот вывод по порту

 

вывод слева - без переменной update и без контроля <9000 и >0 - в моем "железе" такие цифры не приемлемы, черевато поврежением механизмов, справа "фильтр" от скачков и переменная update - если отсутствует прерывание чтоб не считало минусовые значения

Сигнал вот такой:

Вопрос - откуда такие скачки? минус вероятно - при отсутствии прерываний, это ладно, а вот откуда значения более 9000 ?

Обороты девайса по факту = 1800-1900

Сигнал как видно скачет и в + и в -, амплитуда 5в

Причем сигнал удалось поймать только при подключении контакта ардуино +5в на массу устройства через резистор 10кОм, напрямую пусто

V2oD2o
Offline
Зарегистрирован: 24.11.2015

возможно стоит подключить связующий транзистор который 100% открывал бы прерывание при наличии положительного полупериода входящего сигнала ?

V2oD2o
Offline
Зарегистрирован: 24.11.2015

 

Отрезал отрицательную составляющую, походу амплитуда слабовата для реагирования прерывания, срабатывает при +3в

nik182
Offline
Зарегистрирован: 04.05.2015

Как всё запущено. Неоднократно обсасывалось. У вас дребезг цепи прерывания дает несколько прерываний вподряд. Про это говорит время 12-16 мкс. Нужно и помехоподавляющую RC цепь на ноге городить и внутри прерывания задержку на 100 мкс организовывать. Максимальное время наводки на ваших рисунках 952 мкс. Максимальное дребезга 88 мкс.

V2oD2o
Offline
Зарегистрирован: 24.11.2015

Откуда интересно взялся дребезг с выхода цифрового утройства? помех на линии тоже не замечено, шум держится на уровне <0.2V, суть в чтении полезного сигнала, который составляет 1.5-5V

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

V2oD2o, У вас есть возможность снять скриншот с нормального осциллографа? То что вы показали -это то, как ардуина воспринимает сигнал, но о самом сигнале даже  примерно, даже ОЧЕНЬ отдалённого  представления по этой картинке -не получить.

V2oD2o
Offline
Зарегистрирован: 24.11.2015

Это скрин как раз с осциллогафа, я запускаю ардуину и одновременно с этим замеряю цилографом

nik182
Offline
Зарегистрирован: 04.05.2015

Если осцилограф хороший, включите его на диапазанон 5 мкс и посмотрите что прямо на ножке ардуины происходит. Увидите несколько затухающих колебаний. Индуктивности и емкости соединительных проводов хватает на такой процесс. Иногда достаточно резистором ом 200 зашунтировать вход, что бы избавиться от такого дребезга. Но лучше ещё и RC цепь добавить как можно ближе к ноге. Вход прерывания имеет высокий импенданс и реагирует на любую иголку, которую даже осцилографом сложно рассмотреть.

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

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

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

 Я бы посоветовал применить одновременно и аппаратные и программные методы.

1.Аппаратно: поставить лоу-пасс фильтр: от датчика сначала резистор на 1К, после него конденсатор на землю (10-100нФ), потом на ввод.

2. программно запретить прерывания во время обработки прерывания. Это совершенно обязательно. Вообще этого хватит, но аппаратно от дребезга тоже полезно прикрыться. Как бы лишним не будет.

V2oD2o
Offline
Зарегистрирован: 24.11.2015

Ну хоть какой то есть под рукой..

V2oD2o
Offline
Зарегистрирован: 24.11.2015

Вот кстати прям на ноге - не смотрел, смотрел только выход источника сигнала

V2oD2o
Offline
Зарегистрирован: 24.11.2015

Спасибо, попробую!

nik182
Offline
Зарегистрирован: 04.05.2015

wdrakula пишет:

 Я бы посоветовал применить одновременно и аппаратные и программные методы.

1.Аппаратно: поставить лоу-пасс фильтр: от датчика сначала резистор на 1К, после него конденсатор на землю (10-100нФ), потом на ввод.

2. программно запретить прерывания во время обработки прерывания. Это совершенно обязательно. Вообще этого хватит, но аппаратно от дребезга тоже полезно прикрыться. Как бы лишним не будет.

Я вот каким вопросом задаюсь. В даташите написано: "The flag is cleared when the interrupt routine is executed. Alternatively, the flag can be cleared by writing a logical one to it.".  Вот когда обнуляется флаг? При входе в прерывание? Пока исполняется прерывание? Ведь даже если запретить прерывание, то флаг то выставиться. И при разрешении программа опять свалится в прерывание. Т.Е. запрет не защитит от повторного срабатывания. У себя я вижу дребезг существенно короче 12мкс. В STM32 очистку флага отдали програмисту. Я его обычно чищу перед выходом из прерывания. Может быть здесь попробовать тоже чистить программно перед выходом? Может поможет?

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

Это про флаг, а не про прерывание. Флаг удобен, если Вы не прерываете что-то важное, но обработаете событие потом.

При внешних прерываниях INT, повторный вызов не произойдет при прерывании по уровню, а по фронту - спокойно, поэтому и нужно cli-sti скобки ставить вокруг обработчика.

nik182
Offline
Зарегистрирован: 04.05.2015

Хорошо полная цитата.

Pin Change Interrupt Flag Register – PCIFR

When a logic change on any PCINT7..0 pin triggers an interrupt request, PCIF0 becomes set (one). If the I-bit in SREG and the PCIE0 bit in EIMSK are set (one), the MCU will jump to the corresponding Interrupt Vector. The flag is cleared when the interrupt routine is executed. Alternatively, the flag can be cleared by writing a logical one to it.

Ок. Если запретить прерывания - не выставится. Но вот вопрос - когда запрещать прерывания ? Если внутри прерывания, то есть время между входом и запретом когда флаг может выставится. И потом после снятия запрета может сработать. Именно этот флаг вызывает прерывание! Его очистка внутри прерывания ,  перед разрешением глобального прерывания позволит избежать повторного прерывания. 

 

ssss
Offline
Зарегистрирован: 01.07.2016

Что, так тяжело с переводом?

The flag is cleared when the interrupt routine is executed. - Когда уже выполнено, перед выходом из прерывания. А вообще, быстрее было написать несколько строчек и проверить в железе, для самоуспокоения. Там делов то, ногой в прерывании дёрнуть.

Alternatively, the flag can be cleared by writing a logical one to it. - Это, в основном, для случая без использования прерываний. Флаг то устанавливается независимо, разрешено само прерывание или нет.

 

 

nik182
Offline
Зарегистрирован: 04.05.2015

Слушай. Знаток английского. Ты знаешь что такое Participle II   и как оно переводится на русский? Возьми учебник и почитай. Или гугля спроси. Он умный. Он знает. Нет здесь пршедшего времени. От слова совсем. Именно это у меня и вызывает вопрос. Было бы прошедшее время, вопроса бы не было.

ssss
Offline
Зарегистрирован: 01.07.2016

Клоун ты доморощенный! А написать пару строчек и проверить в железе у тебя тоже времени нет? Ну да! Тебе надо спасать мир! )))))))))

И на СТМ32 ты сбрасываешь флаг перед выходом потому что юзаешь СПЛ или ХАЛ... А впрочем, истери и дальше.

nik182
Offline
Зарегистрирован: 04.05.2015

 А при чем тут СПЛ или ХАЛ? В STM32 нет аппаратного сброса. Или опять песня про полностью аппаратные решения?

ssss
Offline
Зарегистрирован: 01.07.2016

Тогда тебе задание на дом! Найти на сайте АРМ что такое "барьеры" и выучить для чего они вообще.