So-net無料ブログ作成

Arduinoによる自動運転への道 その6 [Arduino]

デジタル出力が足りないので、TC74HC595APの2個直列による16本増やしをしてみましょう。

シフトアウト16-2.jpg

ICの配置が上下逆になってますので注意してください。

参考にしたのは、HIRAMINE.COMさんのところです。

ありがとうございます。

**********************
//LED1のみ点灯のスケッチ

#define DATAPIN  (25) // 74HC595のSI(14)へ
#define LATCHPIN (26) // 74HC595のRCK(12)へ
#define CLOCKPIN (27) // 74HC595のSCK(11)へ

void MyShiftOut( int dataPin, int clockPin, int bit, unsigned long val )
{
 for( int i = 0; i < bit; i++ )
 {
  digitalWrite(dataPin, !!(val & (1L << i)));
   
  digitalWrite(clockPin, HIGH);
  digitalWrite(clockPin, LOW);
 }
}

void setup()
{
 pinMode(DATAPIN, OUTPUT);
 pinMode(LATCHPIN, OUTPUT);
 pinMode(CLOCKPIN, OUTPUT);
}

void loop()
{
 for( int i = 0; i < 16; i++ )
 {
  digitalWrite(LATCHPIN, LOW);  // 送信中はLATCHPINをLOWに

  // シフト演算を使って点灯するLEDを選択しています
  MyShiftOut( DATAPIN, CLOCKPIN, 16, 32768 );  //32768を変えることで点灯するLEDを選択

  digitalWrite(LATCHPIN, HIGH);  // 送信後はLATCHPINをHIGHに戻す

  delay(100);
 }
}


**********************

TC74HC595AP(1)のQAピンに繋がるLED1を点灯させるには、

シフトレジスタ16_2.jpg
TC74HC595APを2個直列に繋ぐと16ビットレジスタになります。

QAレジスタだけビットを立てればいいわけです。
(点灯させたいレジスタのビットを立てればいいことです。)

2進数「1000000000000000」を10進数に変換すると「32768」になるので、スケッチの最後の方の「MyShiftOut( DATAPIN, CLOCKPIN, 16, 32768 );  」の第4引数の数値「32768」とすればLED1のみ点灯するわけです。

他の任意のピンから出力したい場合は下記の数値を入れればいいわけです。

<TC74HC595(1)>
LED1
(QA(15番ピン)  32768
LED2
(QB(1番ピン)   16384
LED3
(QC(2番ピン)    8192
LED4
(QD(3番ピン)    4096
LED5
(QE(4番ピン)    2048
LED6
(QF(5番ピン)    1024
LED7
(QG(6番ピン)     512
LED8
(QH(7番ピン)     256

TC74HC595(2)>
LED9
(QA(15番ピン)    128
LED10
(QB(1番ピン)     64
LED11
(QC(2番ピン)     32
LED12
(QD(3番ピン)     16
LED13
(QE(4番ピン)      8
LED14
(QF(5番ピン)      4
LED15
(QG(6番ピン)      2
LED16(QH(7番ピン)      1

ちなみに「65535」で全点灯になります。

TC74HC595APの4個直列の32出力や8個直列の64出力は上記サイトをご参考にされてください。

次回は信号機です。


タグ:鉄道模型
コメント(2)  トラックバック(0) 
共通テーマ:趣味・カルチャー

Arduinoによる自動運転への道 その5 [Arduino]

 我が家では、今頃「あまちゃん」ブームです。

「じぇじぇじぇ!」('jjj')

出力ピンの増設は簡単でしたが、アナログ入力ピンの増設はお手上げです。

デジタルピンの増設が出来たので、センサー入力はアナログピンが足りなくなったら、「アナデジ変換法」でデジタルピンで賄おうと思います。

入力ピンが足りなくなった時に、頼りするサイトはここです。

ここのスケッチをコピペしてやると、親爺ぃの環境ではコンパイルエラーをしてしまいます。

どうも、MISOとSCKの変数名はいけないみたいです。

これが解るまで1週間悩んでしまいました。

P1050506.JPG

使用ICはTC74HC165APです。

シフトイン.jpg
(実際は、タクトスイッチの手前にプルダウン抵抗(10KΩ)が入ります。)

Arduino MEGAのデジタルピンを使います。

**********************************

#define MISOO 24     // データの入力ピン(74HC165-QH)
#define SCKK  23     // クロック出力ピン(74HC165-CK)
#define SLL   22     // レジスタロードピン(74HC165-SL)

byte ShiftData ;

// 74HC165のデータを読込む(受信する)関数
// DataPin :データの入力ピン
// clockPin:クロック出力ピン
// loadPin :レジスタロードピン
byte ShiftIn(int dataPin,int clockPin,int loadPin)
{
     unsigned char x ;
     int  i ;

     x = 0 ;
     digitalWrite(loadPin,LOW) ;          // 入力端子(A-H)の情報をレジスタに読込めと指示する
     digitalWrite(loadPin,HIGH) ;
     x = x | (digitalRead(dataPin) << 7) ;// H端子の内容を受信する
     for (i=6 ; i>=0 ; i--) {             // G端子~A端子まで繰り返す
          digitalWrite(clockPin,HIGH) ;         // 1ビットシフト指示を出す
          digitalWrite(clockPin,LOW) ;
          x = x | (digitalRead(dataPin) << i) ; // シフトされた内容を受信する
     }
     return x ;
}
// 電源起動時とリセットの時だけのみ処理する関数
void setup() {
     // シリアル通信の初期化
     Serial.begin(9600) ;
     // 74HC165のピン情報初期化
     pinMode(MISOO, INPUT) ;
     pinMode(SCKK,  OUTPUT) ;
     pinMode(SLL,   OUTPUT) ;
     digitalWrite(SLL,HIGH) ;
     digitalWrite(SCKK,LOW);
     // 3秒後に開始
     delay(3000) ;
     // 74HC165入力端子のデータを読込み表示を行う
     ShiftData = ShiftIn(MISOO,SCKK,SLL) ;
     Serial.println(ShiftData, BIN);
}
// 繰り返し実行されるメインの処理関数
void loop() {
     byte dt ;

     // 74HC165入力端子のデータを読込む
     dt = ShiftIn(MISOO,SCKK,SLL) ;
     if ( dt != ShiftData ) {
          // データに変化が有れば表示する
          ShiftData = dt ;
          Serial.println(dt, BIN) ;
     }
}

*************************************

シリアルモニター.jpg

タクトスイッチのSW1~SW8を順番に押した時のシリアルモニターの表示です。

起動時は、プルアップされているので「11111111」が表示されます。(スイッチはどれも押されていない)

sw1を押すと、「11111110」となり、右端が「0」になり、タクトスイッチを離すと「11111111」に戻ります。

パターンが読めたので、シリアルモニターの値から、sw1を押してる時にLED1が点灯、離すと消灯、SW2が押されている時にLED2が点灯、離すと消灯というふうにスケッチを追加します。(以下、SW8まで同じ)

**********************************

#define MISOO 24     // データの入力ピン(74HC165-QH)
#define SCKK  23     // クロック出力ピン(74HC165-CK)
#define SLL   22     // レジスタロードピン(74HC165-SL)

byte ShiftData ;

// 74HC165のデータを読込む(受信する)関数
// DataPin :データの入力ピン
// clockPin:クロック出力ピン
// loadPin :レジスタロードピン
byte ShiftIn(int dataPin,int clockPin,int loadPin)
{
     unsigned char x ;
     int  i ;

     x = 0 ;
     digitalWrite(loadPin,LOW) ;          // 入力端子(A-H)の情報をレジスタに読込めと指示する
     digitalWrite(loadPin,HIGH) ;
     x = x | (digitalRead(dataPin) << 7) ;// H端子の内容を受信する
     for (i=6 ; i>=0 ; i--) {             // G端子~A端子まで繰り返す
          digitalWrite(clockPin,HIGH) ;         // 1ビットシフト指示を出す
          digitalWrite(clockPin,LOW) ;
          x = x | (digitalRead(dataPin) << i) ; // シフトされた内容を受信する
     }
     return x ;
}
// 電源起動時とリセットの時だけのみ処理する関数
void setup() {
     // シリアル通信の初期化
     Serial.begin(9600) ;
     // 74HC165のピン情報初期化
     pinMode(MISOO, INPUT) ;
     pinMode(SCKK,  OUTPUT) ;
     pinMode(SLL,   OUTPUT) ;
     pinMode(28,   OUTPUT) ;
     pinMode(29,   OUTPUT) ;
     pinMode(30,   OUTPUT) ;
     pinMode(31,   OUTPUT) ;
     pinMode(32,   OUTPUT) ;
     pinMode(33,   OUTPUT) ;
     pinMode(34,   OUTPUT) ;
     pinMode(35,   OUTPUT) ;
    
     digitalWrite(SLL,HIGH) ;
     digitalWrite(SCKK,LOW);
     // 3秒後に開始
     delay(3000) ;
     // 74HC165入力端子のデータを読込み表示を行う
     ShiftData = ShiftIn(MISOO,SCKK,SLL) ;
     Serial.println(ShiftData, BIN);
}
// 繰り返し実行されるメインの処理関数
void loop() {
     byte dt ;

     // 74HC165入力端子のデータを読込む
     dt = ShiftIn(MISOO,SCKK,SLL) ;
     if ( dt != ShiftData ) {
          // データに変化が有れば表示する
          ShiftData = dt ;
          Serial.println(dt, BIN) ;
     }
       
      if(dt==B11111110){
         digitalWrite(28,HIGH) ;
      }
      if(dt==B11111111){
         digitalWrite(28,LOW) ;
     }
     if(dt==B11111101){
         digitalWrite(29,HIGH) ;
      }
      if(dt==B11111111){
         digitalWrite(29,LOW) ;
     }
     if(dt==B11111011){
         digitalWrite(30,HIGH) ;
      }
      if(dt==B11111111){
         digitalWrite(30,LOW) ;
     }
      if(dt==B11110111){
         digitalWrite(31,HIGH) ;
      }
      if(dt==B11111111){
         digitalWrite(31,LOW) ;
     }
     if(dt==B11101111){
         digitalWrite(32,HIGH) ;
      }
      if(dt==B11111111){
         digitalWrite(32,LOW) ;
     }
     if(dt==B11011111){
         digitalWrite(33,HIGH) ;
      }
      if(dt==B11111111){
         digitalWrite(33,LOW) ;
     }
     if(dt==B10111111){
         digitalWrite(34,HIGH) ;
      }
      if(dt==B11111111){
         digitalWrite(34,LOW) ;
     }
     if(dt==B1111111){
         digitalWrite(35,HIGH) ;
      }
      if(dt==B11111111){
         digitalWrite(35,LOW) ;
     }
}

*************************************

タクトスイッチを順番に押すと対応するLEDが点灯する動画です。

これで、タクトスイッチの代わりにセンサーからの入力を任意のデジタルピンから出力出来るようになりました。


タグ:鉄道模型
コメント(2)  トラックバック(0) 
共通テーマ:趣味・カルチャー

Arduinoによる自動運転への道 その4 [Arduino]

 <注意>
この記事は、PWMピンを使った、デジタルピンの増設になります。

自動運転を目指す上で、PWM出力ピンとアナログ入力ピンを増やせないことには先には進めません。

実験線では、PWM出力20本、アナログ入力ピンは24本必要です。

信号機は三灯式になるので、デジタルピンは72本も必要なんでけどね。(^^ゞ

手始めに、TC74HC595を使ってPWM出力ピンを増やします。

シフト回路図.jpg

Arduino MEGAの2・3・4番ピンを使いました。

P1050505.JPG

***********************************

int latchPin = 3;  // TC74HC595のRCKへ
int clockPin = 4; // TC74HC595のSCKへ
int dataPin = 2;  // TC74HC595のSIへ

void setup() {
  pinMode(latchPin, OUTPUT);
  pinMode(clockPin, OUTPUT);
  pinMode(dataPin, OUTPUT);
}

void loop() {
    digitalWrite(latchPin, LOW);
     shiftOut(dataPin, clockPin, MSBFIRST, 1);  //数値を変えることで出力ピンが変わる
    digitalWrite(latchPin, HIGH);  // 送信終了後latchPinをHIGHにする
    delay(500);
 
}

*****************************************

15行目の「1」でLED1のみ点灯します。
(TC74HC595のQAピン(15番ピン)から5Vが出力されます)

以下、
「2」で、LED2(QBピン(1番ピン))
「4」で、LED3(QCピン(2番ピン))
「8」で、LED4(QDピン(3番ピン))
「16」で、LED5(QEピン(4番ピン))
「32」で、LED6(QFピン(5番ピン))
「64」で、LED7(QGピン(6番ピン))
「128」で、LED8(QHピン(7番ピン))

と、なります。

上記以外の数値を入れると複数のLEDが点灯します。

ちなみに、「255」ですと全LEDが点灯します。

なんでそうなるかというと、

点灯パターン.jpg

「shiftOut(dataPin, clockPin, MSBFIRST, 1);  」と、命令すると、LED1に繋がるQAピンのみ「1」になります。(QAピンから5V出力される)

各出力ピンの状態は、「00000001」(2進数)となり、それを10進数に変換すると「1」ってことです。

「3」と入れると、2進数に変換すると「00000011」となり、LED3が点灯しないで、LED1とLED2が点灯するわけです。

複数のLEDを1命令で制御出来るのは、信号機のLED制御では役立ちますね。

デジタルピンも同じやり方で出力ピンを増やすことが出来ます。

次回は、アナログ入力ピンを増やします。


タグ:鉄道模型
コメント(4)  トラックバック(0) 
共通テーマ:趣味・カルチャー

Arduinoによる自動運転への道 その3 [Arduino]

自動運転構想3.jpg

前記事の実験で、ギャップ1区間にPWMピンは2本必要になります。

この実験線のギャップ区間は10区間です。

Arduino MEGA 2560 R3の入出力ピンは豊富とはいえ、PWM出力に使えるピンは15本です。

う~~~~~~ん、5本足りない。(^^ゞ

シフトレジスタを使えば増やせるらしいのですが、読んでもちんぷんかんぷんです。

ここなんて、漢字やひらがなが出てこなく、ローマ字ばかりです。(^^ゞ

ここが丁寧に解説されているのですが、とても難解です。(^^ゞ(^^ゞ(^^ゞ

74HC595を入手して、あれやこれややってみないと分かりませんね。

急場しのぎとして、増設とは違うのですが、出力ピンを切り換える方法を思いついたので書いておきます。

PWMピン増設.jpg

DIGITALピンを余計に1本消費するのですが、使ってない区間のPWM出力を他の区間に回せます。

スケッチで、DIGITALピンを「higt」を追加すればリレーが切り替わってB区間にPWM2番、3番ピンの出力が回せます。
(A区間と同時は無理ですよ)

「使いまわし法」とでもしておきましょう。

センサーも多く使うのでアナログピンが不足するのは目に見えてます。(実験線で24本必要)

アナデジ.jpg

こうすると、センサー出力をデジタルピン入力で扱えます。

「アナデジ変換法」とでもしておきましょうか。

こんなことを考えるのは楽しいものです。


タグ:鉄道模型
コメント(2)  トラックバック(0) 
共通テーマ:趣味・カルチャー

Arduinoによる自動運転への道 その2 [Arduino]

 Arduinoは外部電源に12Vを使っても、各ピンからの出力は5Vのままです。

5VではNゲージは動きませんので、モータードライバICで5Vを12V出力にします。

モータードライバ2.jpg

モータードライバICとArduinoの配線はこうなります。

前進は、PWM2ピンから5V出力されると、レール1へ12Vプラス、レール2がマイナスです。
(PWM3ピンは0V)

後進は、PWM3ピンから5V出力されると、レール2へ12Vプラス、レール1がマイナスです。(PWM2ピンは0V)

停止は、PWM2ピン、3ピンとも0Vです。

往復運転をさせてみます。

部屋が散らかっているのは気にしないでください。(^^;

それより気にして欲しいのは、行きも帰りも同じ動きさせているのですが、発車位置を大きくオーバーランしてしまいます。

なんでやろ?

家が傾いているのでしょうか・・・・(^^;

int p1 = 2; //正転時のピン
int p2 = 3; //逆転時のピン

void start() //発車
{
   analogWrite(p2,LOW);
   int i; //ここから9行目までで加速操作
  for (i = 20; i < 30; i++) {
    analogWrite(p1, i);
    delay(200);
    analogWrite(p1, LOW);
    }
}

void teisoku() //加速後のスピードを維持
{
   analogWrite(p1,30);
   analogWrite(p2,LOW);
   delay(5000); //ここでA区間を抜けきるまでの時間調整
 }

void stop() //停止
{
   digitalWrite(p1,LOW);
   digitalWrite(p2,LOW);
 }

void setup()
 {
   pinMode(p1,OUTPUT);
   pinMode(p2,OUTPUT);
   start(); //発車
     teisoku(); //定速
       stop();//停止
     
delay(5000); //往路停止後5秒間待ち

p1=3;                //レールの極性反転
p2=2;                //レールの極性反転
 start(); //発車
   teisoku(); //定速
    stop();//停止
 }

void loop()
 {
  }

<追記>
車両を前後入れ替えてやってみたところ、まったく逆でした。
どうも車両の動力の問題みたいですね。

 

タグ:鉄道模型
コメント(2)  トラックバック(0) 
共通テーマ:趣味・カルチャー

Arduinoによる自動運転への道 その1 [Arduino]

このシリーズは長くなりそうですよ。(^^;

モータードライバICが到着しましたので、実験線による自動運転を目指してまいります。

まずは「発車モード」をスケッチします。

P1050460.JPG

実験線でプログラムを試していくと、暴走する危険があるのでLEDの点灯で動きを確認して行きます。

PWM2番と4番ピンに2色LEDを挿しています。
(4番ピンはまだ使いません。)

出力特性2.jpg

停止から設定速度まで加速、その後設定速度を維持し、A区間を抜けたらOFFにしたいものです。

ArduinoのPWM出力を使います。

発車スケッチ1.jpg

10~13行目で段々とPWM出力を上げていきます。

変数「i」は13行目の「delay(500);」で0.5秒ごとに2番ピンからのPWM出力を0から50まで25秒掛けて段々上がって行きます。
(500ミリ秒=0.5秒)
(0.5秒x50回=25秒)

これを実行すると、

徐々にPWM出力が上がってLEDが明るくなって行きますが、明るさが50まで行くとそのまま点灯状態です。

グラフの「teisoku」の部分がが延々と続いた状態になってますね。

発車スケッチ2.jpg

14行目を足して、PWM出力を0にして消してみます。

今度は消えたのですが、グラフの「start」部分で終わってしまいました。

25秒でグラフのB区間に車両が入っていれば問題はないのですが、これだとA区間の長さを自由に設定出来ません。

発車スケッチ3.jpg
さらに14~16行目を追加して、50の明るさになってから、5秒間維持したのち、PWM出力を0にします。



訳わからん動きになってしまいました。(^^;

これのまま進んでも埒が明きませんので、違う方向から考えなおしです。

ネットで調べていくうちに、一つ一つを関数にすることを思いつきました。

int p1 = 2; //正転時のピン
int p2 = 4; //逆転時のピン

void start() //発車
{
   int i; //ここから9行目までで加速操作
  for (i = 0; i < 50; i++) {
    analogWrite(p1, i);
    delay(500);
    analogWrite(p1, 0);
    }
}

void teisoku() //加速後のスピードを維持
{
   analogWrite(p1,50);
   delay(1000); //ここでA区間を抜けきるまでの時間調整
 }

void stop() //停止
{
   digitalWrite(p1,LOW);
   digitalWrite(p2,LOW);
 }

void setup()
 {
   pinMode(p1,OUTPUT);
   pinMode(p2,OUTPUT);
   start(); //発車
   teisoku(); //定速
   stop();//停止
 }

void loop()
 {
  }

分かりやすいように、「teisoku」を実行する部分は、
LEDが最大輝度で1秒間光るように書いてます。
実行してみます。

希望通りの動きをしてくれました。

加速度や「teisoku」区間の長さの調整も自在に調整できます。

「発車モード」が出来たので、「停車モード」は逆パターンにするだけです。

他のモードは簡単なので、いよいよモータードライバICを使った実験線で車両を動かして行きます。


タグ:鉄道模型
コメント(4)  トラックバック(0) 
共通テーマ:趣味・カルチャー

Arduinoは、いいんでね~の その8 [Arduino]

実験線3.jpg

前記事の実験線はやめて、エンドレス仕様に変更になりました。

これでないと、追い抜きが出来ませんからね。

センサーや信号機の数が・・・・(^^ゞ

A駅のスイッチバックのポイントのギャップなのですが、ここは「徐行モード」を追加しますのでギャップを切りました。

坪尻駅のスイッチバックは、のんびりした風情が欠かせませんからね。

さらにB駅で特急の通過がありますので、「走行モード」より速い「特急モード」と「発車モード」と走行モード」の繋ぎに「加速モード」を追加します。

モータードライバICが来ないことには先には進めませんが、Arduino MEGA 2560 R3は、1枚では足りなそう~。(^^ゞ


タグ:鉄道模型
コメント(3)  トラックバック(0) 
共通テーマ:趣味・カルチャー

Arduinoは、いいんでね~の その7 [Arduino]

実験線2.jpg

Arduinoを使う目処が立ったので、上記の実験線を作って、いろいろなパターン運転を自動でさせてみたいと思います。

今年はこの実験で終わりそうですね。(^^;

みなさま、良いお年を~♪


タグ:鉄道模型
コメント(2)  トラックバック(0) 
共通テーマ:趣味・カルチャー

Arduinoは、いいんでね~の その6 [Arduino]

前記事で、簡単なワンショット出力が出来ないArduinoくん。

スケッチを変更してみました。

ワンショット3.jpg

ええ、loop内では永遠に繰り返しになってしまうので、setup内に書いてみただけです。(^^;

いいのか悪いのか分かりませんが、結果至上主義です。(^^)v

でもこれ1回こっきりしか実行されませんのでご注意ください。


タグ:鉄道模型
コメント(0)  トラックバック(0) 
共通テーマ:趣味・カルチャー

Arduinoは、いいんでね~の その5 [Arduino]

PECOポイントの制御をArduinoでやってみようと思います。

PECOポイントマシンの適正電圧とコンデンサ容量の実証実験」を覚えているでしょうか?

19V電源と電解コンデンサ、トグルスイッチでポイントマシンを駆動させましたが、12V電源とモーメンタリのスイッチだけでも切り換えが出来ます。

モーメンタリ.jpg
この場合、切り換えスイッチは一瞬ONにしたらすぐにOFFに戻すようにしないと、コイルが焼け切れてしまいます。

手を離すとトグルスイッチのレバーは中立に戻ってしまうので、開通方向をレバーの倒れ方で判断することができません。

この方法をArduinoでやってみようと思いました。

P1050456.JPG

ArduinoのDigitalピン(52番)から1秒間だけ出力して、LEDを点灯そして消灯させます。

ワンショット.jpg

さっそく動かしてみましょう。

点灯したままで消灯してくれません。(^^ゞ

はて?どこを間違えたのでしょうか?

間違いはないのです。

Arduinoは忠実にプログラム通りに動いているのです。

目には見えませんが、9行目で消灯して、すぐさま7行目を実行してしまいます。

6行目のループ関数で延々と繰り返してしまいます。

Arduinoではループ関数の中でプログラムを書かないとコンパイルエラーを起こしてしまいます。

Arduinoの特徴といえばそれまでですが、これは困りました。(^^ゞ

こんな簡単なことをやるのに、一筋縄ではいかないArduinoなのです。

雲1つない快晴の空に、いつのまにか暗雲が・・・・・

<追記>
その後、「単線自動閉塞」で大きな関門になっていくのでした。(-_-;)


タグ:鉄道模型
コメント(4)  トラックバック(0) 
共通テーマ:趣味・カルチャー