LoginSignup
0
1

More than 1 year has passed since last update.

BVE 鉄道シミュレーターで自宅運転台を動かそう~電車でGoコントローラーを使う~

Last updated at Posted at 2022-02-08

BVE 鉄道シミュレーターで自宅運転台を動かそう~準備編~の続きになります。
https://qiita.com/usashirou/items/f99effc0651ff35ead9c
今回は、電車でGoコントローラーを改造してBVEを動かしてみます。

BVEの外部プラグインでコントール

BVEはプラグインを追加することで入力機器や外部出力で動作する機器を追加できます。
今回は、BVEの入力インタフェースとATSプラグインを使用して電車を動かしてみましょう。
入力インタフェースはキーボードや外部コントローラーから車両を運転できるようにするプラグインになります。
保安装置プラグインは、車両からの情報を出力するために使います。
初めに外部コントローラーを使えるようにしましょう。

外部コントローラーを使えるようにする

今回は初代電車でGoコントローラーのワンハンドル版を使用できるようにします。
なお、現在販売されているUSB版やコンバーターを使用すれば無加工で使用できるようです。

改造

まずは、隠しネジを外して分解していきます。
初代電車でGoコントローラーはマスコンの位置に応じて可変抵抗で電圧を変化させています。
なお、ブレーキとマスコンで2つの可変抵抗がついており、どちらの出力も読み取る必要があります。
今回は、この可変抵抗とボタンの出力をArduinoUnoで検出します。
ArduinoUnoから3.3VとGND、検出用のGPIOとしてアナログ入力がありA0~A5のうちの2個及びキーのABC,Start,Selectの5個のデジタル入力を使用するため基板から外にジャンパーケーブルを出します。
なお、元のケーブルは使う可能性がある為、私は残しましたが、切っても問題ないと思います。
注:入力する電源は3.3Vを使用してください
DSC_0773 (2).JPG
そして、元に戻します。
image.png

コントローラーとArduinoUnoをつなげた様子

DSC_0071 (2).JPG

入力プラグイン

標準でいくつかのコントローラーに対応していますが、Arduinoの入力を受け取れるプラグインを追加しましょう。
image.png
三八電車店さんのUniversalContactInterface(UCI)を使用します。
http://saha209kame.web.fc2.com/BVE_ATSPI.html
標準だとC:\Program Files (x86)\mackoy\BveTs5\Input Devicesにプラグインを保存します。
image.png
ダウンロードしたUniversalContactInterface.dllInputsフォルダに置きます。
image.png
セキュリティ警告が出ますが続行します。
image.png
UniversalContactInterfaceが表示されています。
これでUniversalContactInterfaceが使用できるようになります。
BVEを起動して入力プラグインの項目にUniversalContactInterfaceがあることを確認します。
image.png
プロパティを開けることで中の設定を変えることが可能です。
例えば、ABCのスイッチにホーンを割り当てたりといったことが可能になります。
image.png
ArduinoをつなげたCOMポートを選択してOKをクリックします。

電圧を調べる

三八電車店さんですでにArduinoのプログラムが用意されていますが、このままでは使えない為、修正しましょう。
最初に可変抵抗の値を把握しましょう。
可変抵抗の値をanalogReadを使用して1ノッチ毎に把握しておきましょう。
analogReadはすべてのGPIOピンで使用することは出来ません。
ArduinoUnoやNanoの場合Axピンが該当します。
以下はArduinoUnoで試した例です。

Brake
EB: 630
B8:375
B7:333
B6:292
B5:250
B4:208
B3:166
B2:125
B1:83
B0:41

Mascon
P0:83
P1:166
P2:250
P3:334
P4:418
P5:502

流用するプログラム

今回はねぎ味噌BVE公開所さんのプログラムを流用します。
valとして40分の1の値で判断するようにします。
http://kongoexp165hakureirw.blog.fc2.com/blog-entry-5.html
これを先の三八電車店さんのプログラムに挿入します。

プログラム

使用したプログラムは以下です。
まだ修正可能な場所がいくつかあると思いますがとりあえず動くようになりました。
UniversalContactInterfaceで加速にするにはB0が必要なのでB0+Pxが出力されるようにしています。

const int maspin = A3;//マスコンの可変抵抗を接続するピンを選択
const int brpin = A2;//ブレーキの可変抵抗を接続するピンを選択

int NOWBR = 0;
int BEFORBR = 0;

int NOWMC = 0;
int BEFORMC = 0;

const int DEAD = 4;
int DEADsw = 0;
int NOWDEAD = 0;
int BEFORDEAD = 0;

const int REBF = 11;
int REBFsw = 0;
const int REBR = 12;
int REBRsw = 0;

const int SW0 = 5;
int SW0sw = 0;
int NOWSW0 = 0;
int BEFORSW0 = 0;
const int SW1 = 6;
int SW1sw = 0;
int NOWSW1 = 0;
int BEFORSW1 = 0;
const int SW2 = 7;
int SW2sw = 0;
int NOWSW2 = 0;
int BEFORSW2 = 0;
const int SW3 = 8;
int SW3sw = 0;
int NOWSW3 = 0;
int BEFORSW3 = 0;
const int SW4 = 9;
int SW4sw = 0;
int NOWSW4 = 0;
int BEFORSW4 = 0;
const int SW5 = 10;
int SW5sw = 0;
int NOWSW5 = 0;
int BEFORSW5 = 0;

int NOWREB = 0;
int BEFORREB = 0;

int ON = LOW;
int OFF = HIGH;

void setup() {
  pinMode(DEAD, INPUT_PULLUP);
  pinMode(REBF, INPUT_PULLUP);
  pinMode(REBR, INPUT_PULLUP);
  pinMode(SW0, INPUT_PULLUP);
  pinMode(SW1, INPUT_PULLUP);
  pinMode(SW2, INPUT_PULLUP);
  pinMode(SW3, INPUT_PULLUP);
  pinMode(SW4, INPUT_PULLUP);
  pinMode(SW5, INPUT_PULLUP);

  Serial.begin(19200);
  while (!Serial);
}

void loop() {
  int current = analogRead(maspin);
  int brake = analogRead(brpin);
  int bval = brake / 40; //1~1023割る1ノッチ当たりの範囲 intは小数点以下切り捨てを利用
  int mval = current / 40; //1~1023割る1ノッチ当たりの範囲 intは小数点以下切り捨てを利用

  DEADsw = digitalRead(DEAD);
  REBFsw = digitalRead(REBF);
  REBRsw = digitalRead(REBR);

  SW0sw = digitalRead(SW0);
  SW1sw = digitalRead(SW1);
  SW2sw = digitalRead(SW2);
  SW3sw = digitalRead(SW3);
  SW4sw = digitalRead(SW4);
  SW5sw = digitalRead(SW5);

  //スイッチ
  if (SW0sw == ON) {
    NOWSW0 = 1;
  }
  if (SW0sw == OFF) {
    NOWSW0 = 0;
  }
  if (NOWSW0 != BEFORSW0) {
    if (NOWSW0 == 1) {
      Serial.print("S0\r");
    }
    if (NOWSW0 == 0) {
      Serial.print("S100\r");
    }
  }
  BEFORSW0 = NOWSW0;

  if (SW1sw == ON) {
    NOWSW1 = 1;
  }
  if (SW1sw == OFF) {
    NOWSW1 = 0;
  }
  if (NOWSW1 != BEFORSW1) {
    if (NOWSW1 == 1) {
      Serial.print("S1\r");
    }
    if (NOWSW1 == 0) {
      Serial.print("S101\r");
    }
  }
  BEFORSW1 = NOWSW1;

  if (SW2sw == ON) {
    NOWSW2 = 1;
  }
  if (SW2sw == OFF) {
    NOWSW2 = 0;
  }
  if (NOWSW2 != BEFORSW2) {
    if (NOWSW2 == 1) {
      Serial.print("S2\r");
    }
    if (NOWSW2 == 0) {
      Serial.print("S102\r");
    }
  }
  BEFORSW2 = NOWSW2;

  if (SW3sw == ON) {
    NOWSW3 = 1;
  }
  if (SW3sw == OFF) {
    NOWSW3 = 0;
  }
  if (NOWSW3 != BEFORSW3) {
    if (NOWSW3 == 1) {
      Serial.print("S3\r");
    }
    if (NOWSW3 == 0) {
      Serial.print("S103\r");
    }
  }
  BEFORSW3 = NOWSW3;

  if (SW4sw == ON) {
    NOWSW4 = 1;
  }
  if (SW4sw == OFF) {
    NOWSW4 = 0;
  }
  if (NOWSW4 != BEFORSW4) {
    if (NOWSW4 == 1) {
      Serial.print("S4\r");
    }
    if (NOWSW4 == 0) {
      Serial.print("S104\r");
    }
  }
  BEFORSW4 = NOWSW4;

  if (SW5sw == ON) {
    NOWSW5 = 1;
  }
  if (SW5sw == OFF) {
    NOWSW5 = 0;
  }
  if (NOWSW5 != BEFORSW5) {
    if (NOWSW5 == 1) {
      Serial.print("S5\r");
    }
    if (NOWSW5 == 0) {
      Serial.print("S105\r");
    }
  }
  BEFORSW5 = NOWSW5;

  //レバーサ
  if (REBFsw == ON && REBRsw == OFF) {
    NOWREB = 1;
  }
  if (REBFsw == OFF && REBRsw == OFF) {
    NOWREB = 0;
  }
  if (REBFsw == OFF && REBRsw == ON) {
    NOWREB = 2;
  }
  if (NOWREB != BEFORREB) {
    if (NOWREB == 0) {
      Serial.print("RN\r");
    }
    if (NOWREB == 1) {
      Serial.print("RF\r");
    }
    if (NOWREB == 2) {
      Serial.print("RB\r");
    }
  }
  BEFORREB = NOWREB;

  //デッドマン
  if (DEADsw == ON) {
    NOWDEAD = 1;
  }
  if (DEADsw == OFF) {
    NOWDEAD = 0;
  }
  if (NOWDEAD == 0 && NOWDEAD != BEFORDEAD && (NOWBR == 0 || NOWMC != 0)) {
    Serial.print("B998\r");
  }

  BEFORMC = NOWMC;
  BEFORDEAD = NOWDEAD;

  //ブレーキ

  if (bval == 1) {
    NOWBR = 0; //制動N段
  }
  if (bval == 2) {
    NOWBR = 1; //制動1段
  }
  if (bval == 3) {
    NOWBR = 2; //制動2段
  }
  if (bval == 4) {
    NOWBR = 3; //制動3段
  }
  if (bval == 5) {
    NOWBR = 4; //制動4段
  }
  if (bval == 6) {
    NOWBR = 5; //制動5段
  }
  if (bval == 7) {
    NOWBR = 6; //制動6段
  }
  if (bval == 8) {
    NOWBR = 7; //制動7段
  }
  if (bval == 9) {
    NOWBR = 8; //制動8段
  }
  if (bval == 15) {
    NOWBR = 9; //制動EB段
  }
  if (NOWBR == 0) {
  //  Serial.print("B0\r");
  }
  if (NOWBR == 1) {
    Serial.print("B1\r");
  }
  if (NOWBR == 2) {
    Serial.print("B2\r");
  }
  if (NOWBR == 3) {
    Serial.print("B3\r");
  }
  if (NOWBR == 4) {
    Serial.print("B4\r");
  }
  if (NOWBR == 5) {
    Serial.print("B5\r");
  }
  if (NOWBR == 6) {
    Serial.print("B6\r");
  }
  if (NOWBR == 7) {
    Serial.print("B7\r");
  }
  if (NOWBR == 8) {
    Serial.print("B8\r");
  }
  if (NOWBR == 9) {
    Serial.print("B998\r");
  }
  if (NOWBR == 0) {
    if (mval == 2) {
      NOWMC = 0; //力行N段
    }
    if (mval == 4) {
      NOWMC = 1; //力行1段
    }
    if (mval == 6) {
      NOWMC = 2; //力行2段
    }
    if (mval == 8) {
      NOWMC = 3; //力行3段
    }
    if (mval == 10) {
      NOWMC = 4; //力行4段
    }
    if (mval == 12) {
      NOWMC = 5; //力行5段
    }
  }


  if (NOWMC != BEFORMC) {
    if (NOWMC == 0) {
      Serial.print("B0\r");
      Serial.print("P0\r");
    }
    if (NOWMC == 1) {
      Serial.print("B0\r");
      Serial.print("P1\r");
    }
    if (NOWMC == 2) {
      Serial.print("B0\r");
      Serial.print("P2\r");
    }
    if (NOWMC == 3) {
      Serial.print("B0\r");
      Serial.print("P3\r");
    }
    if (NOWMC == 4) {
      Serial.print("B0\r");
      Serial.print("P4\r");
    }
    if (NOWMC == 5) {
      Serial.print("B0\r");
      Serial.print("P998\r");
    }
  }
  delay(10);
}

これで外部コントローラーが使えるようになったと思います。

引用・著作権表示

© 2020 mackoy
© 三八電車店
© ねぎ味噌BVE公開所

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1