Measure speed using two JSN-SR04T Ultrasonic Sensors

Hello, this is my first post!

I need help optimizing the code for measuring car speed using two jsn-sr04t ultrasonic sensors. The sensors are placed in the fence along the road outside my house and are 437 cm apart. It's supposed to detect a car in the first sensor (based on the distance measured from the sensor) and measure the time until it is detected on the same basis as the second sensor. Most of the time the car will enter/leave each sensor independently, but longer cars/buses will be detected by both at the same time. The code I have now will not be able to separate the cars if they are very close (car 2 enters sensor 1 before car 1 leaves sensor 2). I have the following code that seems to work (<1% measurements seem to be wrong/unreasonable high speed).
I'm seeking input on the code, with the hope that someone could help identify any overlooked mistakes or provide suggestions for improving the detection of passing cars and optimizing the overall code.

Attached is my code (post edited with complete code):

//Define variables
unsigned long startTime = 0;
unsigned long endTime = 0;
long distance = 0;
bool carDetected = false;
bool resetSensor1 = true;
bool resetSensor2 = true;

//Define array for storage: 
const int maxEntries = 2000;
unsigned long timeDiff[maxEntries];
int currentIndex = 0;

//Define sensor pinout:
const int sensorPin1 = 14;
const int echoPin1 = 12;
const int sensorPin2 = 4;
const int echoPin2 = 5;

void setup() {
  //Define pinModes:
  pinMode(sensorPin1, OUTPUT);
  pinMode(echoPin1, INPUT);
  pinMode(sensorPin2, OUTPUT);
  pinMode(echoPin2, INPUT);

  //make sure sensorpins is low
  digitalWrite(sensorPin1, LOW);
  digitalWrite(sensorPin2, LOW);
}

void loop() {
  if (!carDetected) {                                          // Start reading sensor 1 if there is no car detected              
    readSensor(sensorPin1, echoPin1);                          // Call the readSensorfunction and read sensor 1 
    if (distance < 380 && distance >220 && resetSensor1) {     // Check if measurement fits with passing car (min, maks distance and if sensor is reset)
      startTime = millis();                                    // Start the timer for the passing car. 
      carDetected = true;                                      // Change the boolean for car detection to true. 
      resetSensor1 = false;                                    // The sensor is now "used" and needs to be reset by a 0 measurement indicating that the current car has left the field. 
    } else if (distance == 0) {                                // If the sensor returns 0 (pulseIn timout), the sensor should be reset
      resetSensor1 = true;
    }
  }
  
  if (carDetected || !resetSensor2) {                          // If car is deteced on sensor 1, detect car on sensor 2.
    readSensor(sensorPin2, echoPin2);                          // Call the readSensorfunction and read sensor 1 
    if (distance < 380 && distance >220 && resetSensor2) {     // Check if measurement fits with passing car (min, maks distance and if sensor is reset)
      endTime = millis();                                      // Start the timer for the passing car.
      if (100 < millis() - startTime) {                        // Check if the passing time is less than 100ms, unrealistic high speed - probably error.
        timeDiff[currentIndex] = (endTime-startTime);          // Store the cars time passing both sensors in ms
        currentIndex = (currentIndex + 1) % maxEntries;        // Increment the array 
      }
      carDetected = false;                                     // Car has now clocked in at 1 & second sensor and we can reset the detection boolean. 
      resetSensor2 = false;                                    // 2 sensor is now "used" and needs to be reset by a 0 measurement indicating that the current car has left the field. 
    } else if (distance == 0 ) {                               // This handles the reset.
      resetSensor2 = true;
    }
    
    if (millis() - startTime > 2000) {                         // If sensor 1 detects a car that somehow never triggers the second sensor within 2 seconds - restart. 
      carDetected = false;
    }     
  }
}

//Function that reads sensor 1
void readSensor(int trigger, int echo) {                        // Function
  digitalWrite(trigger, HIGH);                                  // Trigger jsn-sr04t #1
  delayMicroseconds(20);                                        // Trigger jsn-sr04t #2
  digitalWrite(trigger, LOW);                                   // Trigger jsn-sr04t #3
  long timeElapsed = pulseIn(echo, HIGH, 40000);                // Measure time for echo - timeout set according to expected distance to cars (speeds up measurements)
  distance = timeElapsed * 0.0343 / 2;                          // Calculate distance in centimeters
  delay(1);                                                     // Small delay to prevent faulty readings (will give intermittent 0 readings if no delay)
}

Illustration of setup:

Post complete code.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.