USB接続のパワーウインドウスイッチを自作

published_with_changes 更新日: event_note 公開日:

labelGaming Gear

ETS2のVer1.37からはパワーウインドウの開閉ができるようになりました。それで、自己満足的にパワーウインドウ・スイッチを作ってみました。ベースにしたのはRX8の運転席側ドアスイッチです。

トレーラ・トラックの窓は運転席側と助手席側の2か所なので普通車用のスイッチではイメージに合いません。軽トラ用だときっとチープでしょうから、右ハンドル用になるのですが、手に入るものはこれしかありません。ヤフオク入手です。

木枠を作って、左ドアスイッチの位置に配置しました。ドアのように乗り降り時に開くことができます。


ついでにスイッチパネルについている他のスイッチにも機能を割り振りました。仕上がりは良好です。

ETS2のパワーウインドウ

スイッチを作る前に試しにキーボードの矢印キーにウインドウの開閉を設定してみたのですが、とても心地よく動きます。ON/OFFのスイッチ2個で一つの窓の開閉を行えることになります。

RX8のウインドウスイッチ

回路図の情報を探せませんでしたので、テスターで探りながら接点の解析を行いました。

調べていくと単なるON/OFFだけではなくスイッチの倒し具合により、一つのスイッチで何通りもの接点が存在します。オートモードがあるので接点がその分増えているのでしょう。不要な接点は飛ばして何とか使おうと色々トライしてみましたが、成立しませんでした。

仕方なく、シーソースイッチの機構だけ使い接点は内部にマイクロスイッチを仕込むことにします。次の写真はシーソースイッチの裏側にある基板です。スイッチの元々の接点部品は取り払い更地にしています。

緑の基板はシーソースイッチのすぐ裏側にあります。この基板は写真下のバスバーに乗っかっています。基板中央部に10個近く並んでいるのが基板とバスバーを繋ぐ端子になります。新たに仕込むマイクロスイッチはこれらの端子に接続します。

上から言えば、シーソースイッチ、基板、バスバーの順で重なっている格好です。コネクタ端子はバスバーから、写真で言うと右側で裏の方へ出ています。


マイクロスイッチの設置

使うマイクロスイッチはこれです。見えないところにマイクロスイッチを配置するので、3D CADでレイアウト検討をします。

基板はマイクロスイッチを固定するためと回路パターンに利用します。基板をシーソースイッチに重ねたときに、シーソースイッチから出ている突起がマイクロスイッチをON/OFFできるように位置決めする必要があります。

CAD化してもその通り作れる訳ではないので、CADは見通しを立てる程度だと思って、根気よく微調整しながら作りました。




十字キーを使う

十字キーは実車と同じくバックミラーの前後左右の傾き調整に使います。

内部のパターンは下写真のようになっています。分かりやすくするため接点とパターンに色付けしました。見てのように、前後左右とも一方向につき2系統の接点の組み合わせにより構成しています。




このまま使うと処理が複雑になるので、一方向1パターンに改造します。白丸3か所でパターンカットし、白フチ青丸の1か所でパターンを繋ぎます。これによって、次のようになります。

  • UP:       緑色、   端子④
  • DOWN: ピンク、端子新設
  • RIGHT: 茶色、   端子⑤
  • LEFT:   空色、   端子⑥

6個のミラー

トレーラ・トラックの場合、左右のバックミラーは上下2段に設けられています。さらに前方に真下を見るためのミラーと助手席側の真下を見るためのミラーがあります。合計6個のミラーになります。


ETS2のゲーム上では、各ミラーが番号付けされています。この番号でミラー選択すればよいので、新たに番号キーになるものをRX8のドアスイッチパネルの前方に追加しました。最初の写真で6個のタクトスイッチが並んでいるものがそれです。1~6の数値KeyBoardとして設定します。

このスイッチはミラーの選択だけでなく、オプションライトやビーコンのON/OFFにも使えます。



その他のスイッチ

他のスイッチにもETS2上のゲーム機能を設定します。

  • ウインドウOPEN禁止スイッチ: リーンアウト視点
  • ミラー格納スイッチ:      グローバルマップ
  • L/Rスイッチ:          左右ビュー
  • 新設スイッチ:         ミラー選択メニュー

スイッチ機能のまとめ


ETS2での機能
スイッチパネル
Pro Micro
ピンアサインピンアサイン
十字SW9,10GND
L-WindowOpenUP_ARROWDoor SW8D1
CloseDOWN_ARROW7D0
R-WindowOpenRIGHT_ARRROW15D2
CloseLEFT_ARROW16D3
MirrorUPW十字SW4D10
DOWNSnewD14
LEFTA6D16
RIGHTD5D15
select mirrorEX1D4
青白EX2D5
EX3D6
緑白EX4D7
オレンジEX5D8
オレンジ白EX6D9
格納On/OffMAPD19
window開閉禁止
リーンアウト視点
D18
SW新設F4D20
L/RL/R ViewA3
VCC
GND


スケッチ

Arduinoではありませんが、Leonardo互換の Pro Microを使います。非常にコンパクトでこういった用途には最適です。Resetボタンがついていなので、写真のようにResetピンから持ってきてタクトスイッチをつけています。

先に説明したバスバーにブレッドボードを貼り付け、そこにPro Microを取り付けました。



これをUSB KeyBoard HIDとして使います。左右のウインドウの開閉には、4つの矢印キーを使い、ミラーの前後左右の動きには、"W"、"S"、"A"、"D"のキーを使います。その他はA3ピンを除いてすべてのdegital input(ON/OFF)で使っています。A3はアナログピンで、VCCとGND間を抵抗分圧して入力しています。



//	Leonardoの修飾キーの定義を以下に示します。		
			
//	キー	16進値	10進数
//	KEY_LEFT_CTRL	0x80	128
//	KEY_LEFT_SHIFT	0x81	129
//	KEY_LEFT_ALT	0x82	130
//	KEY_LEFT_GUI	0x83	131
//	KEY_RIGHT_CTRL	0x84	132
//	KEY_RIGHT_SHIFT	0x85	133
//	KEY_RIGHT_ALT	0x86	134
//	KEY_RIGHT_GUI	0x87	135
//	KEY_UP_ARROW	0xDA	218
//	KEY_DOWN_ARROW	0xD9	217
//	KEY_LEFT_ARROW	0xD8	216
//	KEY_RIGHT_ARROW	0xD7	215
//	KEY_BACKSPACE	0xB2	178
//	KEY_TAB			0xB3	179
//	KEY_RETURN		0xB0	176
//	KEY_ESC			0xB1	177
//	KEY_INSERT		0xD1	209
//	KEY_DELETE		0xD4	212
//	KEY_PAGE_UP		0xD3	211
//	KEY_PAGE_DOWN	0xD6	214
//	KEY_HOME		0xD2	210
//	KEY_END			0xD5	213
//	KEY_CAPS_LOCK	0xC1	193
//	KEY_F1			0xC2	194
//	KEY_F2			0xC3	195
//	KEY_F3			0xC4	196
//	KEY_F4			0xC5	197
//	KEY_F5			0xC6	198
//	KEY_F6			0xC7	199
//	KEY_F7			0xC8	200
//	KEY_F8			0xC9	201
//	KEY_F9			0xCA	202
//	KEY_F10			0xCB	203
//	KEY_F11			0xCC	204
//	KEY_F12			0xCD	205


#include <Keyboard.h>
//#include "Mouse.h"

boolean beforeState = false;
int	keyWait=20; //keyboardやbuttonを押した後の保持時間(待機時間) 
// Last state of the button
int lastButtonState[] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
unsigned long prev[] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
const int Interval = 10 ; //msec, for prevrnt chattering
int lastAnalogInput = 512; //normalは抵抗分圧の中央で9991/2
const int AnalogInputPin = A3;

void setup(){
    //起動時に行う処理
  pinMode(0, INPUT_PULLUP);
  pinMode(1, INPUT_PULLUP);
  pinMode(2, INPUT_PULLUP);
  pinMode(3, INPUT_PULLUP);
  pinMode(4, INPUT_PULLUP);
  pinMode(5, INPUT_PULLUP);
  pinMode(6, INPUT_PULLUP);
  pinMode(7, INPUT_PULLUP);
  pinMode(8, INPUT_PULLUP);
  pinMode(9, INPUT_PULLUP);
  pinMode(10, INPUT_PULLUP);
  pinMode(14, INPUT_PULLUP);
  pinMode(15, INPUT_PULLUP);
  pinMode(16, INPUT_PULLUP);
  pinMode(18, INPUT_PULLUP);
  pinMode(19, INPUT_PULLUP);
  pinMode(20, INPUT_PULLUP);

	// Serial
	Serial.begin (9600);
	
	// Initialize Keyboard Library
    Keyboard.begin();

}

void loop(){ //起動後、何度も行う処理

    //ウインドウ開閉
    
    if(digitalRead(0) == LOW){
        if(!beforeState){
        	Keyboard.press(KEY_DOWN_ARROW); //open LH
            beforeState = true;
        }
    }
    else if(digitalRead(1) == LOW){
        if(!beforeState){
        	Keyboard.press(KEY_UP_ARROW); //close LH
            beforeState = true;
        }
    }
    else if(digitalRead(2) == LOW){
        if(!beforeState){
        	Keyboard.press(KEY_RIGHT_ARROW); //open RH
            beforeState = true;
        }
    }
    else if(digitalRead(3) == LOW){
        if(!beforeState){
            Keyboard.press(KEY_LEFT_ARROW); //close RH
            beforeState = true;
            }
    }   
    else{
        if(beforeState){
            Keyboard.releaseAll();
            beforeState = false;
        }
    }

        // 十字キー

        if(digitalRead(10) == LOW){
	        if(!beforeState){
			Serial.println("Ver. UP: W");
	        	Keyboard.write('w');
	            beforeState = true;
            }
        }
        else if(digitalRead(16) == LOW){
            if(!beforeState){
			Serial.println("Hor. LEFT: A ");
		        Keyboard.write('a');
		        beforeState = true;
            }
        }
        else if(digitalRead(14) == LOW){
	        if(!beforeState){
			Serial.println("Ver. DOWN: S ");
	        	Keyboard.write('s');
	            beforeState = true;
            }
        }
        else if(digitalRead(15) == LOW){
		    if(!beforeState){
			Serial.println("Ver. RIGHT: D ");
		        Keyboard.write('d');
		        beforeState = true;
            }
        }
        else {
            if(!beforeState){
                //Serial1.println("Ver._Neutral");
                Keyboard.releaseAll();
                beforeState = false;
            }
        }


  // Read pin values その他のスイッチ設定
  for (int index = 4; index < 21; index++) {
    int currentButtonState = !digitalRead(index);
    if (int changed = (currentButtonState != lastButtonState[index])) {
      unsigned long cur = millis();

      if (cur - prev[index] > Interval) {
        if (index < 10) {
            if(!beforeState && currentButtonState){
                Serial.println((String)"Key No " + (index - 3));Keyboard.write (48+ index -3 );} //button #1-6
            beforeState = true;
        } else switch (index) {
        case 18: //このスイッチは他と違いnormal on(通電 LOW)
            if(!beforeState && !currentButtonState) { //押すとOFF(HIGH), 押した後の状態はHIHG
                Serial.println("+"); //Num + リーンアウト視点 
                Keyboard.write(223);
                beforeState = true;
            } else if (!beforeState && currentButtonState) {// 離すとき、離した後の状態はLOW
                Serial.println("9"); //視点変更 '9' 
                Keyboard.write('9');delay(keyWait); //視点変更 '9'を4回入れてインテリア視点にする
                Keyboard.write('9');delay(keyWait);
                Keyboard.write('9');delay(keyWait);
                Keyboard.write('9');
                beforeState = true;            
            } break;
        case 19:
            if(!beforeState ){ //押したとき(HIGH to LOW)と離したときの両方でキーを出す
                Serial.println("M"); //ワールドマップ
                Keyboard.write('m');
                beforeState = true;
            } break;
        case 20:
            if(!beforeState && currentButtonState) { //押したとき(HIGH to LOW)
                Serial.println("KEY_F4");
                Keyboard.press(KEY_F4);
                beforeState = true;
            } break;
        default:
            if(beforeState){
                Keyboard.releaseAll();
                beforeState = false;
            }
        }
       lastButtonState[index] = currentButtonState;
      }
      prev[index] = cur;
    }
  }
  // Read analog pin values

    int currentAnalogInput = analogRead(AnalogInputPin);
    if (currentAnalogInput != lastAnalogInput)
    {
        if (abs(currentAnalogInput - lastAnalogInput) > 5) {
          Serial.print(currentAnalogInput);
            if (currentAnalogInput < 512/2 ){Keyboard.write(182);Serial.println(" tenkey ^ : Push LEFT");}// ^ LEFT
            else if (currentAnalogInput > (512+1024)/2) {Keyboard.write(221);Serial.println(" ten key * : Push RIGHT");}// * RIGHT
            else {Keyboard.write(233);delay(100);Keyboard.releaseAll();Serial.println(" not Push");}
          lastAnalogInput = currentAnalogInput;
        }
    delay(100);
    } 
}


Powered by Blogger | Designed by QooQ

keyboard_double_arrow_down

keyboard_double_arrow_down