PR

Arduinoで自己保持的な使い方をするには…

self-hold-eyecatch

こんにちはArduinoでいろいろ最近電気工作しているホビーハッピーです。

よくPLCのラダー制御なんかである自己保持回路ってありますよね。

1回ONされたら、何か他のトリガーが入るまでずっとON

しっぱなし。みたいな回路です。

Arduinoでももちろん自己保持的な使い方をすることは可能なので、

試しにスイッチ2つ用意して自己保持っぽいことをしてみます。

今回は自作っぽい要素はほとんどなく、プログラミング重視で行きます。

この記事を読むことでわかること

Arduinoを使って自己保持回路のような使い方がマスターできる。

自己紹介

東証一部上場企業でサラリーマンしてます。

主に工場(生産現場)で使用する検査装置のアプリケーション開発してます。

ヒトの作業を自動化して簡略化するアプリケーションを日々開発中。

転職に成功して現在は超大手企業でシステム系の開発をしています。

Youtubeチャンネルにさまざまな動画を上げています

↓↓↓こちらからYoutubeチャンネルにアクセス!! ↓↓↓

実際に自己保持回路っぽく扱ってみた例

こんな感じでLED1個、抵抗200Ω、タクトスイッチ2個を用意してArduinoと接続します。

self-hold

タクトスイッチの配線方法や、使い方については、

以前記事にした内容を参考にしてくださいね。↓↓↓

動作内容としては、

スイッチ1を押したらLEDを点灯。

スイッチ1は何度押しても変化なし。
(スイッチ1を離してもLEDは点灯し続ける)

スイッチ2を押すとLED消灯。

スイッチ1を押してLEDが点灯するようにする。

通常、タクトスイッチで通電中はLEDが点灯して、

通電が切れるとLEDが消灯しますよね。(単純な電気回路の場合)

今回の自己保持回路っぽいものは、1回LEDを押すと
たとえタクトスイッチを離しても、保持してくれます。

ただ、注意点として普通にLEDをONするようにスケッチ(プログラム)に

記述するだけでは、毎回ループしてLEDをONする命令が飛びます。

LEDくらいならいいですが、モーターでこれをやると

暴走する原因になってしまいます。

ですから必要な時だけONするイメージをつけましょう。

自己保持回路に使用した回路

具体的に使用した回路をこちらに載せておきます。

ピンの番号はてきとうに変えてください。以下で紹介するスケッチ(プログラム)と

一致させておけば問題なく動きます。

13番ピンと11番ピンです。

見やすいように離していますが、もちろん隣同士で2,3番ピンを使っても大丈夫です。

ワークとしてわかりやすくするためにLEDをつけています。

このLEDは5番ピンにつながっています。

self-hold
自己保持っぽく状態を保持するための回路

どんなスケッチ(プログラム)で自己保持回路っぽくしているか

今回使用したスケッチ(プログラム)をこちらに載せておきます。

ポイントは、state(状態番号)を使用して何度もLEDのON/OFF命令を出さないようにしているところです。

  int L_switch = 13;
  int R_switch = 11;
  int LED_pin = 5;
  int state = 0;
  /*
  state 0 : L_switch wait input LED OFF
  state 1 : L_switch in LED ON R_switch wait input
  */

void setup() {  
 pinMode(L_switch,INPUT);
 pinMode(R_switch,INPUT);
 pinMode(LED_pin,OUTPUT);
 Serial.begin(9600);
}

void loop() {
  // L_switch入力待ち状態
  if(state == 0)
  {    
    // L_switchが入力されたらLEDを点灯させて次の状態1へ移行
    if(digitalRead(L_switch)==HIGH)
    {
      digitalWrite(LED_pin,HIGH);         
      state = 1;
    }    
  }
  // R_switchの入力待ち状態。一度L_switchが入力されて状態1になっていることが前提。
  if(state == 1)
  {
    if(digitalRead(R_switch)==HIGH)
    {
      digitalWrite(LED_pin,LOW);  
      state = 0;
    }
  }  
}

L_switchはその名の通り、左のタクトスイッチ。

R_switchは右のタクトスイッチ。

LED_pinはLEDとつながっているピンを指定しています。

重要なのは、stateという状態番号を置いて、それで判別させているところです。

一回目左のタクトスイッチを押す=(L_switch)がHIGHになる

すると、状態0で押されているのでLEDは点灯します。

その後、左のタクトスイッチを押しても、LEDは点灯したままです。

state = 1ですから、そもそもL_switchは監視していません。

つまり何度L_switchを押してもLEDのONは最初1回だけということになります。

しかし、右のタクトスイッチを押すことにより、

LEDが消灯します。LEDの消灯と同時にstateも0に変更されますから、

このLEDの消灯の指示も1回きりということになります。

その後、stateは0に戻っていますから、

L_switfhの監視に戻る。という感じの流れです。

簡単な電気回路では、スイッチは保持しておく必要がありますが、

このように状態の定義によって、

スイッチを保持しておく必要がなくなります。

今回の自己保持回路っぽいものの使い道

今回紹介した内容で流用できそうなアイデアを少し出しておきます。

ボタンを1回押されたら、動作完了まで押せなくしたいとき

よくあるのが、ボタンを連打して誤動作してしまうことです。

そんな時はボタン連打されても、counterを見て、「あ、もうすでに1回押されているな」

と判定できれば、連打も怖くないはずです。

そのうえで行いたい動作を完了したら、また押せるようにすればいいのです。

次の動作まで(センサーなどの入力があるまで)動作を保持しておきたいとき

あとは、モーター関係であったり、物を動かす時に便利なところです。

モーターを機械的な端(いけるところの限界)まで行ったら止める。

なんてのも可能です。

ここまで来たら限界だ。というところにセンサーをつけておいて、

実際にステージやモーターの軸がそこまで来たら今回の右のタクトスイッチのような

働きをさせてあげればいいです。

補足:センサーで止まった後の処理

 さて、センサーが反応したところでモーターを止めるのはいいのですが、
センサーが反応した後何も工夫しないと、モーターを再度動かすのが難しいです。

 理由としては、例えば近接センサーなど、物体の検知を行うセンサーの場合、
1点だけでセンサーが反応する。ということは通常ありません。
反応する幅が存在します。ですから、ここからここまではセンサーが反応しますよ。
という範囲が存在します。

 では、今回のように、センサーで反応させて、
自己保持を切った場合、どうなるか?それは、常にセンサーで
自己保持を切ってしまうので、再度動かそうとしても
動かせなくなります。

 その場合の対策方法ですが、
いくつか考えられますが、より安全なのは、
例えば、センサーがOFFになってから、ONになったことを確認したら
自己保持を切る。というやり方です。

 つまり、センサーが「ON状態」それだけが自己保持を切るトリガーではなく、
あくまでもセンサーが「OFF⇨ON」に切り替わったかを確認して、
切り替わった瞬間に自己保持を切る。
というやり方です。

 具体的にやる場合は、割り込み処理を入れるといいでしょう。
attachInterrept()という関数がArduinoには実装されています。
今回の場合だと、センサーのOFF⇨ONに反応して欲しいので、
引数にRISINGを入れてあげれば良さそうですね。

 割り込み処理については本ブログでも紹介していますので、
使い方に不安がある場合は参考にしてみてください。

自己保持回路っぽいもののまとめ

ここまでで状態を定義することで、

自己保持回路のようなものが完成したわけですが、

もちろんこのようにしてスイッチを常時監視してLEDを点灯させることは、

すぐに思いつくかと思います。

  int L_switch = 13;
  int R_switch = 11;
  int LED_pin = 5;
  int state = 0;
  /*
  state 0 : L_switch wait input LED OFF
  state 1 : L_switch in LED ON R_switch wait input
  */

void setup() {  
 pinMode(L_switch,INPUT);
 pinMode(R_switch,INPUT);
 pinMode(LED_pin,OUTPUT);
 Serial.begin(9600);
}

void loop() {
     // L_switchが入力されたら
    if(digitalRead(L_switch)==HIGH)
    {
      digitalWrite(LED_pin,HIGH); // もしこれがモーターの動作だったら...            
    }    
     // R_switchが入力されたら
    if(digitalRead(R_switch)==HIGH)
    {
      digitalWrite(LED_pin,LOW);             
    }    
       
}

ただし、連打されると何度もLEDの点灯の指示が出て嫌ですよね。

モーターの動作の指示なんかしている時は、

連打でさらに進んでしまいます。

この状態の定義によってより安全な動作が可能になります。

ぜひこの状態をうまく使いこなして安全な設計をしてみてください。

コメント

  1. 杉山樹 より:

    学校の課題研究で使用したいと思ったのですが、全て同じ通りにやってもできませんでした。

    • hobbyhappy hobbyhappy より:

      コメントありがとうございます。
      当初はフラグでの管理を考えて記事にしていましたが、状態遷移の考え方のほうが
      スッキリしますので内容を変更させていただきました。
      これで思い通りの制御になるか試してみてください。

      • 杉山樹 より:

        光るストラックアウトを作りたいので
        それに使えるアルディーノの回路を教えてください

  2. 杉山樹 より:

    自己保持回路の並列回路を作りたいので、サイトにアップしてほしいです!!!!

    • hobbyhappy hobbyhappy より:

      コメントありがとうございます。
      その後記事を変更しましたが、思い通りの動きになりましたか??

      並列回路ですか??
      ちょっと自己保持で並列回路という意味がちょっと…
      やりたいことを具体的におっしゃっていただいたほうが力になれると思います。

      • 杉山樹 より:

        ストラックアウトを作ろうと思いこのAruduinoを使った自己保持回路を使用、応用して9個ランプが対応するボタンが押された時に点灯する回路を作ろうと思ったのですが出来ませんでした

  3. 杉山樹 より:

    ストラックアウトのような、複数LEDが点灯でき、自己保持できる回路を教えてほしいです!!!

  4. 杉山樹 より:

    ストラックアウトをアルディーノを使って作りたいです。
    どうやったらいいかわからなく、困っています。9個の自己保持回路を1つのスイッチでリセットできるアルディーノ回路を教えて欲しいです。

    • hobbyhappy hobbyhappy より:

      一つの自己保持回路は記事を読んで理解している前提でお話ししますね。
      ストラックアウトということで、9個のスイッチ、リセット用に1個のスイッチ、つまり10個のスイッチということですね。そうなると、例えばステート(常態遷移)を0b000000000(0が9個でスイッチがON常態だったら1にする)に対応させてみるのはいかがでしょうか?ビットの演算については別記事で上げていますから、そちらを参考にしてみてください。時間が出来たらストラックアウトの記事も出すかもしれませんが、まずはこのアイデアで試してみて下さい。

      • 杉山樹 より:

        実際にやってみましたが出来なかったので、アルディーノの制御を実際に書いて欲しいです
        何回も頼み込んでしまい申し訳ないです。

タイトルとURLをコピーしました