HOME >> 鉄道模型工作室 > ポイントのスローアクション駆動 レバーの角度情報を取込む
Nゲージのポイントを、実際のポイントの様にスローアクションで駆動させようと挑戦しています。 ステップモータを駆動させることが出来たので、そこに出力レバーの角度情報を取込んで制御してみた。
■ 出力レバーの角度情報の取得
出力レバーの回転軸として使用している可変ボリュームから、レバーの回転角情報を読取り、制御に生かすことにしよう。 可変ボリュームは10KΩの物を使用しており、その両端をArduino の5volt出力と接続し、中間部をアナログ入力ポートのゼロ番につないでいます。 Arduinoに直接接続するのは危険なので、1KΩ程度の抵抗を挿入すべきですが、ボリュームをいっぱいに回すことは無いと判断して、抵抗を入れていません。 危険ですけどね。下の写真。
.
まず、センサとしての出力状態をチェックしました。 出力ポートをArduinoに接続せず、テスターにてその電圧を観察することにしました。 右の写真。
ステップモータは、先回のテストその2のプログラムを走らせて、最大振れ角の状態での電圧を読取りました。 下の写真。 これによって正常に電圧が出力されていることが確認できたので、アナログポートに接続し、電圧情報をシリアルモニタによって取込むことにしました。
スケッチの変更点は、
Serial.println("clockwise"); stepper1.step(STEP);
の部分を、次の様に変更した。
for (i=0;i<10;i++){ vol += analogRead(ANGLE); } vol = vol/10; Serial.println(vol); stepper1.step(STEP);
FORループを使って何度か読取ってその平均を取っていますが、これは簡単なノイズ対策です。
シリアルポートに出力されたデータを見る限り、安定したデータを出力している様でした。 この実験中に、ふと心配になったことがあります。 それは、プログラムや取り扱をミスった場合、ステップモータの回転が大きくなり、グルーと一回転してしまう恐れもあります。 すると、リンク関係が干渉して、どこかがロックし、モータ焼ける?ネジが吹っ飛ぶ?・・・・・・。 そんなパワーが無いと思いますが、このような場合でもリンク系にダメージを与えないように工夫しました。
まず、ステップモータ側のアームの中心軸がロッド面まで飛び出さないように、0.5mmのプラバンでカバーを作りました。 そしてロッドの長さを、24mm から 40mm に伸ばして、 ステップモータ側のアームがクランクアームのようにぐるぐる回っても出力がわアームと干渉しないようにしました。 最初からこのような配慮をして設計しておけばよかったのですが・・・・・・・・。
改善したロッドの状態を下に示します。
// ステップモータを使う その4 #include <Stepper.h> #define PIN1 2 #define PIN2 3 #define PIN3 4 #define PIN4 5 #define ANGLE 0 #define STEP 300 Stepper stepper1(STEP,PIN1,PIN3,PIN2,PIN4); float vol; int i; int movestep; void setup() { stepper1.setSpeed(30); pinMode(PIN1,OUTPUT); pinMode(PIN2,OUTPUT); pinMode(PIN3,OUTPUT); pinMode(PIN4,OUTPUT); pinMode(ANGLE,INPUT); Serial.begin(9600); } void loop() { int vol1 = 740; for (i=0;i<20;i++){ vol += analogRead(ANGLE); delay(1); } vol = vol/20; Serial.println(vol); movestep = (vol-vol1)/0.4; stepper1.step(movestep); digitalWrite(PIN1,LOW); digitalWrite(PIN2,LOW); digitalWrite(PIN3,LOW); digitalWrite(PIN4,LOW); delay(2000); int vol2 = 620; for (i=0;i<20;i++){ vol += analogRead(ANGLE); delay(1); } vol = vol/20; Serial.println(vol); movestep = (vol-vol2)/0.4; stepper1.step(movestep); digitalWrite(PIN1,LOW); digitalWrite(PIN2,LOW); digitalWrite(PIN3,LOW); digitalWrite(PIN4,LOW); delay(2000); }
もう一度、角度データを出力させると、300ステップにて620〜740 まで振れていました。 平均して1ステップで (740-620)/300 = 0.40 振れることになります。
■ 制御ループに組込む
出力側の情報が得られるようになったので、この情報を使ってステップモータを動かすようにします。
まず、上側と下側の目標とする値を 740 と 620 と設定します。 そして、その時の出力レバーの位置(角度)を読取り、目標との差をステップ数に換算して、モータを動かすようにしました。
入力が変化するサーボ機構ではないので、入力側と出力側を随時比較する必要がないため、このようなロジックとしました。 そこで、右の様なスケッチを記述しました。 ただし、いろいろ変更した後の記述ですが・・・・・。
このスケッチをArduinoに書込んで動かしてみました。 作動は正常に動いていましたが、ただ、不思議な現象が起こていました。 それは、最初の部分の動きが変なのです。 幾度かリセットを掛けてその後の動きを観察しましたが、やはり変です。
シリアルモニタで収集した角度データをグラフ化しました。
リセットした時の位置がどこにあっても、最初に指定した場所よりもオーバーしたところまで触れるのですが、その理由が理解できませんでした。
このデータは、ステップモータが動き出す前にアナログデータを読込んで処理していますので、AD変換処理系の不具合と考えました。 このため、delay(1) を入れたり、処理回数を降らしたり減らしたりしたのですが、効果がなかったのです。
● 改良案 1
最初の変な動きを無視することも出来るのですが、すこしこだわってみました。 サーボ機能の様に、常に目標との差を見ながら動かせばよいのですが、ここは、10ステップずつ動かして、目標との差をチェックするロジックとして見ました。
しかし、この方法は失敗でした。 300ステップ動かすところを10ステップずつに区切ったので、ステップもモータの動きはかなり遅くなってしまいました。 このため、スピードを早くさせると、今度はモータの発熱が発生しました。 手で触ると熱いと感じるほどになったのです。
まだ、チューニングの余地があったのですが、この方法をあきらめることにしました。
● 改良案 2
もとの方式に戻り、最初の挙動を容認するとして、その動きを小さくさせることにしました。 setup の部分で、50ステップずつ左右に振らせる準備運動部分を設けたのです。 ステップモータにウォーミングアップさせるのです。
stepper1.step(50); delay(500); stepper1.step(-50); delay(500);
この作戦はうまく行きました。 そして、その後は狙い通りに動くようになりました。 その様子を動画で紹介します。
■ その他の処理
レイアウトに組み込むためには、定位と反位の切り替えスイッチと制御方法などを検討する必要があります。 これは、全体の制御プログラムの中に、今回検討したウォーミングアップ部分をやはりsetup の部分にはめ込み、、右に触れる場合と左に触れる場合は関数部分として記述しておき、スイッチや自動運転指令に従って作動するようにすればよいと考えています。
また、出力レバーの動きをポイントに伝えるリンク系を作る必要がありますので、次は、この検討を実施することにします。
2022/9/27