Хватит ли мощности железа для точного измерения времени?

Viblis
Offline
Зарегистрирован: 04.11.2016

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

В общем то все просто. если бы не точность измерения времени.  Диапазон измеряемых величин от 100 до 500 миллисекунд, необходимая точность 100 микросекунд. (Средние получаемые результаты 155 миллисекунд, 156 миллисекунд, 170 миллисекунд и т.д.). Также осложнение в том, что кнопок четыре, т.е. опрашивать нужно 4-ре ноги и фиксировать данные срабатывания каждой.

Соответственно вопросы: 

Хватит ли ардуиновской частоты 16 МГц  на необходимое разрешение при вычислении времени ?

Какова точность встроеного ардуиновского тактового генератора (насколько я понимаю, температурной стабилизации там нет) или нужно делать выносной ?

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

С какими проблемами тут еще можно столкнуться или я зря беспокоюсь и все значительно проще ?

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

 

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

Viblis,  для результата точностью +/- 100µS  вам вообще не  о чем волноваться, тем более о температурной стабилизации.  Всё остальное зависит от того, как Вы напишите программу.

b707
Offline
Зарегистрирован: 26.05.2017

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

Viblis
Offline
Зарегистрирован: 04.11.2016

b707 пишет:

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

Код наверное нужно писать на аcсемблере ?

sadman41
Offline
Зарегистрирован: 19.10.2016

Viblis пишет:

Код наверное нужно писать на аcсемблере ?

Чтобы подружится с местными - только на ассемблере. А если такой цели нет, то можно и на нечестном Си. 

DetSimen
DetSimen аватар
Offline
Зарегистрирован: 25.01.2017

Viblis пишет:

b707 пишет:

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

Код наверное нужно писать на аcсемблере ?

если из портов напрямую читать, можно и на С.  если через богомерзкий digitalRead(), то кварц перепаять на 200 МГц. 

Viblis
Offline
Зарегистрирован: 04.11.2016

DetSimen пишет:

то кварц перепаять на 200 МГц. 

 

Достаточно просто перепаять кварц на плате и ардуинка заработает на 200 Мгц ? К примеру китайская UNO то же заработает ?

Или же может вообще DUO выбрать на 84Мгц ?

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

Viblis пишет:

Код наверное нужно писать на аcсемблере ?

Код нужно писать на том, на чём Вы умеете писать (если Вы, конечно не профи, которому всё равно чём писать).

b707
Offline
Зарегистрирован: 26.05.2017

Viblis пишет:

DetSimen пишет:

то кварц перепаять на 200 МГц.

Достаточно просто перепаять кварц на плате и ардуинка заработает на 200 Мгц ? К примеру китайская UNO то же заработает ?

Или же может вообще DUO выбрать на 84Мгц ?

вы вообще шуток не понимаете? нафига там 200 МГц?

Ваша задачка - детского уровня, с ней легко справится ардуина на 2-4 МГц. не токмо 16.

Ассемблер не обязателен, можно и Си быстрый код написать.

 

 

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

Viblis пишет:

К примеру китайская UNO то же заработает ?

Только если кварц возьмёте китайский. А если кварц оригинальный, то и Uno оригинальная нужна.

Гриша
Offline
Зарегистрирован: 27.04.2014
mobistrike
mobistrike аватар
Offline
Зарегистрирован: 19.08.2016

TC, поищите , на форуме есть тема про хронометр , измеритель скорости пули. 

Viblis
Offline
Зарегистрирован: 04.11.2016

mobistrike пишет:

TC, поищите , на форуме есть тема про хронометр , измеритель скорости пули. 

Спасибо, таких тем на форуме несколько, там ответы на все вопросы.

Viblis
Offline
Зарегистрирован: 04.11.2016

Почему считает с большим разбросом?

Провожу вот такой эксперемент.

Беру первую плату ардуино UNO Ее задача генерировать импульсы между которыми будет 150 миллисекунд. Для этого пишу простенкий скетч:

void setup()
{
  pinMode(8, OUTPUT);
  pinMode(9, OUTPUT);
  digitalWrite(8, LOW);
  digitalWrite(9, LOW);
  Serial.begin (9600);
}

void loop() {
  unsigned long start = millis(); //переменные для счетчика времени
  unsigned long stoped = millis();

  digitalWrite(8, HIGH);
  while (stoped - start < 150) //цикл по времени
  {
    stoped = millis();
  }
  digitalWrite(9, HIGH);
  digitalWrite(8, LOW);
  digitalWrite(9, LOW);
}

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

unsigned long timeD = 0;
unsigned long time1 = 0;
void setup()
{
  Serial.begin (9600);
}

void loop() {
  pulseIn(2, HIGH, 10000000); //ждем сработку датчика в течении 10 сек
  time1 = millis(); // засекли время сработки
  pulseIn(3, HIGH, 3000000); //ждем сработку кнопки в течении 3 сек
  timeD = millis() - time1; //считаем сколько времени прошло
  Serial.println(timeD);
  timeD = 0;
  time1 = 0;
}

Соединяю платы между собой. Подключаю монитор порта ко второй плате. Разброс  милисекунд в мониторе от 148 до 151 милисекунды.

Это очень маленькая точность. Мне же в создаваемом приборе нужна точность минимум 100 мксекунд.

Что делать, не пользоваться встроеными функциями и начинать изучать ассемблер или может попробовать осуществить подсчет на прерываниях?

 

 

 
b707
Offline
Зарегистрирован: 26.05.2017

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

Viblis
Offline
Зарегистрирован: 04.11.2016

Если бы было к примеру постоянно 148 или 151 это было бы вполне нормально, это можно откалибровать, хуже то, что цифры скачут от 148 до 151, т.е. частота непостоянна и на нее нельзя опираться при вычислении

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

Сколько времени у Вас прохожит между digitalWrite(8, LOW); и digitalWrite(8, HIGH);? На приёмнике всё успевает сработать? Не хотите там delay поставить и с ним попробовать?

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

Да уж, это не доли микросекунд ловить )))

Да, и строка 12 первого скетча должна выглядеть так

  unsigned long stoped = start;

 

b707
Offline
Зарегистрирован: 26.05.2017

ЕвгенийП пишет:

Сколько времени у Вас прохожит между digitalWrite(8, LOW); и digitalWrite(8, HIGH);? На приёмнике всё успевает сработать? Не хотите там delay поставить и с ним попробовать?

Евгений, мне кажется дело не в этом.  Все проще. Автор пользуется millis() - инструментом с точностью в 1мс. Измерений два -  первом измерении ошибка +/- 1мс, и так же при втором. Потом эти два значения вычитаются одно из другого - и точно в соответсвии с теорией измерений ошибка получается +/- 2мс

Чтобы иметь точность в 0.1мс, нужно мерить время не хуже +/- 50мкс. Как вариант - использовать micros

Viblis
Offline
Зарегистрирован: 04.11.2016

b707 пишет:

Чтобы иметь точность в 0.1мс, нужно мерить время не хуже +/- 50мкс. Как вариант - использовать micros

Спасибо за идею. Стало значительно точнее.