Hello!
This is my first Arduino project, and my first post on this forum. I'm having a lot of fun learning about Arduino and happy with the progress I've made on my own, but I'm at a place where I think I need help. I would welcome feedback on how to make my question more clear to this group, if needed!
Project Overview:
I'm attempting to create a Laser Lap Timer to use outdoors for a dirtbike event my friends have set for later in the summer. The timer should record:
- Current Lap Time
- Current Lap number
- Last Lap
- Best Lap
The Hardware being used:
- Mega2560
- ISO103 Receivers
- HiLetgo 3.5" TFT LCD Display ILI9486/ILI9488 480x320 36 Pins for Arduino Mega2560
- connection wires
The Library that I'm using for the TFT display is:
Because I'm still learning about how to make things with Arduino, the project lives as a mashup between two existing projects. I took the example project from the TFT_HX8357 library (TFT_Print_Test) and inserted what I believed to be the important portions of code from this Laser Lap Timer project that I found on Gadgetronicx >> [Lap timer for slot cars using Laser and Arduino] Note: because I'm a new user, I'm only allowed to post two links, so I'm unable to link the project here. However it is the first thing that comes up when doing a Google Search for the words in BOLD.
The current state of the project seems to be working, which is very exciting for me! But I'm having two issues:
- The entire screen refreshes at the rate assigned in the delay portion at the end of the code. It's very abrasive to look at. I'm currently unable to figure out how to only update the portion of the screen that displays lap times, when necessary.
- I'm struggling to get the times to display in Minute:Second:Millisecond. It appears to just be displaying in Millisecond only.
The code that I've hobbled together is posted below. I'm sure that there may be a more efficient way to achieve what I'm looking for and would welcome feedback on that as well. Currently, as stated before, it's kind of a mish-mash between two existing projects that I've found.
#include <TFT_HX8357.h> // Hardware-specific library
TFT_HX8357 tft = TFT_HX8357(); // Invoke custom library
#define TFT_GREY 0x5AEB // New colour
// laps info
unsigned long currentRunStartMillis;
unsigned long lastRunInMillis;
unsigned long bestRunInMillis;
int currentLap;
unsigned long savedMillis;
// global for display
int sec_val, milli_val;
// laser gate
const int gateSensorPin = 2; // the number of the gate sensor pin
int gateSensorState; // the current reading from the sensor
int lastgateSensorState = LOW; // the previous reading from sensor
unsigned long lastDebounceTime = 0; // the last time the sensor pin was toggled
int debounceDelay = 50; // the debounce time; increase if the output flickers
void setup(void) {
tft.init();
tft.setRotation(3);
// pin mode
pinMode(gateSensorPin, INPUT);
delay(1); // to late the sensor and laser work, so we wont get the lap triggered.
// reset params
currentRunStartMillis = 0;
lastRunInMillis = 0;
bestRunInMillis = 0;
currentLap = 0;
}
void loop() {
// read the state of the laser sensor:
int reading = digitalRead(gateSensorPin);
// If the switch changed, due to noise or pressing:
if (reading != lastgateSensorState) {
// reset the debouncing timer
lastDebounceTime = millis();
} //end if
// if passes the debounce time
if ((millis() - lastDebounceTime) > debounceDelay) {
if (reading != gateSensorState) {
gateSensorState = reading;
// If we went low, this mean the beam was broken
if (gateSensorState == LOW) {
// save the millis so all the math on it will be done with the same value.
savedMillis = millis();
// if its not the first lap
if (currentLap > 0) {
// save the last run
lastRunInMillis = savedMillis - currentRunStartMillis;
// if last run is faster then best run
if (lastRunInMillis < bestRunInMillis || bestRunInMillis == 0) {
//save as best
bestRunInMillis = lastRunInMillis;
} //end if
} //end if
//reset the current
currentRunStartMillis = savedMillis;
// move lap counter
currentLap++;
} //end if
} //end if
} //end if
// save the reading. Next time through the loop, it'll be the lastgateSensorState:
lastgateSensorState = reading;
// Fill screen with random colour so we can see the effect of printing with and without
// a background colour defined
tft.fillScreen(TFT_RED);
// Set "cursor" at top left corner of display (0,0) and select font 2
// (cursor will move to next line automatically during printing with 'tft.println'
// or stay on the line is there is room for the text with tft.print)
tft.setCursor(20, 0, 2);
// Set the font colour to be white with a black background, set text size multiplier to 1
tft.setTextColor(TFT_BLUE); tft.setTextSize(3);
// We can now plot text on screen using the "print" class
tft.println("CURRENT LAP");
tft.setCursor(50, 40, 2);
// Set the font colour to be white with a black background, set text size multiplier to 1
tft.setTextColor(TFT_BLUE); tft.setTextSize(5);
// We can now plot text on screen using the "print" class
tft.println(long(currentRunStartMillis));
tft.setCursor(20, 110, 2);
// Set the font colour to be white with a black background, set text size multiplier to 1
tft.setTextColor(TFT_BLUE); tft.setTextSize(3);
// We can now plot text on screen using the "print" class
tft.println("LAST");
tft.setCursor(50, 150, 2);
// Set the font colour to be white with a black background, set text size multiplier to 1
tft.setTextColor(TFT_BLUE); tft.setTextSize(5);
// We can now plot text on screen using the "print" class
tft.println(long(lastRunInMillis));
tft.setCursor(20, 240, 2);
// Set the font colour to be white with a black background, set text size multiplier to 1
tft.setTextColor(TFT_GREEN); tft.setTextSize(4);
// We can now plot text on screen using the "print" class
tft.println("BEST");
tft.setCursor(160, 230, 2);
// Set the font colour to be white with a black background, set text size multiplier to 1
tft.setTextColor(TFT_BLUE); tft.setTextSize(5);
// We can now plot text on screen using the "print" class
tft.println(long(bestRunInMillis)),sec_val, milli_val;
delay(0);
}
// calculate millis into 2 values, seconeds 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;
}