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

Я создаю систему хронометража, в которой есть стартовый, разделенный и финишный лучи. Я использую стартовые ворота, которые опускаются, когда начинается гонка. когда он падает, он отключает 1-й датчик, начиная отсчитывать миллисекунды, которые я использую для расчета времени. Я использую ИК-датчики, которые дают мне 3 раза в миллисекундах, а затем я делаю расчет в Excel, который дает мне время разделения и финиша.

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

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

Ниже показан скетч, над которым я работаю.

//таймер
unsigned long start, reaction, push, elapsed; 


void setup()
{
  Serial.begin(115200);
  pinMode(2, INPUT); // запуск переключателя
  pinMode(3, INPUT); // раздельный датчик
  pinMode(4, INPUT); // финишный датчик
}


void loop(){
   
if (digitalRead(2) == LOW)
  {

    start = millis();
    
  }



  if (digitalRead(3) == HIGH)
  {

    reaction = millis();
 // delay(200); // для устранения дребезга
    
    
  }

     if (digitalRead(4)==HIGH)
      {

       push=millis();
       delay(500); // для устранения дребезга

    Serial.print(start);
    Serial.print(",");
    Serial.print(reaction);
    Serial.print(",");
    Serial.print(push);
    Serial.println();

  }

}

, 👍0

Обсуждение

Вы уверены, что это действительно портит выбор времени для следующего человека? Когда вы сбрасываете стартовые ворота, ваш код устанавливает «старт» на текущее время. Но когда вы фактически начинаете следующую гонку, ваш код перезаписывает start правильным значением. Пока вы сбрасываете ворота **после** срабатывания последнего датчика (который фактически распечатывает время), все в порядке, насколько я вижу., @Gerben

Итак, что происходит, если при тестировании (просто используя мою руку, чтобы разбить балки), если я делаю это быстро, мне кажется, что я получаю хороший результат. но если я поставлю датчик финиша далеко от разделения, он даст мне после расчетов число в первый раз, которое НАМНОГО больше, чем должно быть наоборот., @chris

Так, например, я получаю начальную милли 27083, разделенную на 28 657, окончательную из 29 214. Когда я делаю математику, чтобы получить m/s, оказывается, что 1,574 от начала до разделения и 0,557 от разделения до конца... ... Я не уверен, проблема ли это в моем коде или в моей математике?, @chris

Эти значения в миллисекундах не кажутся мне странными, если предположить, что машина ускоряется. Я думаю, что вы рассчитываете s/m, а не m/s. Вы должны разделить расстояние (которое, как я предполагаю, равно 1 м) на количество секунд (которое составляет 0,1574 и 0,557). Тогда вы получите в среднем 0,64 м/с на первом участке. И в среднем 1,8 м/с на втором участке., @Gerben


1 ответ


1

Время начала по умолчанию равно нулю, поэтому вы можете изменить его на:

if (digitalRead(2) == LOW && start == 0)
  {

    start = millis();
    
  }
,

Вы также можете объявить start как статический в цикле: `static long start = millis();`. Таким образом, он вызывается только в первый раз и запоминает переменную в остальной части цикла()., @Ananas_hoi

с изменением строки скетча на «if (digitalRead(2) == LOW && start == 0)» кажется, что первые миллисекунды всегда имеют то же значение, что и при первом срабатывании, но другие датчики записывают то, что выглядит правильные номера., @chris

* Я думаю, что нужна строка кода, чтобы 1-й датчик == LOW один раз и ничего не делал * - это то, что делает мое предложение. Если вы хотите, чтобы он «сбросил», вам нужно больше кода. Я не совсем уверен, какие у вас параметры. Как узнать, что вы начинаете новую гонку?, @Nick Gammon