I've been successful in creating a laser gate timer for my bike pumptrack. However, it doesn't work all of the time and I'm wondering if my sensors just are not capable of what I need them to do. At low speeds it seems to work fine, but when I break the laser very quickly, it does not register that there has been a beam break. Is there anyway to adjust the accuracy of the laser gate in the code or maybe just an upgrade in electronics. If an upgrade is needed, what would you recommend? I built this with little experience and lots of youtube.
I'm using an amazon a Laser Sensor Module Non-Modulator Tube Laser Receiver Module with a KY-008 650nm Laser Transmitter Module
I've tried removing sunlight from the equation. I've got the sensor in blackout box with just a hole to allow the laser light to enter and make contact with the sensor. I did notice that I was having issues with accuracy even more when the laser and sensor where about 5-6 feet apart. I've shorted the distance to about 3.5 feet. I can't really go shorter distance than that, or I risk running over the whole thing with my bike tire. I also made sure to have the gate just 1-2 inches off the ground, so that the tire and wheel break the beam, and not just the spokes on the wheel.
Here is my code
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27, 20, 4);
// laps info
unsigned long currentRunStartMillis;
unsigned long lastRunInMillis;
unsigned long bestRunInMillis;
int currentLap;
unsigned long savedMillis;
unsigned long lockoutUntilMillis = 0; // New variable to manage lockout period
int sec_val, milli_val; // variables to show the time on the display in seconds and milliseconds
// laser gate
const int gateSensorPin = A0; // the number of the gate sensor pin
int gateSensorState; // the current reading from the sensor
int lastgateSensorState = LOW; // the previous reading from the sensor
unsigned long lastDebounceTime = 0; // the last time the sensor pin was toggled
int debounceDelay = 50; // the debounce time; increase if the output flickers
const unsigned long lockoutDuration = 500; // Lockout duration in milliseconds
void setup() {
pinMode(gateSensorPin, INPUT);
delay(50); // allow the sensor and laser to stabilize
lcd.init(); // initialize the lcd
lcd.backlight(); // turn on the LCD screen backlight
lcd.setCursor(0, 0);
lcd.print("Pumptrack");
lcd.setCursor(0, 1);
lcd.print("Laser Lap Timer ");
lcd.setCursor(0, 2);
lcd.print("1.0");
lcd.setCursor(0, 3);
lcd.print("Let's Ride");
delay(5000);
lcd.clear();
// Print initial text on LCD screen
lcd.setCursor(0, 0);
lcd.print("Lap ");
lcd.setCursor(0, 1);
lcd.print("Current Lap ");
lcd.setCursor(0, 2);
lcd.print("Last Lap ");
lcd.setCursor(0, 3);
lcd.print("Best Lap ");
delay(1500);
// reset parameters
currentRunStartMillis = 0;
lastRunInMillis = 0;
bestRunInMillis = 0;
currentLap = 0;
}
void loop() {
int reading = digitalRead(gateSensorPin);
if (reading != lastgateSensorState) {
lastDebounceTime = millis();
}
if ((millis() - lastDebounceTime) > debounceDelay) {
if (reading != gateSensorState) {
gateSensorState = reading;
// Only process if not in lockout period
if (gateSensorState == LOW && millis() > lockoutUntilMillis) {
savedMillis = millis();
if (currentLap > 0) {
lastRunInMillis = savedMillis - currentRunStartMillis;
if (lastRunInMillis < bestRunInMillis || bestRunInMillis == 0) {
bestRunInMillis = lastRunInMillis;
}
}
currentRunStartMillis = savedMillis;
currentLap++;
// Set lockout until after the specified duration
lockoutUntilMillis = millis() + lockoutDuration;
}
}
}
lastgateSensorState = reading;
// print laps
lcd.setCursor(4, 0);
lcd.print(currentLap);
// save current millis
savedMillis = millis();
// if we start the first lap
if (currentLap > 0) {
calcResultFromMillis(savedMillis - currentRunStartMillis, &sec_val, &milli_val);
} else {
calcResultFromMillis(0, &sec_val, &milli_val);
}
// Update the display with lap times
// Current Lap Time
lcd.setCursor(12, 1);
lcd.print(sec_val);
lcd.print(":");
lcd.print(milli_val);
// Last Lap Time
calcResultFromMillis(lastRunInMillis, &sec_val, &milli_val);
lcd.setCursor(9, 2);
lcd.print(sec_val);
lcd.print(":");
lcd.print(milli_val);
// Best Lap Time
calcResultFromMillis(bestRunInMillis, &sec_val, &milli_val);
lcd.setCursor(9, 3);
lcd.print(sec_val);
lcd.print(":");
lcd.print(milli_val);
}
// calculate millis into 2 values, seconds and millis for display
void calcResultFromMillis(unsigned long value, int *sec_val, int *milli_val) {
*sec_val = int(value / 1000);
*milli_val = value - *sec_val * 1000;
}
13 posts - 4 participants