<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Using 2 ToF4M Units as a Timing Gate]]></title><description><![CDATA[<p dir="auto">Hello,</p>
<p dir="auto">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.</p>
<p dir="auto">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?</p>
<p dir="auto">Thanks for any help.</p>
<p dir="auto">#include &lt;M5Core2.h&gt;<br />
#include &lt;Wire.h&gt;<br />
#include "SparkFun_VL53L1X.h"<br />
#include "Arduino.h"</p>
<p dir="auto">#define TCAADDR 0x70                                                      // Address for TCA9548A</p>
<p dir="auto">// Declare sensors<br />
SFEVL53L1X sensors[2];                                                    // Array for sensors</p>
<p dir="auto">// Line break configuration<br />
int distanceThreshold             = 1000;                                 // Distance threshold for line break detection (adjusted for bicycles)<br />
int timingBudget                  = 50;                                   // Timing budget for better accuracy (reduced for high speed)</p>
<p dir="auto">// Timing configuration<br />
float sensorDistance              = 30.0;                                 // Distance between sensors in mm (adjust based on calibration)<br />
unsigned long startMicros         = 0;                                    // Timer start time in microseconds<br />
unsigned long stopMicros          = 0;                                    // Timer stop time in microseconds<br />
unsigned long lastResetTime       = 0;                                    // Last time the screen was reset<br />
unsigned long resetDelay          = 1000000;                              // Delay for resetting screen (1 second in microseconds)<br />
unsigned long minTimeDifference   = 100;                                  // Minimum time difference to avoid division by zero</p>
<p dir="auto">// Global variables for trigger sequence tracking<br />
bool sensor0Triggered             = false;<br />
bool sensor1Triggered             = false;<br />
unsigned long sensor0TriggerTime  = 0;<br />
unsigned long sensor1TriggerTime  = 0;</p>
<p dir="auto">// Debouncing configuration<br />
const int debounceDelay = 50;                                             // Debounce delay in milliseconds<br />
unsigned long lastTriggerTime[2] = {0, 0};                                // Last trigger time for each sensor</p>
<p dir="auto">void tcaselect(uint8_t i) {<br />
if (i &gt; 5) return;<br />
Wire.beginTransmission(TCAADDR);<br />
Wire.write(1 &lt;&lt; i);<br />
Wire.endTransmission();<br />
}</p>
<p dir="auto">void setup() {<br />
M5.begin();<br />
Serial.begin(115200);<br />
Wire.begin();<br />
M5.Lcd.fillScreen(TFT_BLACK);<br />
M5.Lcd.setTextSize(2);<br />
Serial.println("Initializing Sensors...");</p>
<p dir="auto">// Initialize sensors with timing budget<br />
for (int i = 0; i &lt; 2; i++) {<br />
tcaselect(i);<br />
if (sensors[i].begin() != 0) {<br />
Serial.print("Sensor failed to initialize on port ");<br />
Serial.println(i + 1);<br />
} else {<br />
Serial.print("Sensor initialized on port ");<br />
Serial.println(i + 1);<br />
sensors[i].setTimingBudgetInMs(timingBudget);<br />
}<br />
}</p>
<p dir="auto">// Set up the display<br />
M5.Lcd.fillScreen(TFT_BLACK);<br />
M5.Lcd.setTextSize(5);<br />
M5.Lcd.setTextColor(TFT_WHITE);<br />
M5.Lcd.setTextDatum(MC_DATUM);                                          // Center the text<br />
}</p>
<p dir="auto">void loop() {<br />
M5.update();</p>
<p dir="auto">unsigned long currentMicros = micros();                                 // Current time in microseconds</p>
<p dir="auto">// Monitor sensor[0]<br />
tcaselect(0);<br />
sensors[0].startRanging();<br />
while (!sensors[0].checkForDataReady()) {<br />
delay(10);<br />
}<br />
int distance0 = sensors[0].getDistance();<br />
sensors[0].clearInterrupt();<br />
sensors[0].stopRanging();</p>
<p dir="auto">// Check if sensor[0] is triggered with debouncing<br />
if (distance0 &gt; 0 &amp;&amp; distance0 &lt; distanceThreshold &amp;&amp; currentMicros - lastTriggerTime[0] &gt; debounceDelay * 1000) {<br />
sensor0Triggered = true;<br />
sensor0TriggerTime = currentMicros;                                   // Record trigger time<br />
Serial.println("Sensor 0 triggered");                                 // Debug output<br />
lastTriggerTime[0] = currentMicros;                                   // Update last trigger time<br />
}</p>
<p dir="auto">// Monitor sensor[1]<br />
tcaselect(1);<br />
sensors[1].startRanging();<br />
while (!sensors[1].checkForDataReady()) {<br />
delay(10);<br />
}<br />
int distance1 = sensors[1].getDistance();<br />
sensors[1].clearInterrupt();<br />
sensors[1].stopRanging();</p>
<p dir="auto">// Check if sensor[1] is triggered with debouncing<br />
if (distance1 &gt; 0 &amp;&amp; distance1 &lt; distanceThreshold &amp;&amp; currentMicros - lastTriggerTime[1] &gt; debounceDelay * 1000) {<br />
sensor1Triggered = true;<br />
sensor1TriggerTime = currentMicros;                                   // Record trigger time<br />
Serial.println("Sensor 1 triggered");                                 // Debug output<br />
lastTriggerTime[1] = currentMicros;                                   // Update last trigger time<br />
}</p>
<p dir="auto">// Validate trigger sequence and calculate speed<br />
if (sensor0Triggered &amp;&amp; sensor1Triggered &amp;&amp; sensor1TriggerTime &gt; sensor0TriggerTime) {<br />
unsigned long timeDifference = sensor1TriggerTime - sensor0TriggerTime;<br />
if (timeDifference &gt; 0) {<br />
float speedInMmPerMs = sensorDistance / timeDifference * 1000.0;<br />
float speedInKph = speedInMmPerMs * 3.6;                            // Convert to km/h<br />
M5.Lcd.fillScreen(TFT_BLACK);<br />
M5.Lcd.drawString(String(speedInKph, 2) + " km/h", 160, 120);       // Display speed with 2 decimal places<br />
lastResetTime = currentMicros;                                      // Record reset time<br />
}<br />
// Reset trigger sequence<br />
sensor0Triggered = false;<br />
sensor1Triggered = false;<br />
}</p>
<p dir="auto">if (currentMicros - lastResetTime &gt; resetDelay) {<br />
M5.Lcd.fillScreen(TFT_BLACK);<br />
startMicros = 0;<br />
stopMicros = 0;<br />
}</p>
<p dir="auto">delay(100);<br />
}</p>
]]></description><link>https://community.m5stack.com/topic/6389/using-2-tof4m-units-as-a-timing-gate</link><generator>RSS for Node</generator><lastBuildDate>Wed, 29 Apr 2026 09:38:23 GMT</lastBuildDate><atom:link href="https://community.m5stack.com/topic/6389.rss" rel="self" type="application/rss+xml"/><pubDate>Sun, 28 Apr 2024 13:49:38 GMT</pubDate><ttl>60</ttl></channel></rss>