Замер времени между срабатываниями датчиков

Booooooot
Offline
Зарегистрирован: 08.01.2017

Всем привет, нужна не большая помощь в программировании аруины. Вобщем, есть 2 датчика, можно считать их хоть кнопками ибо они реагируют на событие и выдают либо 1 либо 0. Нужно засечь время между срабатыванием первого датчика и второго. Как это сделать, вообще не понимаю... Потом это все в массивчик закинуть, но думаю это я смогу уже прикрутить)

Буду безгранично благодарен тому, кто поможет :)

JasKo
Offline
Зарегистрирован: 21.11.2015

Ну, как минимум разрешить прерывания по изменению  стотояния пинов порта куда подключены датчики, (лучше использовать пины одного порта), написать обработчк прерывания, в котором считывать стотояние millis() и вычилять разницу от предыдущего срабатывания.

PS: Если нужен скетч, то добропожаловать в "Ищу исполнителя" - где за небольшое вознаграждение откликнется куча желающих.

Booooooot
Offline
Зарегистрирован: 08.01.2017

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

Значит копать в сторону прерываний, спасибо тебе!

a5021
Offline
Зарегистрирован: 07.07.2013

Для подобных задач хорошо подходит таймер в режиме захвата. Можно вообще прерывания не использовать.

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

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

Booooooot
Offline
Зарегистрирован: 08.01.2017

Ухты, то что нужно! Спасибо тебе огромное!

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

Для программирования ардуины нужны три вещи:milis() , millis()  и еще millis().

Booooooot
Offline
Зарегистрирован: 08.01.2017

Попробовал только что 2 предыдущих совета, ничего не получилось((

Попробую прерывания и millis()...

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016
/*millis_start_stop.ino
  #1 кнопка1 -> 2 (btn1_pin) 0 нажата /1 нет
  #2 кнопка2 -> 3 (btn2_pin) 0 нажата /1 нет
  Принцип кода: В сериал отправляется время между 1 и 2 нажатием
*/
// #1
const int btn1_pin = 2; // вывод кнопки 1
bool btn1, btn1_old ; //значение на кнопке без дребезга, тоже но стар значение
bool bounce_btn1 = 0; //антидребезговый флаг
// #2
const int btn2_pin = 3; // вывод кнопки 2
bool btn2, btn2_old ; //значение на кнопке без дребезга, тоже но стар значение
bool bounce_btn2 = 0; //антидребезговый флаг
void setup() {
  Serial.begin(9600);
  // #1
  pinMode(btn1_pin, INPUT_PULLUP); // подключить кнопку 1 с подтяжкой
  btn1 = digitalRead(btn1_pin);
  // #2
  pinMode(btn2_pin, INPUT_PULLUP); // подключить кнопку 2 с подтяжкой
  btn2 = digitalRead(btn2_pin);
}
void loop() {
  // #1
  static uint32_t past_1 = 0 ;
  static uint32_t past1_1 = 0 ;
  if (! bounce_btn1 && btn1 != digitalRead(btn1_pin)) { // если прошел фронт изм на выводн
    bounce_btn1 = 1;    // выставить флаг
    past_1 = millis();  // сделать временую отчет
  }
  else if ( bounce_btn1 && millis() - past_1 >= 5 ) { // если прошло антидребезговое время
    bounce_btn1 = 0;      // то снять флаг
    btn1_old = btn1;
    btn1 = digitalRead(btn1_pin) ; // прочитать реальное значение на выводе
    if (btn1_old && ! btn1) {      // если обнаружилось что это было нажатие
      past1_1 = millis();// сделать временной отчет нажатия кнопки
    }
  }
  // #2
  static uint32_t past_2 = 0 ;
  if (! bounce_btn2 && btn2 != digitalRead(btn2_pin)) { // если прошел фронт изм на выводн
    bounce_btn2 = 1;   // выставить флаг
    past_2 = millis(); // сделать временую отчет
  }
  else if ( bounce_btn2 && millis() - past_2 >= 5 ) { // если прошло антидребезговое время
    bounce_btn2 = 0;      // то снять флаг
    btn2_old = btn2;
    btn2 = digitalRead(btn2_pin) ; // прочитать реальное значение на выводе
    if (btn2_old && ! btn2) {      // если обнаружилось что это было нажатие
      Serial.print("Time 1->2:");
      Serial.println( millis() - past1_1);
    }
  }
}

 

Booooooot
Offline
Зарегистрирован: 08.01.2017

Спасибо большое! Только код сложноват для меня((

Попытаюсь из этого выделить "голую" функцию засекания времени...

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

Это же для механических кнопок, защита от дребезга. Тестовая программа.

Booooooot
Offline
Зарегистрирован: 08.01.2017

В принципе я уже немного модифицировал, и уже есть результат. Осталось только убрать все лишнее, и понять принцип)

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

millis() это часы, но не человеческие(секунды, минуты,часы) , а машинные . Счет милисекунд (0,001 сек)от подачи питания или RESET. Одним датчиком "засекаешь время",а втором вычитает разницу между текущим и ранее засеченым. Ну там может быть от 1 милисек до 48 дней. 

Booooooot
Offline
Зарегистрирован: 08.01.2017

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

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

Booooooot пишет:

мне нужен сам алгоритм засекания и вычитывания разницы

А какой у Вас алгоритм засекания времени без компьютерной программы?

В момент первого события посмотреть на часты и записать время Т1. В момент второго события посмотреть на часы и записать время Т2. Затем из Т2 вычесть Т1 - получится время между событиями. Вы не знаете этого алгоритма?

Booooooot
Offline
Зарегистрирован: 08.01.2017

Уже разобрался, всем большое спасибо! Что бы я без вас делал)

mag155
Offline
Зарегистрирован: 21.12.2017

Всем привет! Такой вопрос еть два флага которые поднимаюстся сначала оди потом второй нужно замерять время между их срабатываниями частота срабатывания 50 герц . Прерывания использовать не желательно ибо ардуина и так загружена и прерывать ее нельзя. Мерять можно к примеру раз в 5 секунд. 

if (micros() - time_F15 > 80000){
time_F15 = micros();
if(flag_F1on == 1 ){
 time_F13 = micros;  
} 
 if(flag_F2on == 1 ){  
 time_F14 = micros;
 val = time_F14 - time_F13;
 time_F13 = 0;
 time_F14 = 0;
 }  
}  
   Serial.println   ( val);

Пробовал вот так но данные постоянно разные я так думаю проблема в том что все же нужно через прерывания ? Но может есть какоето другое решение ???

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

Я может чаго-то нежопонял, но если по условию

mag155 пишет:

нужно замерять время между их срабатываниями частота срабатывания 50 герц . 

То время, очевидно, 20мс - чего его замерять-то?

Или это у каждого флага 50Гц, а Вы хотите сдвиг фазы измерять? Поясните что нужно-то.

mag155
Offline
Зарегистрирован: 21.12.2017

Фаз всего три нужно измерить время между первым и двумя на случай не правильной фазировки . Если не правильная фазировка время между флагами должно быть больше.

mag155
Offline
Зарегистрирован: 21.12.2017

Время

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

А зачем время? Три входа, после првого смотрим кто раньше - в ту сторону и крутится поле. Время совсем не нужно.

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

Понятие "раньше" без понятия "время" не существует.

mag155
Offline
Зарегистрирован: 21.12.2017

Истину глаголите.

mag155
Offline
Зарегистрирован: 21.12.2017

Может чё посоветуете есть еще три цифровых входа которые считывают импульсы с каждой из фаз.

Arhat109-2
Offline
Зарегистрирован: 24.09.2015

mag155, для замера интервалов между событиями по одному входу у мег есть "прерывание по захвату таймера" для 16-и битных таймеров. Используйте его для точного замера. Никакой "имитатор" не даст большей точности.

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

Прерывания по захвату у ардуиновской Мега2560 есть только от двух таймеров 4,5 .. используйте Arduino Core или мою плату (Ардуино Мега + расширенная память, ссылку уже приводил Вам) если нужно больше таких прерываний..

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

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