Arduino Playground is read-only starting December 31st, 2018. For more info please look at this Forum Post

Speed Gate with multiple conversions

Written for IDE version 1.5.7

Created by HazardsMind

This sketch is designed to measure the time in either microseconds or milliseconds, depending on the set resolution and calculate the speed based on the given factor and time. It can also use either interrupts or regular digital pins (2, 3) Sketch is using a default distance of 35.6 feet, please adjust accordingly.

//=======Scale Factors=============================
#define FPS_to_MPH 0.68182
#define FPS_to_MPS 0.3048
#define FPS_to_KPH 1.09728
#define FPS_to_KNOTS 0.5924
#define FPS_to_CPS 30.48

#define CPS_to_FPS 0.0328
#define CPS_to_KPH 0.036
#define CPS_to_KNOTS 0.0194
#define CPS_to_MPS 0.01
#define CPS_to_MPH 0.0223

#define KPH_to_CPS 27.7777
#define KPH_to_FPS 0.9113
#define KPH_to_KNOTS 0.5399
#define KPH_to_MPS 0.2777
#define KPH_to_MPH 0.6213

#define KNOTS_to_CPS 51.4444
#define KNOTS_to_FPS 1.6878
#define KNOTS_to_KPH 1.852
#define KNOTS_to_MPS 0.5144
#define KNOTS_to_MPH 1.1507

#define MPS_to_CPS 100.0
#define MPS_to_FPS 3.2808
#define MPS_to_KPH 3.6
#define MPS_to_KNOTS 1.9438
#define MPS_to_MPH 2.2369

#define MPH_to_CPS 44.704
#define MPH_to_FPS 1.4666
#define MPH_to_KPH 1.6093
#define MPH_to_KNOTS 0.8689
#define MPH_to_MPS 0.4470
//=================================================

#define DISTANCE 35.5625 // distance between the two sensors or gates in feet.
template<typename type> void Swap(type (&A), type (&B)) {
  type T = A;
  A = B;
  B = T;
}

#define Accuracy_Resolution LOW // Set accuracy resolution to use either interrupts(HIGH), or regular digital pins(LOW)
#define Time_Resolution HIGH // Set time resolution to use either micros(HIGH) or millis(LOW)

bool GotFirstSensor = false, GotSecondSensor = false;
unsigned long SensorOne_timer = 0, SensorTwo_timer = 0;
//================================================================================

#if (Accuracy_Resolution == LOW)
const byte firstGateSen = 2;
const bool FGS_state = HIGH;
const byte secondGateSen = 3;
const bool SGS_state = HIGH;
#endif

void setup()
{
  Serial.begin(115200);
#if (Accuracy_Resolution == HIGH)
  attachInterrupt(0, SensorOneState, RISING);
  attachInterrupt(1, SensorTwoState, RISING);
#else
  pinMode(firstGateSen, INPUT);
  pinMode(secondGateSen, INPUT);
#endif
}

void loop()
{
  static float Speed;
  // This is using normal buttons to detect car passing through one gate to another,
  // this can be changed to use US sensors to replace the buttons. That part you will
  // need to write yourself.
#if(Accuracy_Resolution == LOW)
  if ((digitalRead(firstGateSen) == FGS_state) && GotSecondSensor == false)
    SensorOneState();

  if ((digitalRead(secondGateSen) == SGS_state) && GotFirstSensor == false)
    SensorTwoState();
#endif

  if (GotFirstSensor & GotSecondSensor) //both must be true for this condition to be true
  {
    Speed = GetSpeed(SensorOne_timer, SensorTwo_timer, DISTANCE, FPS_to_MPH ); // send the times and the distance into the function.
    Serial.print("MPH: ");
    Serial.println(Speed);
    ClearStates();
  }
}

void SensorOneState()
{
#if(Time_Resolution == HIGH)
  SensorOne_timer = micros(); //record the time the car reaches the first gate
#else
  SensorOne_timer = millis();
#endif
  GotFirstSensor = true;
}

void SensorTwoState()
{
#if(Time_Resolution == HIGH)
  SensorTwo_timer = micros(); //record the time the car reaches the second gate
#else
  SensorTwo_timer = millis();
#endif
  GotSecondSensor = true;
}

void ClearStates()
{
  GotFirstSensor = false;
  GotSecondSensor = false;
}

float GetSpeed(unsigned long T1, unsigned long T2, float Distance, float Factor)
{
  static float CF;
  static long tmp;

  CF = Distance * Factor; // "(FPS_to_MPH)" -> conversion factor, feet per second to miles per hour
  if (T1 > T2)
    Swap(T1, T2);

  tmp = (T2 - T1);
#if(Time_Resolution == HIGH)
  tmp /= 1000000.00; // since the time we are using is in microseconds, we need to convert microseconds to seconds
#else
  tmp /= 1000.00; // since the time we are using is in milliseconds, we need to convert milliseconds to seconds
#endif
  Serial.print("Time (seconds): ");
  Serial.println(tmp);
  return (CF / tmp); //return the speed of the car in MPH
}