измерение интервалов сигналов. как правильно реализовать.

servilat
Offline
Зарегистрирован: 12.12.2013

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

__________|````|___________________________________|```````|_______......

параметры сигнала полки в пределах 10-100 мкс

передний фронт от 0 в 1  в пределах от 200 мкс до 2000мкс

16МГц

эти 2 полки с 2х разных датчиков, поэтому есть возможность привязать к 2м разным ногам контролера только имеет ли смысл?

как правильно это сделать?

с чего начинать?

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

нужны ли прерывания?

 

maksim
Offline
Зарегистрирован: 12.02.2012

servilat пишет:

с чего начинать?

С нормального описания протокола, по которому общается датчик и дать ссылку на описание датчика. А то в результате может оказаться так что вы пытаетесь описать PWM, PPM, PCM, 1-Wire или VirtualWire...

maksim
Offline
Зарегистрирован: 12.02.2012

   

servilat
Offline
Зарегистрирован: 12.12.2013

оптические датчики на разрыв луча HOA6503-001

http://www.sensorica.ru/shop/datchiki_opticheskie-32403-507950071

сори. сразу не дошло уточнить.

servilat
Offline
Зарегистрирован: 12.12.2013

оптические датчики на разрыв луча HOA6503-001

http://www.sensorica.ru/shop/datchiki_opticheskie-32403-507950071

сори. сразу не дошло уточнить.

двоит сайт

step962
Offline
Зарегистрирован: 23.05.2011

servilat пишет:

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

__________|````|___________________________________|```````|_______......

параметры сигнала полки в пределах 10-100 мкс

"полка" - это высокий уровень?

Цитата:

передний фронт от 0 в 1  в пределах от 200 мкс до 2000мкс

"передний фронт" - это время перехода с низкого на высокий уровень? Или все же время до этого перехода?

Цитата:

16МГц

эти 2 полки с 2х разных датчиков, поэтому есть возможность привязать к 2м разным ногам контролера только имеет ли смысл?

как правильно это сделать?

с чего начинать?

Прерывание по переднему фронту - настраиваем и запускаем таймер/счетчик. Прерывание по заднему фронту - считываем значение таймера/счетчика.

Это если важны лишь длины участков с высокими уровнями. Если необходима полная картина - обнуляем/запускаем таймер/счетчик по какому-либо триггеру, в прерываниях по переднему/заднему фронту запоминаем информацию о времени(значении счетчика) и типе перехода (LOW->HIGH / HIGH->LOW). В "периоды затишья" анализируем. 8-битного счетчика на это не хватит. С 16-битным есть надежда, что удастся собрать всю нужную информацию до его переполнения. В противном случае придется ввести дополнительную переменную - счетчик переполнений таймера. Но тогда и с 8-битовым Т/С можно все правильно обсчитать.

Цитата:

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

"задержка" - примерно одинакова при обработке что переднего фронта, что заднего: 4+ такта (1/4+ мксек) Значит - взаимно компенсируется. При правильной настройка таймера/счетчика эта задержка вообще не будет влиять на результат, т.к. ЦПУ будет работать с "замороженными" значениями.

Цитата:

нужны ли прерывания?

Нужны ... если важен результат.

maksim
Offline
Зарегистрирован: 12.02.2012

Еще бы написали что хотите мерить - обороты?

http://arduino.ru/forum/programmirovanie/takhometr-0

servilat
Offline
Зарегистрирован: 12.12.2013

пролет пули между оптодатчиками. скорость от 100 до 500 м/сек

за сылку спасибо! шас гляну

maksim
Offline
Зарегистрирован: 12.02.2012

Ну так что ж вы, называйте вещи своими именами

Хронограф

servilat
Offline
Зарегистрирован: 12.12.2013

спасибо!

код практически совпал 2 прерывания на 2х ногах по высокому и разница в void с выводом.

пока неиспользовал флаг boolean flag

servilat
Offline
Зарегистрирован: 12.12.2013

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

тестировал gama hunter 440 новое с магазина выдавало 147-150мс пуля 0,49гр

после установки газовой пружины выдало 298-306мс пуля таже (по ТХ завода 308 мах), первые 3 пули с эффектом дизиления ушли на сверхзвук 410, 388, 340 мс с характерным выстрелом малокалиберной винтовки, из за них масляный нагар на аллюминевом квадрате

пришлось мерять передние и задние фронты сопоставлять разницу мкс по сенсорам и между ними. вобщем при упертой хорошо винтовке разница 0 микросекунд, приболтающейся в воздухе доходило до 40 мкс, также Delta_speed_bullet=0 являлось показателем соосности траектории и центров оптических датчиков, при отклонении появлялась разница

таблица времени с проца до модернизации, сам код и фото

  1 2 3 4 5 6 7
Time1Up =  52159588 34699108 30000076 364682112 452632192 579092180 700015628
Time1Down =  52159624 34699144 30000112 364682148 452632228 579092216 700015660
Time2Up = 52160396 34699948 30000904 364682992 452633088 579092976 700016476
Time2Down = 52160432 34699984 30000944 364683032 452633128 579093012 700016516
               
               
               
T1_bullet = 36 36 36 36 36 36 32
T2_bullet = 36 36 40 40 40 36 40
               
Diff_T1T2_bullet_Up =  808 840 828 880 896 796 848
Diff_T1T2_bullet_Down = 808 840 832 884 900 796 856
               
               
               
Start_speed_bullet_sensor1 = 180,555556 180,5556 180,5556 180,5555556 180,5555556 180,5555556 203,125
Start_speed_bullet_sensor2 = 180,555556 180,5556 162,5 162,5 162,5 180,5555556 162,5
               
Start_speed_bullet_Up = 148,514851 142,8571 144,9275 136,3636364 133,9285714 150,7537688 141,509434
Start_speed_bullet_Down = 148,514851 142,8571 144,2308 135,7466063 133,3333333 150,7537688 140,1869159
               
Start_speed_bullet =  148,514851 142,8571 144,5792 136,0551213 133,6309524 150,7537688 140,8481749
Delta_speed_bullet = 0 0 18,05556 18,05555556 18,05555556 0 40,625
               
Slowing_speed_bullet = 0 0 21753,68 20471,15142 20106,4093 0 47681,92488
               
Energy_bullet = 5,40388197 5 5,121267 4,535194031 4,375021701 5,568041211 4,860361053
               
Measurement_error = 18,4033273 17,02707 17,44029 15,44333958 14,89761605 18,96273822 16,55126711




//Хронометр
#include <LiquidCrystal.h>
LiquidCrystal lcd(4, 5, 10, 11, 12, 13);


volatile unsigned long Time1Up = 0;      //Время срабатывания первого датчика передний фронт
volatile unsigned long Time1Down = 0;    //Время срабатывания первого датчика задний фронт
volatile unsigned long Time2Up = 0;      //Время срабатывания второго датчика передний фронт
volatile unsigned long Time2Down = 0;    //Время срабатывания второго датчика задний фронт

long T1_bullet = 0;                      //время пролета пули по первому датчику (мкс) /1000000
long T2_bullet = 0;                      //время пролета пули по второму датчику (мкс) /1000000
long Diff_T1T2_bullet_Up = 0;            //время пролета пули между датчиками по переднему фронту (мкс) /1000000
long Diff_T1T2_bullet_Down = 0;          //время пролета пули между датчиками по заднему фронту (мкс) /1000000

float Distance_sensor = 120.00 / 1000;    //расстояние между датчиками (мм) /1000

//GAMO PRO MAGNUM
float Mass_bullet = 0.48 / 1000;         //масса пули (гр) / 1000
float length_bullet = 6.50 / 1000;       //длина пули (мм) /1000

//PREDATOR POLYMAG
//float Mass_bullet = 0.52 / 1000;         //масса пули (гр) / 1000
//float length_bullet = 8.70 / 1000;       //длина пули (мм) /1000
//float length_bullet = 6.50 / 1000;       //длина пули (мм) /1000 ?

//LUMAN DOMED PELLETS
//float Mass_bullet = 0.68 / 1000;         //масса пули (гр) / 1000
//float length_bullet = 6.40 / 1000;       //длина пули (мм) /1000

//H&N SPORT Baracuda
//float Mass_bullet = 0.69 / 1000;         //масса пули (гр) / 1000
//float length_bullet = 7.00 / 1000;       //длина пули (мм) /1000

//JSB MATCH DIABLO
//float Mass_bullet = 0.67 / 1000;         //масса пули (гр) / 1000
//float length_bullet = 6.30 / 1000;       //длина пули (мм) /1000



float Start_speed_bullet_Up = 0;         //скорость пули по передним фронтам (мкс) /1000000
float Start_speed_bullet_Down = 0;       //скорость пули по задним фронтам (мкс) /1000000
float Start_speed_bullet_sensor1 = 0;    //скорость пули по по первому датчику (мкс) /1000000
float Start_speed_bullet_sensor2 = 0;    //скорость пули по по второму датчику (мкс) /1000000
float Start_speed_bullet = 0;            //средняя скорость по переднему и заднему фронту (мкс) /1000000
float Delta_speed_bullet = 0;            //разница скороростей по прохождению через 2 датчика (мкс) /1000000
float Slowing_speed_bullet = 0;          //замедление пули вычесленное по 2м щелевым датчикам по разнице времени прохождения через каждый (мс^2) (ускорение)
float Measurement_error = 0;             //погрешность измерения
float Energy_bullet = 0;                 //энергия пули (Дж)

boolean flag = false;                    // флаг запуска расчетов и вывода
boolean flag_lcd = true;

void setup() {
  Serial.begin(57600);
  attachInterrupt(0, StartUp, CHANGE);   //Прерывание по фронту на D0
  attachInterrupt(1, EndUp, CHANGE);     //Прерывание по фронту на D1
  // устанавливаем размер (количество столбцов и строк) экрана
  lcd.begin(20, 4);
}

void loop() {
  if (flag == true) {
    flag_lcd = true;
    T1_bullet = (Time1Down - Time1Up);                                                     //время пролета пули в щели первого датчика (мкс) /1000000
    T2_bullet = (Time2Down - Time2Up);                                                     //время пролета пули в щели второго датчика (мкс) /1000000
    Diff_T1T2_bullet_Up = (Time2Up - Time1Up);                                             //время пролета пули между датчиками по переднему фронту (мкс) /1000000
    Diff_T1T2_bullet_Down = (Time2Down - Time1Down);                                       //время пролета пули между датчиками по заднему фронту (мкс) /1000000

    Start_speed_bullet_sensor1 = length_bullet * 1000000 / T1_bullet;              //скорость пули по по первому датчику (м*сек)
    Start_speed_bullet_sensor2 = length_bullet * 1000000 / T2_bullet;              //скорость пули по по второму датчику (м*сек)
    Start_speed_bullet_Up = Distance_sensor * 1000000 / Diff_T1T2_bullet_Up;        //скорость пули по передним фронтам (м*сек)
    Start_speed_bullet_Down = Distance_sensor * 1000000 / Diff_T1T2_bullet_Down;    //скорость пули по задним фронтам (м*сек)

    Start_speed_bullet = (Start_speed_bullet_Up + Start_speed_bullet_Down) / 2;            //средняя скорость пули по фронтам датчиков (м*сек)
    Delta_speed_bullet = Start_speed_bullet_sensor1 - Start_speed_bullet_sensor2;          //разница скоростей прохождения через датчики (м*сек)
    Slowing_speed_bullet = Delta_speed_bullet * 1000000 / (((Diff_T1T2_bullet_Up + Diff_T1T2_bullet_Down) / 2)) / 1; //(ускорение) замедление пули усреднено по фронтам через датчики
    //енергия пули
    Energy_bullet = (Mass_bullet * sq(Start_speed_bullet)) / 2;
    // погрешность измерения. точность измерения времени 1мкс
  //  Measurement_error = 100 * (abs(Distance_sensor/((Distance_sensor/Start_speed_bullet) - 0.000001) - Start_speed_bullet));
      Measurement_error= 100 / ((Diff_T1T2_bullet_Up + Diff_T1T2_bullet_Down) / 2);

    //   Serial.print("Time1Up = ");
    //   Serial.println(Time1Up);
    //   Serial.print("Time1Down = ");
    //   Serial.println(Time1Down);

    //   Serial.print("Time2Up = ");
    //   Serial.println(Time2Up);
    //   Serial.print("Time2Down = ");
    //   Serial.println(Time2Down);

    //сброс всех переменных в 0
        Time1Up = 0;      //Время срабатывания первого датчика передний фронт
        Time1Down = 0;    //Время срабатывания первого датчика задний фронт
        Time2Up = 0;      //Время срабатывания второго датчика передний фронт
        Time2Down = 0;    //Время срабатывания второго датчика задний фронт
     flag = false;                                    //измерения проведены возможен старт следующих
  }

  if (true) {
    lcd.clear();

    lcd.setCursor(0, 0);
    lcd.print("Vav=  ");
    lcd.setCursor(4, 0);
    lcd.print(Start_speed_bullet);

    lcd.setCursor(10, 0);
    lcd.print("ERR=");
    lcd.setCursor(14, 0);
    lcd.print(Measurement_error);

    lcd.setCursor(0, 1);
    lcd.print("Vup=");
    lcd.setCursor(4, 1);
    lcd.print(Start_speed_bullet_Up);

    lcd.setCursor(10, 1);
    lcd.print("Vdw=");
    lcd.setCursor(14, 1);
    lcd.print(Start_speed_bullet_Down);

    lcd.setCursor(0, 2);
    lcd.print("Vs1=  ");
    lcd.setCursor(4, 2);
    lcd.print(Start_speed_bullet_sensor1);

    lcd.setCursor(10, 2);
    lcd.print("Vs2=");
    lcd.setCursor(14, 2);
    lcd.print(Start_speed_bullet_sensor2);
  
    lcd.setCursor(0, 3);
    lcd.print(T1_bullet);
    lcd.setCursor(4, 3);
    lcd.print(T2_bullet);

    lcd.setCursor(8, 3);
    lcd.print(Diff_T1T2_bullet_Up);
    lcd.setCursor(14, 3);
    lcd.print(Diff_T1T2_bullet_Down);

    flag_lcd = false;
    delay(500);
  }
}
//срабатывание первого датчика
void StartUp() {
  if (Time1Up == 0) {
    Time1Up = micros();
  }
  else {
    Time1Down = micros();
  }
}
//срабатывание второго датчика
void EndUp() {
  if (Time2Up == 0) {
    Time2Up = micros();
  }
  else {
    Time2Down = micros();
    flag = true;
  }
}