レーザートリガー・スロットカーラップタイマー: GLCD表示で高精度計時
必要な部品と材料
| 部品 | 数量 | 備考 |
|---|---|---|
| Arduino Mega 2560 | 1 | ピン数多くGLCD制御に有利 |
| KY-008 レーザーモジュール (赤色, 5V) | 1 | 発光側 |
| レーザー受光センサー (KY-008対応フォトトランジスタモジュール等) | 1 | 受光側、デジタル出力 |
| グラフィックLCD (GLCD, KS0108互換, 128×64) | 1 | 並列インターフェース |
| ブレッドボード/ユニバーサル基板 | 1 | |
| ジャンパーワイヤー | 多数 | |
| スロットカートラック | 1 | 既存コースに設置 |
使用ソフトウェア
- Arduino IDE
- openGLCDライブラリ (Bitbucket / Playground)
プロジェクト概要
スロットカー (ミニチュア電動レーシングカー) コースのラップタイムを、レーザーゲートで計測し、グラフィックLCD (GLCD) にリアルタイム表示するシステムです。レーザー光がカー通過で遮断されるたびにラップを検知。現在ラップ、前回ラップ、ベストラップをミリ秒精度で表示。デバウンス処理で誤検知を防止。自作自走スロットカープロジェクトの派生として制作されました。

ハードウェア構成
1. KY-008 レーザーモジュール
- ピン: - (GND), + (VCC), S (信号)
- 常時点灯でOKなら S と + を両方 5V に接続 (簡易)
- 点灯制御したい場合: S を Arduino デジタルピンに接続し HIGH で点灯
2. レーザー受光センサー
- 3ピン: GND, VCC (5V), SIGNAL (デジタル出力)
- SIGNAL → Arduino デジタルピン 2 (割り込み対応ピン推奨)
- 光受信時 HIGH / 遮断時 LOW (またはその逆、モジュール仕様確認のこと)
3. GLCD (KS0108並列接続)
データ線 8本 (D0-D7) + 制御線 6本 (RS, RW, E, CS1, CS2, RST) + 電源/コントラスト調整 = 最低14本必要。Mega 2560なら余裕で接続可能。ピンアサインは openGLCD ライブラリの設定ファイル或いはコンストラクタで指定。

配線の整理には専用コネクター自作がおすすめ (写真参照)。
ソフトウェア: ラップタイマーロジック
主要変数
unsigned long currentRunStartMillis; // 現在ラップ開始時刻
unsigned long lastRunInMillis; // 前回ラップタイム
unsigned long bestRunInMillis; // ベストラップタイム
int currentLap = 0; // ラップカウント
unsigned long savedMillis; // 割り込み時刻保存用
// デバウンス用
int gateSensorState;
int lastGateSensorState = LOW;
unsigned long lastDebounceTime = 0;
const int debounceDelay = 50; // ms
表示エリア定義 (openGLCD)
gText t1; // ラップ数 + 現在ラップタイム (大フォント)
gText t2; // 前回ラップタイム
gText t3; // ベストラップタイム
セットアップ
void setup() {
pinMode(gateSensorPin, INPUT);
delay(50); // センサー/レーザー安定待ち (起動時誤検知防止)
GLCD.Init(NON_INVERTED);
// 表示エリア定義
t1.DefineArea(textAreaTOP, lcdnums14x24); // 上部: 大きい数字フォント
t2.DefineArea(0, GLCD.CenterY, 8, 2, fixednums7x15);
t3.DefineArea(GLCD.CenterX, GLCD.CenterY, 8, 2, fixednums7x15);
t3.SetFontColor(WHITE);
t3.ClearArea();
// 固定ラベル
GLCD.SelectFont(System5x7);
GLCD.CursorTo(1, 4); GLCD.print("LAST");
GLCD.CursorTo(11, 4); GLCD.print("BEST");
// 初期化
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;
// ビーム遮断 (LOW) = カー通過検知
if (gateSensorState == LOW) {
savedMillis = millis(); // 同一時刻で演算
if (currentLap > 0) {
// 2周目以降: ラップタイム確定
lastRunInMillis = savedMillis - currentRunStartMillis;
// ベスト更新判定
if (lastRunInMillis < bestRunInMillis || bestRunInMillis == 0) {
bestRunInMillis = lastRunInMillis;
}
}
// 次ラップ開始時刻リセット
currentRunStartMillis = savedMillis;
currentLap++;
}
}
}
lastGateSensorState = reading;
// === 表示更新 (毎ループ実行) ===
savedMillis = millis();
int sec_val, milli_val;
// 現在ラップ経過時間
if (currentLap > 0) {
calcResultFromMillis(savedMillis - currentRunStartMillis, &sec_val, &milli_val);
} else {
calcResultFromMillis(0, &sec_val, &milli_val);
}
// ラップ数 (左上)
t1.CursorTo(0, 0);
t1.Printf(F("%02d"), currentLap);
// 現在ラップタイム (右上)
t1.CursorTo(3, 0);
t1.Printf(F("%02d.%03d"), sec_val, milli_val);
// 前回ラップ (左下)
calcResultFromMillis(lastRunInMillis, &sec_val, &milli_val);
t2.CursorTo(1, 1);
t2.Printf(F("%02d.%03d"), sec_val, milli_val);
// ベストラップ (右下)
calcResultFromMillis(bestRunInMillis, &sec_val, &milli_val);
t3.CursorTo(1, 1);
t3.Printf(F("%02d.%03d"), sec_val, milli_val);
}
ミリ秒→秒/ミリ秒変換ヘルパー
void calcResultFromMillis(unsigned long value, int *sec_val, int *milli_val) {
*sec_val = int(value / 1000);
*milli_val = value - *sec_val * 1000;
}
設置・調整のポイント
- 光軸合わせが最重要: レーザーとセンサーをコース両側に固定し、カー通過ラインで確実に遮断されるよう高さ・角度を微調整
- 環境光対策: センサーに遮光フードを付けたり、変調レーザー/同期検波化で耐ノイズ向上
- デバウンス時間: カー速度と車体長に合わせて調整 (50msは目安、高速化なら短く)
- 電源: MegaはUSB給電可だが、レーザー常時点灯なら外部5V推奨
発展アイデア
- 複数レーン対応 (センサー増設、ラップデータ配列化)
- SDカードログ保存 (CSVで後解析)
- Bluetooth/Wi-Fiでスマホ/PCにリアルタイム転送
- スタート信号 (赤外線/無線) と同期してレーススタート自動検知
- セクタタイム計測 (中間ポイント追加)
- OLED/I2C LCDへの移植 (配線削減、Mega不要)
製造プロセス
- アルミニウムレーザーマーキング専門ガイド:精度、耐久性、産業用途
- レーザーマーキング総合ガイド:種類、メリット、用途
- ファイバーレーザーマーキング:現代産業向けの精度、速度、汎用性
- レーザーポインター:設計、製造、安全性の概要
- ローラーコースター:雪ソリから鋼鉄の巨人へ
- 半導体レーザー:現代技術を支える精密光生成
- 固体レーザー:技術、応用、将来動向
- 砂時計:歴史、職人技、現代的魅力
- レーザー誘導ミサイル:開発、製造、戦略的インパクト
- Kuman 3.5インチTFTディスプレイをRetroPieにインストールするステップバイステップガイド
- Rpibot:組み込みシステム学習向け低コスト拡張性モバイルロボット