Cronómetro para Slot Car Activado por Láser con Pantalla GLCD – Cronometraje Preciso para Pistas RC
Componentes y materiales
| Arduino Mega 2560 | 1 |
| Láser KY 008 | 1 |
Aplicaciones y servicios en línea
- Arduino IDE
Sobre este proyecto
Introducción
Compré un par de módulo láser KY008 y un sensor a juego, y supe que tenía que hacer algún proyecto chulo con él. Así que tomé el par y creé una puerta de cronometraje eléctrico para la pista de slot car que ya estaba en la mesa para mi proyecto de slot car autónomo.
El Hardware
Los 3 componentes principales son el módulo láser, el sensor receptor láser y la pantalla GLCD.
Realmente me encanta usar GLCD, puedes encontrar info sobre el pinout aquí: https://playground.arduino.cc/Code/GLCDks0108/
Y puedes descargar la librería desde aquí:
https://bitbucket.org/bperrybap/openglcd
Creé un conector agradable y fácil para él, como se muestra en la imagen de abajo.
El módulo láser KY008 tiene 3 pines, -, + y S, solo uní tanto el S como el + al 5V. Si no quieres que el láser esté encendido todo el tiempo, conecta el pin S a un pin digital en el Arduino. Cuando lo pongas en alto, el láser se encenderá.
El sensor tiene 3 pines también, GND, VCC y SIGNAL. Conecta a alimentación y el pin de entrada en el Arduino.
El desafío más difícil en esta construcción fue conseguir que todo estuviera alineado.
Puedes ver el resultado final en este clip.
Código
Archivo sin título (Arduino)
/*
* Puerta digital de cronometraje
* Código por: Tal Ofer
* talofer99@hotmail.com
*/
#include "openGLCD.h"
// info de vueltas
unsigned long currentRunStartMillis;
unsigned long lastRunInMillis;
unsigned long bestRunInMillis;
int currentLap;
unsigned long savedMillis;
gText t1; // definirá área de texto en runtime
gText t2; // definirá área de texto en runtime
gText t3; // definirá área de texto en runtime
// globales para display
int sec_val, milli_val;
// puerta láser
const int gateSensorPin = 2; // el número del pin del sensor de puerta
int gateSensorState; // la lectura actual del sensor
int lastgateSensorState = LOW; // la lectura previa del sensor
unsigned long lastDebounceTime = 0; // la última vez que el pin del sensor cambió
int debounceDelay = 50; // el tiempo de anti-rebote; aumentar si la salida parpadea
void setup() {
// modo pin
pinMode(gateSensorPin, INPUT);
delay(50); // para que el sensor y láser funcionen, así no obtendremos la vuelta activada.
// iniciar GLCD
GLCD.Init(NON_INVERTED);
// definir áreas
t1.DefineArea(textAreaTOP, lcdnums14x24);
t2.DefineArea(0, GLCD.CenterY, 8, 2, fixednums7x15);
t3.DefineArea(GLCD.CenterX, GLCD.CenterY, 8, 2, fixednums7x15);
t3.SetFontColor(WHITE); // color de fuente
t3.ClearArea();
// imprimir texto
GLCD.SelectFont(System5x7);
GLCD.CursorTo(1, 4);
GLCD.print("LAST");
GLCD.CursorTo(11, 4);
GLCD.print("BEST");
// resetear parámetros
currentRunStartMillis = 0;
lastRunInMillis = 0;
bestRunInMillis = 0;
currentLap = 0;
}
void loop() {
// leer el estado del sensor láser:
int reading = digitalRead(gateSensorPin);
// Si el interruptor cambió, debido a ruido o pulsación:
if (reading != lastgateSensorState) {
// resetear el temporizador de anti-rebote
lastDebounceTime = millis();
} // fin if
// si pasa el tiempo de anti-rebote
if ((millis() - lastDebounceTime) > debounceDelay) {
if (reading != gateSensorState) {
gateSensorState = reading;
// Si fuimos a LOW, esto significa que el haz se rompió
if (gateSensorState == LOW) {
// guardar los millis para que todas las matemáticas se hagan con el mismo valor.
savedMillis = millis();
// si no es la primera vuelta
if (currentLap > 0) {
// guardar la última vuelta
lastRunInMillis = savedMillis - currentRunStartMillis;
// si la última vuelta es más rápida que la mejor
if (lastRunInMillis < bestRunInMillis || bestRunInMillis == 0) {
// guardar como mejor
bestRunInMillis = lastRunInMillis;
} // fin if
} // fin if
// resetear la actual
currentRunStartMillis = savedMillis;
// mover contador de vueltas
currentLap++;
} // fin if
} // fin if
} // fin if
// guardar la lectura. La próxima vez en el bucle, será lastgateSensorState:
lastgateSensorState = reading;
// imprimir Vueltas
t1.CursorTo(0, 0); // establecer en ubicación
t1.Printf(F("%02d"), currentLap);
// guardar millis actuales
savedMillis = millis();
// si empezamos la primera vuelta
if (currentLap > 0) {
calcResultFromMillis(savedMillis - currentRunStartMillis, &sec_val, &milli_val);
} else {
calcResultFromMillis(0, &sec_val, &milli_val);
} // fin if
// VUELTA ACTUAL
t1.CursorTo(3, 0); // columna y fila relativas al área de texto
t1.Printf(F("%02d.%03d"), sec_val, milli_val);
// ÚLTIMA VUELTA
calcResultFromMillis(lastRunInMillis, &sec_val, &milli_val);
t2.CursorTo(1, 1); // columna y fila relativas al área de texto
t2.Printf(F("%02d.%03d"), sec_val, milli_val);
// MEJOR VUELTA
calcResultFromMillis(bestRunInMillis, &sec_val, &milli_val);
t3.CursorTo(1, 1);
t3.Printf(F("%02d.%03d"), sec_val, milli_val);
} // fin loop
// calcular millis en 2 valores, segundos y milisegundos para display
void calcResultFromMillis(unsigned long value, int *sec_val, int *milli_val) {
*sec_val = int(value / 1000);
*milli_val = value - *sec_val * 1000;
}
Proceso de manufactura
- Guía Experta de Marcado Láser en Aluminio: Precisión, Durabilidad y Aplicaciones Industriales
- Guía Completa de Marcado Láser: Tipos, Beneficios y Aplicaciones
- Marcado Láser de Fibra: Precisión, Velocidad y Versatilidad para Industrias Modernas
- Puntero Láser: Diseño, Fabricación y Resumen de Seguridad
- Montañas Rusas: De Trineos de Nieve a Gigantes de Acero
- Láseres de Semiconductor: Generación Precisa de Luz para Tecnología Moderna
- Láseres de Estado Sólido: Tecnología, Aplicaciones y Tendencias Futuras
- El reloj de arena: historia, artesanía y atractivo moderno
- Misiles Guiados por Láser: Desarrollo, Fabricación e Impacto Estratégico
- Cómo Instalar la Pantalla TFT 3.5″ Kuman en RetroPie – Guía Paso a Paso
- Rpibot: Robot Móvil Económico y Expandible para Aprendizaje de Sistemas Embebidos