令和式ドライビングターボ

@tktk360 2020年03月04日に作成  (2020年03月04日に更新)

作成の動機

  • 皆さんは、ドライビングターボをご存じありますでしょうか。
    1983年に、トミーから発売されたドライブゲームのことです。
    子供のころ、欲しかったのですが、買ってもらえず、友達のうちで遊び倒していたのが懐かしい一品です。
    現代の子供が楽しむには、いささかチープだと思われますので、電子工作初心者の私なりに子供と遊べるようアレンジしてみました。
    メインマイコンが、がじぇるねのGR-KURUMI(くるみ)なので、題して、クルミーズ「カ●ズ」っぽい何かです。
    ロゴ

どんなゲーム

  • タブレットの液晶の上に、電子工作した車を吸盤でつけています。
    ゲームは、背景が上から下へスクロールするドライブものとなっており、タブレットの傾きをジャイロで検知し
    映像を左右に動かすことで、車が動いたように見せています。アイテムを取ったり、障害物にぶつかると、
    車に内蔵したフルカラーLEDが発行することで演出を強化しています。
    デモ動画

車体の電子工作

  • 「カ●ズ」のガチャガチャを分解し、中に、がじぇるねのマイコン「GR-KURUMI」を搭載しています。
    車体の加工は、USBのケーブル取り出し口用にカバーをカットした程度で、すっぽり収まりました。
    基板のピンク色がカ●ズの赤色とマッチし、いい仕事をしています。
    使用パーツは、下記となっています。
品目 価格
GR-KURUMI 2,200
タクトスイッチ、導線 100
FT232RL 350
耐震強度吸盤 110
USB miniBケーブル 110
カーズガチャガチャ 300

※フルカラーLEDは、GR-KURUMIの内蔵のものを利用しています。
※電力は、USBケーブルでの給電としています。(通信にも利用し一石二鳥!)
※半田の箇所は、
・タクトスイッチを導線で基板の11ピンに固定しています。
・FT232RLを基板に固定しています。

GR-KURUMI 搭載の車

クルミーズのマイコンプログラム

  • プログラムは、IDE for GRを使用しています。
    下記コードで完結しているため、そのままご利用可能です。

クルミーズの車体(GrKurumiCar.ino)

// Pin 22,23,24 are assigned to RGB LEDs. #define LED_RED 22 // LOW active #define LED_GREEN 23 // LOW active #define LED_BLUE 24 // LOW active //Switch #define INPUT_PIN 11 #define MODE_NONE 0 #define MODE_ITEM 1 #define MODE_DAMAGE 2 #define MODE_SPEEDUP 3 // switch int status1 = 0; boolean g_switch1 = 0; boolean g_led = 0; byte ledMode = MODE_NONE; int modeTime = 0; // the setup routine runs once when you press reset: void setup() { //setPowerManagementMode(PM_STOP_MODE, 0, 1023); //Set CPU STOP_MODE in delay() //setOperationClockMode(CLK_LOW_SPEED_MODE); //Set CPU clock from 32MHz to 32.768kHz // initialize the digital pin as an output. Serial.begin(9600); pinMode(LED_RED, OUTPUT); pinMode(LED_GREEN, OUTPUT); pinMode(LED_BLUE, OUTPUT); //Switch pinMode(INPUT_PIN, INPUT) ; // turn the LEDs on, glow white. digitalWrite(LED_RED, LOW); digitalWrite(LED_GREEN, LOW); digitalWrite(LED_BLUE, LOW); } //Red + Green -> Brown //Red + Blue -> Purple //Green + Blue-> void setLED(bool r, bool g, bool b) { digitalWrite(LED_RED, r ? LOW : HIGH); digitalWrite(LED_GREEN, g ? LOW : HIGH); digitalWrite(LED_BLUE, b ? LOW : HIGH); } // the loop routine runs over and over again forever: void loop() { //Switch status1 = digitalRead(INPUT_PIN) ; //スイッチの状態を読む /////////////////////////////////////////////////////////////// //[Switch1] //OFF if(status1 == HIGH) { if (g_switch1 == 1) { //Serial.println("OFF1"); g_switch1 = 0; delay(100); } } //ON else { if (g_switch1 == 0) { Serial.println("ON1"); g_switch1 = 1; ledMode = MODE_SPEEDUP; delay(100); } } /////////////////////////////////////////////////////////////// //Pc to Arduino if ( Serial.available() ) { char mode = Serial.read(); switch (mode) { case '0' : ledMode = MODE_NONE; setLED(false, false, false); break; case '1' : ledMode = MODE_ITEM; break; case '2' : ledMode = MODE_DAMAGE; break; case '3' : ledMode = MODE_SPEEDUP; break; } } /////////////////////////////////////////////////////////////// // LED if(ledMode == MODE_ITEM) { //Yellow Green Yellow setLED(false, g_led, false); } else if(ledMode == MODE_DAMAGE) { //Blue Red Blue setLED(false, false, g_led); } else if(ledMode == MODE_SPEEDUP) { //Red Yellow Red setLED(g_led, false, false); } delay(100); g_led = !g_led; }

タブレット側のプログラム

  • タブレット側のゲームプログラムは、Unity3Dを使い作成しています。
    車体のクルミーズをUSB接続すると、タブレット側は「COM数値」として認識します。そのCOMに対して、
    シリアル通信で、値を送り反映させています。
    ここでは、タブレットと、車体の間のデータを送受信するプログラムを参考として、掲載いたします。

下記プログラムを、UnityのGameObjectに追加してください。
ゲームから車体へ、データ送信は、WriteData APIで書き込みます。
車体からゲームは、OnDataReceivedをトリガーとしたイベントとして通知がきます。
皆んさんも是非オリジナルゲームを作って見てください。

SerialDataの送受信(SerialManager.cs)

using System; using System.IO.Ports; using System.Threading; using UnityEngine; public class SerialManager : MonoBehaviour { public delegate void SerialDataReceivedEventHandler(string message); public event SerialDataReceivedEventHandler OnDataReceived; #region << フィールド >> public string comPort = "COM2"; SerialPort _serial; string _message = string.Empty; Thread _SerialThread; bool _isThreading = false; bool _isNewMessageReceived = false; #endregion << フィールド >> void OnDestroy() { ThreadEnd(); } void Update() { if (_isNewMessageReceived) { _isNewMessageReceived = false; OnDataReceived(_message); } } public void Open(string portName) { if(string.IsNullOrEmpty(portName)) { return; } Open(portName, 9600); } public void Open(string portName, int baudRate) { if (_SerialThread == null) { this.comPort = portName; Init(portName, baudRate); _SerialThread = new Thread(this.UpdateData); } } public void ThreadStart() { if (_SerialThread != null) { _SerialThread.Start(); } } public void ThreadEnd() { if (_isThreading) { _isThreading = false; _SerialThread.Abort(); _serial.Close(); _isNewMessageReceived = false; } } void Init(string portName, int baudRate) { try { _serial = new SerialPort(portName, baudRate, Parity.None, 8, StopBits.One); _serial.Open(); } catch (Exception e) { _serial = null; return; } } public void WriteData(string dat) { try { if (_serial != null) { _serial.Write(dat); Debug.Log(dat); } } catch (System.Exception e) { Debug.LogWarning(e.Message); } } public string GetData() { return _message; } public void UpdateData() { _isThreading = true; while (_isThreading && _serial != null && _serial.IsOpen) { try { _message = _serial.ReadLine(); _isNewMessageReceived = true; } catch (System.Exception e) { Debug.LogWarning(e.Message); } } } }

最後に

  • デモ動画を載せておきます。よろしければ、感想をお待ちしております。
    プレイデモ動画
3
1
tktk360 さんが 2020/03/04 に 編集 をしました。 (メッセージ: 初版)
tktk360 さんが 2020/03/04 に 編集 をしました。
ログインしてコメントを投稿する