// MoBa-Speed for ARDUINO V1.5
// powered by N-Modellbahn.de - Joerg Kiessling - 2018
// Version 1.4 is for LCD display and was modified by Rainer Karbaum - 2022
// Arduino Sketch for model speed measurement
// for Arduino Nano.V3, UNO.V3, MEGA
// 2 IR Line Trackers with LM393 komperator output
// Notel for LCD 20x04 Blue LCD Screen
// Digital sensor input Left and Right
#define SENSOR_L 7
#define SENSOR_R 6
////// DECLARATIONS
#include <SPI.h> // Not needed when using I2C
#include <Wire.h> //I2C library
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd = LiquidCrystal_I2C(0x27, 20, 4);
//Distance from sensor Left to sensor Right - your distance (mm)
const double distance = 205.0;
//Your model scale 1/xx
int scale = 160;
//Waiting time to display results (ms)
int waitingtime = 1000;
//Name of variables for time and speed measuring
long int deltatime, starttime, freetime;
void setup() {
//Sensor Input
pinMode(SENSOR_L, INPUT_PULLUP);
pinMode(SENSOR_R, INPUT_PULLUP);
//Interface baud rate
Serial.begin(9600);
//Display
initialize_display();
}
void loop() {
//waiting for signal, sensor Left
if (digitalRead(SENSOR_L) == LOW)
{
//Sensor Left was activated, start time = system time (ms)
starttime = millis();
underprogress_display();
//waiting for signal sensor Right
while (digitalRead(SENSOR_R) == HIGH) {}
//Measured time in ms
deltatime = (millis() - starttime);
refresh_display();
freetime = 0;
if (digitalRead(SENSOR_R) == LOW)
{
freetime = 0;
while (freetime < 20)
{
freetime++;
if (digitalRead(SENSOR_R) == LOW)
{
freetime = 0; //reset time with new occupation
}
delay (50);
}
delay (50);
}
state_ready_display();
}
//waiting for signal, sensor Right
if (digitalRead(SENSOR_R) == LOW)
{
//Sensor Right was activated, start time = system time (ms)
starttime = millis();
underprogress_display();
//waiting for signal sensor Left
while (digitalRead(SENSOR_L) == HIGH) {}
//Measured time in ms
deltatime = (millis() - starttime);
refresh_display();
freetime = 0;
if (digitalRead(SENSOR_L) == LOW)
{
freetime = 0;
while (freetime < 20)
{
freetime++;
if (digitalRead(SENSOR_L) == LOW)
{
freetime = 0; //reset time with new occupation
}
delay (50);
}
delay (50);
}
state_ready_display();
}
} //End of loop
//Output on display
void refresh_display() {
//Output on serial monitor
Serial.println("Speedcheck running..");
Serial.println("");
Serial.println("Deltatime:");
Serial.print(deltatime);
Serial.println(" ms");
Serial.println("---------");
Serial.println("Speed:");
Serial.print(distance / deltatime);
Serial.println(" m/s (real)");
Serial.print(scale * distance / deltatime * 3.6, 0);
Serial.print(" km/h (scale 1/");
Serial.print(scale);
Serial.println(")");
//Output on LCD Display
lcd.init();
lcd.setCursor(0, 0);
lcd.print("Speed ");
lcd.setCursor(7, 0);
lcd.print(scale * distance / deltatime * 3.6, 0); //calculating speed in km/h
lcd.setCursor(11, 0);
lcd.print("km/h");
lcd.setCursor(0, 1);
lcd.print("Spur 1/");
lcd.setCursor(8, 1);
lcd.print(scale);
lcd.setCursor(0, 2);
lcd.print("Delta ");
lcd.setCursor(7, 2);
lcd.print(deltatime * 0.001);
lcd.setCursor(12, 2);
lcd.print("s");
lcd.setCursor(6, 3);
lcd.print(distance / deltatime);
lcd.setCursor(11, 3);
lcd.print("ms");
lcd.setCursor(0, 3);
lcd.print("Time ");
lcd.display();
delay(waitingtime);
}
void state_ready_display() {
lcd.init();
lcd.setCursor(2, 2);
lcd.print("Warte auf Lok ...");
lcd.setCursor(4, 0);
lcd.print("km/h letzte Lok");
lcd.setCursor(0, 0);
lcd.print(scale * distance / deltatime * 3.6, 0); //calculating speed in km/h
lcd.setCursor(0, 1);
lcd.print("--------------------");
lcd.display();
Serial.println("");
Serial.println("<<< READY >>>");
}
void underprogress_display() {
lcd.init();
lcd.setCursor(1, 2);
lcd.print("Messung laeuft ...");
lcd.setCursor(1, 0);
lcd.print("Geschwindigkeit");
lcd.display();
}
void initialize_display() {
lcd.init();
lcd.backlight();
delay(250);
lcd.noBacklight();
delay(1000);
lcd.backlight();
delay(1000);
lcd.setCursor(0, 0);
lcd.print("powered by");
lcd.setCursor(0, 1);
lcd.print("N-Modellbahn.de");
lcd.setCursor(0, 2);
lcd.print("Version 1.5");
lcd.setCursor(0, 3);
lcd.print("by Rainer Karbaum");
lcd.display();
delay(1000);
lcd.init();
lcd.setCursor(2, 2);
lcd.print("Warten auf Zug");
lcd.setCursor(4, 0);
lcd.print("Spur 1/");
lcd.setCursor(11, 0);
lcd.print(scale);
lcd.display();
Serial.println("<<< READY >>>");
}