文書の過去の版を表示しています。
目次
DSshieldAUTO
DSshieldAUTOは、DSshieldとArduinoUNOだけで、パソコンなしに小規模な自動運転を実現するためのソフトウェアソリューションです。 小さいジオラマの車両やギミックをDCCで自動制御して、手を離しながら模型やジオラマをお楽しみいただける仕組みを提供しています。
AUTOスケッチでできること
- パソコンなしで、DCC車両やポイントを気軽に動かせます。(最初のプログラミングするときだけ、パソコンを使用します)。ボタンやセンサーに応じて、車両やポイントを動かすことも出来ます。ArduinUNOにACアダプタをつなげるだけ。
 - DSシールドだけで完結。小規模な用途にも、数万円の高価なコマンドステーションは不要。
 - メルクリン(Marklin Motorola, MM1, MM2)やDCCの車両・ポイントに対応
 - 教育向け、研修向け、自分の技術向上、ジオラマのギミックのパワーアップなどに使用できます。
 
必要な物
- DCCポイントやDCC車両、レール、ジオラマなど皆様がお持ちのDCCデコーダ搭載物
 - Arduino UNOもしくは互換機
 - 必要に応じて、ボタンやS88デコーダ(在線検出器)、LEDなど。
 - パソコン
 - Arduino IDE(無料)
 
配線の仕方
スケッチの書き込み方法
- Arduino IDEをインストールする。Arduino UNO(互換機)のUSBドライバもインストールする。
 - ボードをArduino UNOにして、ポートをArduino UNOとして認識したポートを指定する。空白はNG。
 
- Uploadボタン(→マーク)を押して書き込む
 
スケッチの作り方
はじめに
全体の構成
Arduinoのスケッチは、setup()とloop()で大きく構成されます。一方で、AUTOスケッチでは、user_init()とuser_program()の2つで構成されます。setup()とloop()は、DCC制御で使用しておりますので、user_の関数にプログラミングしていただきます。なお、user_initはsetupからコールされています。user_programはloopからコールされています。ほとんど同じように使用することが出来ます。
使用できるピン
ピン・端子を使用するときは、pinModeをuser_init()の中で必ずピンの設定します。
//D8ピンを出力にする。 pinMode(8, OUTPUT); //D7ピンを入力にする。 pinMode(7, INPUT); //A2ピンを入力にする。 pinMode(A2, INPUT);
実際に使う場合には、以下のように使用します。
//D8ピンをHIGH(1)で出力する。ピンには5Vが出力される。0VにしたいときはLOW(0)を指定する。 digitalWrite(8, HIGH); //D7ピンからピン状態を読み取る。D7が5Vのときは1がaSensorに入る。0Vのときは0が入る。 int aSensor = digitalRead(7); //A2ピンからアナログの状態を読み取る。A2ピンが5Vのとき1024が入る。2.5Vのとき512、0Vのときは0になる。 int aAnalog = analogRead(A2);
DSシールドで解放されているピンは以下の通りです。この他は、S88や電圧チェック機能で使用されています。 なお、いかに記載はありませんが、5V、3.3V、GNDピンは自由に使用できます。
| デジタル入出力ピン | D7,D8,D11,D12 | 0V,5Vの信号読み取りや、出力を行えます。ボタンの入力、LEDの出力に使用できます。 | 
| アナログおよび デジタル入出力ピン  | A2,A3 | デジタルに加え、光センサや可変抵抗器などのアナログセンサを使えます。 | 
| I2C通信または アナログおよび デジタル入出力ピン  | A4,A5 | 上記に加え、I2C通信が使用できます。wire.hをインクルードする必要があります。 | 
主な命令
AUTOスケッチでは、Arduinoの命令は全部使えますが、たぶん混乱するだけなので、以下の命令でまずは使ってみてください。
車両アドレス: 「ADDR_DCC+DCCアドレス」で指定してください。DCCアドレス8102であれば、ADDR_DCC+8102です。MM2アドレス5なら、ADDR_MM2+5です。
アクセサリアドレス:「ADDR_ACC_DCC+DCCアクセサリアドレス」で指定してください。DCCポイント32であれば、ADDR_ACC_DCC+32です。MM2のポイント5であれば、ADDR_ACC_MM2+5です。
| 命令 | 解説 | 使用例 | 
|---|---|---|
| CMD_END() | 永久ループで止めます。この命令の後は一切制御できなくなります。 | CMD_END(); | 
| CMD_ScanS88() | S88からデータを収集する処理。 | CMD_ScanS88(); | 
| CMD_GetS88(S88アドレス) | 収集したS88データから希望のS88アドレス(1-16)の状態(0 or 1)を得る。 | aSensor = CMD_GetS88(2); | 
| CMD_Wait(待ち時間ミリ秒) | ミリ秒単位(1000で1秒)で待ちます。 | CMD_Wait(1000); | 
| CMD_Power(オンオフ命令) | 0で線路電源オフ、1で線路電源オン。 | CMD_Power(1); | 
| CMD_LocSpeed(車両アドレス, 速度) | 速度は、0-1023で与えてください。 | CMD_LocSpeed(ADDR_DCC+3,500); | 
| CMD_LocDirection(車両アドレス, 進行方向); | 進行方向は0:FWD, 1:REVです。 | CMD_LocDirection(ADDR_DCC+3,1); | 
| CMD_LocFunction(車両アドレス, ファンクション番号, ファンクション状態); | ファンクション番号(0-28)を操作します。 | CMD_LocFunction(ADDR_DCC+3,1,1); | 
| CMD_LocFunctionMomentary(車両アドレス, ファンクション番号); | ファンクション番号(0-28)を操作します。0→1→0のMomentary動作を自動で行います。 | CMD_LocFunctionMomentary(ADDR_DCC+3,1); | 
| CMD_Turnout(アクセサリアドレス, 分岐状態) | ポイントや信号機を操作します。0:分岐, 1:直進です。 | CMD_Turnout(ADDR_ACC_DCC+32,1); | 
| Serial.print, Serial,println | シリアル通信でPC等にメッセージを送れます。 | Serial.println(“車両1検出”); | 
スケッチの例
アドレス3車両のファンクション操作
/*****************************************************************/
/*  User Program Area                                            */
/*****************************************************************/
void user_init(void)
{
}
void user_program(void)
{
	SerialDS.println("Power On");
	CMD_Power(1);
	
	CMD_LocFunction(ADDR_DCC + 3, 0, 1);
	CMD_LocFunction(ADDR_DCC + 3, 1, 1);
	CMD_Wait(500);
	
	SerialDS.println("Loc 3, Func 10, On");
	CMD_LocFunction(ADDR_DCC + 3, 10, 1);
	
	CMD_Wait(500);
	
	SerialDS.println("Loc 3, Func 11, On");
	CMD_LocFunction(ADDR_DCC + 3, 11, 1);
	
	CMD_Wait(500);
	
	SerialDS.println("Loc 3, Func 9, On");
	CMD_LocFunction(ADDR_DCC + 3, 9, 1);
	
	CMD_Wait(500);
	
	SerialDS.println("End...");
	/* 永久ループ(終了) */
	while(1){}
}
タクトスイッチによるルート切り替え
/*****************************************************************/
/*  User Program Area                                            */
/*****************************************************************/
void user_init(void)
{
	pinMode(8, INPUT);
	pinMode(11, INPUT);
	pinMode(12, INPUT);
	
	digitalWrite(8, HIGH);//内部プルアップON
	digitalWrite(11, HIGH);//内部プルアップON
	digitalWrite(12, HIGH);//内部プルアップON
	
	CMD_Power(1);
	Serial.println("Power On");
}
void user_program(void)
{
	//ボタンが押されたとき、digitalReadは0を返す。押さないときは1を返す。
	
	if( digitalRead(8) == 0)
	{
		Serial.println("Route 1");
		
		CMD_Turnout(ADDR_ACC_DCC + 2, 0);
		CMD_Wait(1000);
	}
	if( digitalRead(11) == 0)
	{
		Serial.println("Route 2");
		
		CMD_Turnout(ADDR_ACC_DCC + 1, 1);
		CMD_Wait(1000);
		CMD_Turnout(ADDR_ACC_DCC + 2, 1);
	}
	
	if( digitalRead(12) == 0)
	{
		Serial.println("Route 3");
		
		CMD_Turnout(ADDR_ACC_DCC + 1, 0);
		CMD_Wait(1000);
		CMD_Turnout(ADDR_ACC_DCC + 2, 1);
	}
}
Youtube動画: