SSブログ

Arduinoで自動運転に挑戦してみる! その3 プログラムで自動運転 [Arduinoで自動運転(DCC)]

こんにちは。ここ数日の都内はやっと夏らしい青空になってます♪

ただ、去年と比べると35度超えとなっていないので『昭和の頃の夏』を思い出してます。

この週末から夏休みという皆様も多いのでは?
私は去年もそうでしたが、夏休みはなし!

さて、arduinoでの自動運転ですが、なんとか試運転まで辿り着きました。

IMG_3425.JPG

言葉で説明するよりも動画を観てもらうのが解り易いと思いましたのでUPしてみました。



ホームの有効長や待避線の長さがギリギリなので、急停車や車止めで止まったりと、まだまだの状態ですが、プログラムの改良とストラクチャの作り込みを開始しようと思います。

今回のプログラムです。


/***********************************************************************/
/*                                                                     */
/*      Zゲージ 千秀鉄道 姨捨タイプワンプレートレイアウト           */
/*      自動運転プログラム                                             */
/*                                                                     */
/*                                                                     */
/*      Ver.1.00                2016.07.xx                             */
/*                                                                     */
/*                                              by 目黒のダンボ        */
/*                                                                     */
/***********************************************************************/

#include <IRremote.h>

//  変数を宣言

#define P01_R 1   // No.1 ポイント  右
#define P01_L 2   // No.1 ポイント  左
#define P02_R 3   // No.2 ポイント  右
#define P02_L 4   // No.2 ポイント  左
#define P03_R 5   // No.3 ポイント  右
#define P03_L 6   // No.3 ポイント  左
#define P04_R 7   // No.4 ポイント  右
#define P04_L 8   // No.4 ポイント  左
#define P05_R 9   // No.5 ポイント  右
#define P05_L 10  // No.5 ポイント  左
#define P06_R 11  // No.6 ポイント  右
#define P06_L 12  // No.6 ポイント  左
#define P07_R 13  // No.7 ポイント  右
#define P07_L 14  // No.7 ポイント  左

#define Photo_r 900  // フォトリフレクタの戻り値 店
// #define Photo_r 800 // フォトリフレクタの戻り値 窓際

#define Track_2 115 // 115系
#define Track_1 165 // 165系
#define Type_115 115  // 115系
#define Type_165 165  // 165系

/***********************************************************************/
/*      変数を宣言                                                     */
/*      タイマー割り込みのレジスター値を指定して周波数を設定します     */
/*      analogWrite3(n)のnに相当する部分に出力値を入れていきます     */
/***********************************************************************/

void analogWrite3(int op1)
{
  TCCR2A=0b00100011;
  TCCR2B=0b00001010;
  OCR2A=150;
  OCR2B=op1;
}
/***********************************************************************/
/*      変数を宣言                                                     */
/*      タイマー割り込みのレジスター値を指定して周波数を設定します     */
/*      analogWrite10(n)のnに相当する部分に出力値を入れていきます    */
/***********************************************************************/
void analogWrite10(int op2)
{
  TCCR1A=0b00100011;
  TCCR1B=0b00011010;
  OCR1A=150;
  OCR1B=op2;
} 



int latchPin = 2; // 74HC595のST_CPへ 白
int clockPin = 7; // 74HC595のSH_CPへ 緑
int dataPin  = 4; // 74HC595のDSへ  黄色

int v;
int h;
int l;

int fw=1;   // 前後進用変数

int RECV_PIN = 8;     // リモコン入力 赤
IRrecv irrecv(RECV_PIN);
decode_results results;


void setup() {
  pinMode(latchPin, OUTPUT);  // 白
  pinMode(clockPin, OUTPUT);  // 緑
  pinMode(dataPin, OUTPUT); // 黄色

  Serial.begin(9600);
  irrecv.enableIRIn(); // Start the receiver

  pinMode(13, OUTPUT); // 確認用LED

  pinMode(3,OUTPUT);   // 赤
  pinMode(10,OUTPUT);  // 白
  pinMode(11,OUTPUT);  // 緑
  pinMode(12,OUTPUT);  // 黄

}

void loop() {

int val;        // フォトリフレクタ用変数

  digitalWrite(13, HIGH);   // 電源ONで確認用LEDを点灯
  delay(1000);  // wait for a second
  // turn the LED off by making the voltage LOW
  // フォトリフレクタの戻り値確認
  Serial.println("Step000");
  val = SENSOR_read(0);
  Serial.println("sensor1");
  Serial.println(val);
  val = SENSOR_read(1);
  Serial.println("sensor2");
  Serial.println(val);
  val = SENSOR_read(2);
  Serial.println("sensor3");
  Serial.println(val);

  if (irrecv.decode(&results)) {
    Serial.println("Step000");
    Serial.println(results.value, HEX);
    irrecv.resume(); // Receive the next value

    if((results.value == 0xFF30CF) ||
      (results.value == 0x9716BE3F)){ // リモコンが1か?
        // turn the LED on (HIGH is the voltage level)

      digitalWrite(13, LOW);    // 確認用LEDを消灯
      delay(1000);  // wait for a second


      // モータードライバ準備
//      Serial.println("Step001");
//      PR_Mdriver();

      // ポイント設定1
      Serial.println("Step011");
      point_set1();
      delay(2000);

      // モータードライバ準備
      Serial.println("Step012");
      PR_Mdriver();

      delay(500);

      // 上り2番線から発車
      // 前進加速
      Serial.println("Step013");
      F_Accel(Track_2);

      // 上り本線を力行

      // 退避線への入線をチェック
      // フォトリフレクタから読み込み
      // センサー3を通過までループする
      do{
        val = SENSOR_read(2);
        delay(100);
      } while (val > Photo_r) ;
      Serial.println("sensor3");
      Serial.println(val);

      // 前進減速
      Serial.println("Step014");
      F_Decel(Track_2);

      // ポイント設定2
      Serial.println("Step021");
      point_set2();
      delay(2000);

      // モータードライバ準備
      Serial.println("Step022");
      PR_Mdriver();

      delay(500);

      // 上り2番線へ
      // 後進加速
      Serial.println("Step023");
      R_Accel(Track_2);

      // 上り2番線への入線をチェック
      // フォトリフレクタから読み込み
      // センサー2を通過までループする
      do{
        val = SENSOR_read(1);
        delay(100);
      } while (val > Photo_r) ;
      Serial.println("sensor2");
      Serial.println(val);

      // 後進減速
      Serial.println("Step024");
      R_Decel(Track_2);

      // ポイント設定3
      Serial.println("Step031");
      point_set3();
      delay(2000);

      // モータードライバ準備
      Serial.println("Step032");
      PR_Mdriver();

      delay(500);

      // 下り1番線から発車
      // 前進加速
      Serial.println("Step033");
      F_Accel(Track_1);

      // 退避線への入線をチェック
      // フォトリフレクタから読み込み
      // センサー3を通過までループする
      do{
        val = SENSOR_read(2);
        delay(100);
      } while (val > Photo_r) ;
      Serial.println("sensor3");
      Serial.println(val);

      // 前進減速
      Serial.println("Step034");
      F_Decel(Track_1);

      // ポイント設定4
      Serial.println("Step041");
      point_set4();
      delay(2000);

      // モータードライバ準備
      Serial.println("Step042");
      PR_Mdriver();

      // 後進加速
      Serial.println("Step043");
      R_Accel(Track_1);

      // 下り本線を力行
      delay(5000);

      // ポイント設定5
      Serial.println("Step051");
      point_set5();
      delay(2000);

      // 下り1番線への入線をチェック
      // フォトリフレクタから読み込み
      // センサー1を通過までループする
      do{
        val = SENSOR_read(0);
        delay(100);
      } while (val > Photo_r) ;
      Serial.println("sensor1");
      Serial.println(val);

      // 後進減速
      Serial.println("Step052");
      R_Decel(Track_1);

      // モータードライバ準備
      Serial.println("Step053");
      PR_Mdriver();

    }
  }
}

/***********************************************************************/
/*      ポイント設定1                                                  */
/*      ポイントの状態を                                               */
/*              P1⇒左                                                 */
/*              P2⇒左                                                 */
/*              P3⇒右                                                 */
/*              P4⇒右                                                 */
/*              P5⇒右                                                 */
/*              P6⇒右                                                 */
/*              P7⇒右                                                 */
/*      に切り換える                                                   */
/***********************************************************************/

void point_set1() {

  point_onoff8(P01_L);
  point_onoff8(P02_L);
  point_onoff8(P03_R);
  point_onoff8(P04_R);
  point_onoff8(P05_R);
  point_onoff8(P06_R);
  point_onoff8(P07_R);
  point_off();

}

/***********************************************************************/
/*      ポイント設定2                                                  */
/*      ポイントの状態を                                               */
/*              P1⇒左                                                 */
/*              P2⇒左                                                 */
/*              P3⇒左                                                 */
/*              P4⇒右                                                 */
/*              P5⇒右                                                 */
/*              P6⇒右                                                 */
/*              P7⇒左                                                 */
/*      に切り換える                                                   */
/***********************************************************************/

void point_set2() {

  point_onoff8(P01_L);
  point_onoff8(P02_L);
  point_onoff8(P03_L);
  point_onoff8(P04_R);
  point_onoff8(P05_R);
  point_onoff8(P06_R);
  point_onoff8(P07_L);
  point_off();

}

/***********************************************************************/
/*      ポイント設定3                                                  */
/*      ポイントの状態を                                               */
/*              P1⇒左                                                 */
/*              P2⇒左                                                 */
/*              P3⇒左                                                 */
/*              P4⇒左                                                 */
/*              P5⇒左                                                 */
/*              P6⇒左                                                 */
/*              P7⇒右                                                 */
/*      に切り換える                                                   */
/***********************************************************************/

void point_set3() {

  point_onoff8(P01_L);
  point_onoff8(P02_L);
  point_onoff8(P03_L);
  point_onoff8(P04_L);
  point_onoff8(P05_L);
  point_onoff8(P06_L);
  point_onoff8(P07_R);
  point_off();

}

/***********************************************************************/
/*      ポイント設定4                                                  */
/*      ポイントの状態を                                               */
/*              P1⇒左                                                 */
/*              P2⇒左                                                 */
/*              P3⇒右                                                 */
/*              P4⇒左                                                 */
/*              P5⇒左                                                 */
/*              P6⇒左                                                 */
/*              P7⇒右                                                 */
/*      に切り換える                                                   */
/***********************************************************************/

void point_set4() {

  point_onoff8(P01_L);
  point_onoff8(P02_L);
  point_onoff8(P03_R);
  point_onoff8(P04_L);
  point_onoff8(P05_L);
  point_onoff8(P06_L);
  point_onoff8(P07_R);
  point_off();

}

/***********************************************************************/
/*      ポイント設定5                                                  */
/*      ポイントの状態を                                               */
/*              P1⇒左                                                 */
/*              P2⇒左                                                 */
/*              P3⇒右                                                 */
/*              P4⇒左                                                 */
/*              P5⇒右                                                 */
/*              P6⇒左                                                 */
/*              P7⇒右                                                 */
/*      に切り換える                                                   */
/***********************************************************************/

void point_set5() {

  point_onoff8(P01_L);
  point_onoff8(P02_L);
  point_onoff8(P03_R);
  point_onoff8(P04_L);
  point_onoff8(P05_R);
  point_onoff8(P06_L);
  point_onoff8(P07_R);
  point_off();

}


/***********************************************************************/
/*      ポイント切り換え                                               */
/*        ポイント point_no を切り替えます                             */
/***********************************************************************/
void point_onoff8(int point_no) {
  // 送信中のlatchPinはグランド(LOW)レベル
  digitalWrite(latchPin, LOW);
  // シフト演算を使って切り替えるポイントを選択しています
  point_no = point_no -1;

  v = 1<<point_no;
  h = v>>8;
  l = v & 0xff;
  shiftOut(dataPin, clockPin, MSBFIRST, h);
  shiftOut(dataPin, clockPin, MSBFIRST, l);
  // 送信終了後latchPinをHIGHにする
  digitalWrite(latchPin, HIGH);
  delay(500);
}


/***********************************************************************/
/*      ポイント切り換え終了                                           */
/*        シフトレジスタをクリアする                                   */
/***********************************************************************/
void point_off() {
  // 送信中のlatchPinはグランド(LOW)レベル
  digitalWrite(latchPin, LOW);
  // シフト演算を0クリア
  shiftOut(dataPin, clockPin, MSBFIRST, 0);
  shiftOut(dataPin, clockPin, MSBFIRST, 0);
  // 送信終了後latchPinをHIGHにする
  digitalWrite(latchPin, HIGH);
  // 送信終了後latchPinをHIGHにする
  delay(1000);
}

/***********************************************************************/
/*      モータードライバ準備                                           */
/***********************************************************************/

void PR_Mdriver() {
  digitalWrite(3,LOW);
  digitalWrite(11,LOW);
  digitalWrite(12,LOW); 
}

/***********************************************************************/
/*      前進 加速                                                     */
/***********************************************************************/

void F_Accel(int Track_no) {
  digitalWrite(11,HIGH);
  if(Track_no == Type_115){
    Serial.println("Track_no");
    Serial.println(Track_no);
    for (int i=1 ;i<12 ;i++ ){
      analogWrite3(i);
      digitalWrite(10,LOW);
      delay(100);
    }
  }
  else{
    Serial.println("Track_no");
    Serial.println(Track_no);
    for (int i=41 ;i<80 ;i++ ){
      analogWrite3(i);
      digitalWrite(10,LOW);
      delay(50);
    }
  }
}

/***********************************************************************/
/*      後進 加速                                                     */
/***********************************************************************/

void R_Accel(int Track_no) {
  digitalWrite(12,HIGH);
  if(Track_no == Type_115){
    Serial.println("Track_no");
    Serial.println(Track_no);
    for (int i=1 ;i<12 ;i++ ){
      analogWrite10(i);
      digitalWrite(3,LOW);
      delay(100);
    }
  }
  else{
    Serial.println("Track_no");
    Serial.println(Track_no);
    for (int i=41 ;i<80 ;i++ ){
      analogWrite10(i);
      digitalWrite(3,LOW);
      delay(50);
    }
  }
}

/***********************************************************************/
/*      前進 減速                                                     */
/***********************************************************************/

void F_Decel(int Track_no) {
  if(Track_no == Type_115){
    Serial.println("Track_no");
    Serial.println(Track_no);
    for (int i=12;i>1;i--){
      analogWrite3(i);
      digitalWrite(10,LOW);
      delay(120);
    }
  }
  else{
    Serial.println("Track_no");
    Serial.println(Track_no);
    for (int i=80;i>41;i--){
      analogWrite3(i);
      digitalWrite(10,LOW);
      delay(40);
    }
  }
  analogWrite3(0);
  digitalWrite(10,LOW);
}

/***********************************************************************/
/*      後進 減速                                                     */
/***********************************************************************/

void R_Decel(int Track_no) {
  if(Track_no == Type_115){
    Serial.println("Track_no");
    Serial.println(Track_no);
    for (int i=12;i>1;i--){
      analogWrite10(i);
      digitalWrite(13,LOW);
      delay(95);
    }
  }
  else{
    Serial.println("Track_no");
    Serial.println(Track_no);
    for (int i=80;i>41;i--){
      analogWrite10(i);
      digitalWrite(13,LOW);
      delay(30);
    }
  }
  analogWrite10(0);
  digitalWrite(13,LOW);
}


/***********************************************************************/
/*      フォトリフレクタからの読み込み処理                             */
/*      (30回読み込み平均をとる)                                     */
/***********************************************************************/
int SENSOR_read(int PinNo) {
     long ans ;
     int i ;

     ans = 0 ;
     for (i=0 ; i < 30 ; i++) {
      // 指定のアナログピン(0番端子)から読取り
          ans  = ans + analogRead(PinNo) ;
     }
     return ans/30 ;  // 30回の平均値を返す
}





nice!(2)  コメント(2)  トラックバック(0) 
共通テーマ:趣味・カルチャー

nice! 2

コメント 2

taka@

こんにちは!やってますね~(^^)

私も無いアタマをフル活用してますが、イマイチ理解不能・・・orz
もっと良い脳みそが欲しいですw

ところで、動画が非公開になってるみたいで・・・(リンク先も)
ご確認を~♪


by taka@ (2016-08-08 14:09) 

目黒のダンボ

taka@さん、こんばんは。

>こんにちは!やってますね~(^^)
なんとかプロトタイプ的なのはできてきました。

>私も無いアタマをフル活用してますが、イマイチ理解不能・・・orz
DCCの自動運転、期待してます!

>もっと良い脳みそが欲しいですw
私も欲しい!(笑)

>ところで、動画が非公開になってるみたいで・・・(リンク先も)
>ご確認を~♪
あぁぁ、脳みそどころか、注意力もないようです。^^;
設定を変えましたので、再度ポチっとしてみてください。

by 目黒のダンボ (2016-08-10 02:29) 

コメントを書く

お名前:
URL:
コメント:
画像認証:
下の画像に表示されている文字を入力してください。

トラックバック 0