Using 2 ToF4M Units as a Timing Gate
-
Hello,
I am trying to use a pair of ToF4M Units through a PaHub, connected to the M5Stack Core2 with Arduino IDE, to create a timing gate but not quit getting the results I would like.
The included code snippet works fine/ish, however, the screen doesn't always display the speed when I pass my hand through the sensors (showing in the console readout), nor can I pass my hands through at speed. What am I missing or am I trying to push the units too far?
Thanks for any help.
#include <M5Core2.h>
#include <Wire.h>
#include "SparkFun_VL53L1X.h"
#include "Arduino.h"#define TCAADDR 0x70 // Address for TCA9548A
// Declare sensors
SFEVL53L1X sensors[2]; // Array for sensors// Line break configuration
int distanceThreshold = 1000; // Distance threshold for line break detection (adjusted for bicycles)
int timingBudget = 50; // Timing budget for better accuracy (reduced for high speed)// Timing configuration
float sensorDistance = 30.0; // Distance between sensors in mm (adjust based on calibration)
unsigned long startMicros = 0; // Timer start time in microseconds
unsigned long stopMicros = 0; // Timer stop time in microseconds
unsigned long lastResetTime = 0; // Last time the screen was reset
unsigned long resetDelay = 1000000; // Delay for resetting screen (1 second in microseconds)
unsigned long minTimeDifference = 100; // Minimum time difference to avoid division by zero// Global variables for trigger sequence tracking
bool sensor0Triggered = false;
bool sensor1Triggered = false;
unsigned long sensor0TriggerTime = 0;
unsigned long sensor1TriggerTime = 0;// Debouncing configuration
const int debounceDelay = 50; // Debounce delay in milliseconds
unsigned long lastTriggerTime[2] = {0, 0}; // Last trigger time for each sensorvoid tcaselect(uint8_t i) {
if (i > 5) return;
Wire.beginTransmission(TCAADDR);
Wire.write(1 << i);
Wire.endTransmission();
}void setup() {
M5.begin();
Serial.begin(115200);
Wire.begin();
M5.Lcd.fillScreen(TFT_BLACK);
M5.Lcd.setTextSize(2);
Serial.println("Initializing Sensors...");// Initialize sensors with timing budget
for (int i = 0; i < 2; i++) {
tcaselect(i);
if (sensors[i].begin() != 0) {
Serial.print("Sensor failed to initialize on port ");
Serial.println(i + 1);
} else {
Serial.print("Sensor initialized on port ");
Serial.println(i + 1);
sensors[i].setTimingBudgetInMs(timingBudget);
}
}// Set up the display
M5.Lcd.fillScreen(TFT_BLACK);
M5.Lcd.setTextSize(5);
M5.Lcd.setTextColor(TFT_WHITE);
M5.Lcd.setTextDatum(MC_DATUM); // Center the text
}void loop() {
M5.update();unsigned long currentMicros = micros(); // Current time in microseconds
// Monitor sensor[0]
tcaselect(0);
sensors[0].startRanging();
while (!sensors[0].checkForDataReady()) {
delay(10);
}
int distance0 = sensors[0].getDistance();
sensors[0].clearInterrupt();
sensors[0].stopRanging();// Check if sensor[0] is triggered with debouncing
if (distance0 > 0 && distance0 < distanceThreshold && currentMicros - lastTriggerTime[0] > debounceDelay * 1000) {
sensor0Triggered = true;
sensor0TriggerTime = currentMicros; // Record trigger time
Serial.println("Sensor 0 triggered"); // Debug output
lastTriggerTime[0] = currentMicros; // Update last trigger time
}// Monitor sensor[1]
tcaselect(1);
sensors[1].startRanging();
while (!sensors[1].checkForDataReady()) {
delay(10);
}
int distance1 = sensors[1].getDistance();
sensors[1].clearInterrupt();
sensors[1].stopRanging();// Check if sensor[1] is triggered with debouncing
if (distance1 > 0 && distance1 < distanceThreshold && currentMicros - lastTriggerTime[1] > debounceDelay * 1000) {
sensor1Triggered = true;
sensor1TriggerTime = currentMicros; // Record trigger time
Serial.println("Sensor 1 triggered"); // Debug output
lastTriggerTime[1] = currentMicros; // Update last trigger time
}// Validate trigger sequence and calculate speed
if (sensor0Triggered && sensor1Triggered && sensor1TriggerTime > sensor0TriggerTime) {
unsigned long timeDifference = sensor1TriggerTime - sensor0TriggerTime;
if (timeDifference > 0) {
float speedInMmPerMs = sensorDistance / timeDifference * 1000.0;
float speedInKph = speedInMmPerMs * 3.6; // Convert to km/h
M5.Lcd.fillScreen(TFT_BLACK);
M5.Lcd.drawString(String(speedInKph, 2) + " km/h", 160, 120); // Display speed with 2 decimal places
lastResetTime = currentMicros; // Record reset time
}
// Reset trigger sequence
sensor0Triggered = false;
sensor1Triggered = false;
}if (currentMicros - lastResetTime > resetDelay) {
M5.Lcd.fillScreen(TFT_BLACK);
startMicros = 0;
stopMicros = 0;
}delay(100);
}