Измерение времени соударения металлических шаров

lev39
Offline
Зарегистрирован: 14.08.2012

Спасибо за совет. Обязательно проверю.

leshak
Offline
Зарегистрирован: 29.09.2011

maksim пишет:

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

Проблема "нет гарантии" - действительно имеет место быть. Но вот решение ее "перенос расчетов на дуину" - IMHO не очень хорош. Все-таки расчет лучше делать на стороне компа. А проблему решить путем посылки, вместе с данными, временной метки когда данные были прочитаны с датчика.

Это даст следующие плюсы: 

  • Не будет загружать саму дуину (все-таки у нее главная задача как можно четче регистрировать сами события)
  • Делать "расчеты" позднее. То есть на стороне компа сохранять лог, а потом "воспроизводить его", делать повторные перерасчеты и т.п. 
  • Как результат предыдущего пункта появится возможность использовать для обработки данных не только процессинг, но и Excel (с его статистиками, графиками и т.п.), Matlab  и проч.
  • Давать "лабораторные" сразу нескольким людям. То есть "собрали данные", а потом "каждый пытается их обработать "кто как умеет".
  • Разрабатывать-тестировать логику расчета намного проще на "данных из файла", чем в живую каждый раз что-то делая с оборудованием и на каждом прогоне имея "чуть-чуть другие данные".

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

leshak
Offline
Зарегистрирован: 29.09.2011

2lev39: Вообщем ваш изначальный подход "считать производные на процессинге" - очень здравый. Для его реализации нужно только, кроме отсылки показаний самого analogRead(), посылать еще значение функции millis(). 

P.S. И стоило, все-таки, как рекомендовал Максим, завести под второе устройство еще одну тему. А тут, раз изначально про него заговорили в этой ветке, можно дать ссылку на новую тему.  Что-бы не мешать все это с "соударением шаров".

lev39
Offline
Зарегистрирован: 14.08.2012

Да проблема становится все интереснее.

Заведу новую ветку "Измерение пути, скорости и ускорения тела с помощью Ардуино".

lev39
Offline
Зарегистрирован: 14.08.2012

Готово. Новая тема создана. Давайте общаться там.

leshak
Offline
Зарегистрирован: 29.09.2011

 Ну а ссылочку на новую тему? Может-же "утонуть в форуме" ;)

Вообщем вот новая тема: Измерение координаты, скорости и ускорения тела

AlexFisher
AlexFisher аватар
Offline
Зарегистрирован: 20.12.2011

У Вас неправильный подход к измерению малых интервалов времени! функция digitalRead() весьма медленная, почитайте статью про ускорение некоторых функций ардуино! Луше было бы использовать внешние прерывания (их как раз 2).

Простой тест скорости этой программы

#define Pin1 2
#define Pin2 3

unsigned long micros_start, time = 0;
volatile char button;

void setup() {
  Serial.begin(9600);
  digitalWrite(Pin1, 1);
  digitalWrite(Pin2, 1);   
  Serial.println("Distance: 1 m");
  
  button=digitalRead(Pin1);
  while(button!=digitalRead(Pin1));
  button=digitalRead(Pin1);
  micros_start = micros();
  button=digitalRead(Pin2);
  while(button!=digitalRead(Pin2));
  time = micros() - micros_start;
  unsigned long speed = 1000000.0/time;
  
  Serial.print("Time: ");
  Serial.print(time, DEC);
  Serial.println(" mcs");  
  Serial.print("Speed: ");
  Serial.print(speed, DEC);
  Serial.println(" m/c");
  Serial.println();
}

void loop() {
}

 

дает 12 мкс - их нужно вычитать из результата

Добавил переменную, чтобы компилятор чего не выбросил при оптимизации, без нее было 8 мкс.

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

 Да, деиствительно, вы правы, нужно еще при расчете вычесть 8, но лучше 7, что бы не получилось деления на 0. 

#define Pin1 2
#define Pin2 3

unsigned long micros_start, time = 0;

void setup() {
  Serial.begin(9600);
  digitalWrite(Pin1, 1);
  digitalWrite(Pin2, 1);   
  Serial.println("Distance: 1 m");
  
  while(digitalRead(Pin1));
  micros_start = micros();
  while(!digitalRead(Pin2));
  time = micros() - micros_start - 7;
  unsigned long speed = 1000000.0/time;
  
  Serial.print("Time: ");
  Serial.print(time, DEC);
  Serial.println(" mcs");  
  Serial.print("Speed: ");
  Serial.print(speed, DEC);
  Serial.println(" m/c");
  Serial.println();
}

void loop() {
}

 

 

leshak
Offline
Зарегистрирован: 29.09.2011

 

AlexFisher пишет:

Луше было бы использовать внешние прерывания (их как раз 2).

В сообщении #31 я дал реализацию на внешних прерваниях. Но, почемуто, "в работу" эта версия не пошла :(.