PR

arduino nano everyの複数ピンの入力状態を1行で確認する方法【IN】

arduino-nano-every-IN

さて、今日はarduino nano everyの入力ピンを一気に確認する方法です。

ピンの入力状態を調べる方法として有名なのがdigitalReadですよね。

ただ、このdigitalRead使う場合、

入力状態を確認できるのは1つのピンだけですよね?

今回紹介する方法だと、なんと複数ピンの状態を1行で確認することができます。

Arduinoの標準の方法では残念ながらできません。

atmega4809[AVR]のマイコンとして扱っていきます。

Arduino nano every の出力ピンを、

同時に複数出力指示する方法については

こちらの記事で紹介していますのでご覧ください。

↓↓↓↓

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

自己紹介

サラリーマンしてます。

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

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

2022年5月に転職。現役バリバリの技術者です。
現在は超大手企業の新規事業分野で装置の研究・開発をしています。

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

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

注意

本ブログはアフィリエイトを用いた広告を掲載しています。

今回使用するもの。

今回使用するのは以下の3つです。

  • arduino nano every
  • ブレッドボード
  • スイッチ類

arduino nano every

こちらはマイコンボード本体ですね。

今回紹介するのはatmega4809を搭載している、

Arduino nano everyでしか適用できません。

Arduino UNOなんかでやっても動作しないので気をつけましょう。

ちなみにAmazonでも購入できますので、

現在の値段を確認してみましょう。もしかしたら値下がりしているかも….

↓↓↓↓

ブレッドボード

Arduino nano everyはピンヘッダが飛び出ているタイプのArduinoですから、

ブレッドボードに挿して使用しましょう。

そんなブレッドボードですが、

以前わたしがAmazonで購入した激安品で失敗しているので、

念のためもう一度ご紹介します。

安物ブレッドボードで失敗した話

結論から言うと、安いブレッドボードはやめておいたほうが良いです。

ちゃんとしたメーカーもブレッドボードを使用しましょう。

サンハヤト製ならまず間違いないです。

↓↓↓↓

スイッチ類

これは今回各pinの状態を確認したいので、

pinの状態を人の手で変化させるために使用します。

もちろんジャンパーワイヤーで直接GNDに落として確認する。

なんて方法もありますが、ミスってショートさせて

Arduinoを破壊する危険性もありますから、スイッチ類は使用しましょう。

モーメンタリスイッチでも、オルタネイトでも問題ありません。

こんな感じでお手頃価格でセットになっていますから、

こういったものを購入してみるのもいいかもしれないです。

↓↓↓↓

Arduino nano every をatmega4809として扱う。

さて、GPIOのピンの入出力操作については先ほど紹介した記事で書いていますが、

実際IN/OUTの制御ができたら今度は、

各PINの状態も知りたくなりますよね?

例えばD12ピンは今HIGHなのか?

それとも今LOWなのか?

みたいな感じです。センサーやスイッチなんかをトリガーにして

次の動作をさせるときには必ず必要になります。

ぜひマスターしてください。

一般的にはArduinoで各pinの状態を取得するには、

digitalReadを使用するのが一般的かと思いますが、

今回はAVRのマイコン、atmega4809として使用しますから、

digitalReadは一切使用しません。

atmega4809の入力状態を参照する方法。

それでは具体的に各ピンの入力状態を確認してみましょう。

今回使用するのは、前回使用したportAの0番と1番です。

順番に説明していきましょう。

  • portAの0番、1番ピンを入力pinに指定する。
  • portAの0番、1番ピンの状態を1行で取得する。

こんな流れになります。

それでは解説していきます。

portAの0番、1番ピンを入力pinに指定する。

仕様するのはDIRです。

このレジスタを変化させることによって、

出力用のpinなのか、入力用のpinなのかを変更可能です。

今回はportAの0番ピンと1番ピンを入力にします。

出力に指定する場合はビットを立て、

入力に指定する場合はビットを落とします。

ですから今回は、0b00とするわけです。

portAの0番、1番ピンの状態を1行で取得する。

次にpinの状態を取得する方法ですが、

使用するのは、INというAVRのレジスタです。

portAの状態をINを使って調べます。

具体的には、PORTA.IN

これでportAの全pinの状態が取得できます。

注意点としては、何も接続していないpinの状態を読み取ると、

何も接続されておらず、LOWでもHIGHでもない状態となり、

不安定な値を出します。

これは通常のdigitalReadの時も同様ですので、

INを使えば何もつながなくていいわけではないです。

Arduinoの公式の説明でもそのことが書いてあります。

Notes and Warnings

If the pin isn’t connected to anything, digitalRead() can return either HIGH or LOW (and this can change randomly).

arduino公式refarenceより

具体的にatmega4809の入力状態確認してみる。

では実際に入力状態を確認していきましょう。

スイッチの配線もあるので、

まずは配線方法を紹介していきます。

配線方法

配線はこのようにします。

↓↓↓

arduino-nano-every-input
arduino nano every で複数のinputを同時に確認する配線

スイッチ類は、何も接続されていない状態だと、

「各pinが不安定になる。」という説明をしましたが、

その対策として5Vと抵抗を使用してプルアップしています。

スイッチが押される前はプルアップされたほうに電気が流れ、

スイッチが押されるとGNDに落ちる仕組みです。

実際やってみるとわかりますが、

このプルアップ抵抗をつけないと、ほんとに入力状態が

HIGHになったりLOWになったりでランダムになります。

必ずプルアップはしておきましょう。

スケッチ

では配線も済んだので、

ここからはスケッチ(Arduinoに書き込むプログラム)の説明をします。

まずはいきなり全コードを貼っておきます。

void setup(){
    PORTA.DIR |= 0b00;
    Serial.begin(9600);
  }
void loop(){
    int nowstatus = PORTA.IN;
    delay(1000);
    int pa0Status = (nowstatus & 0b01);
    int pa1Status = (nowstatus>>1 & 0b01);
    Serial.print("AllRegister:");
    Serial.println(nowstatus);
    Serial.print("PA0Status:");
    Serial.println(pa0Status);
    Serial.print("PA1Status:");
    Serial.println(pa1Status);
}

ポイントとなるところを解説していきます。

スケッチのポイント①:DIR

先ほど少し説明しましたが、DIRは

各ピンを出力ピンにするか、入力ピンにするかを指定します。

Arduino言語で言うところのpinModeと似たようなものです。

ただし、このDIRでは、PORTAすべて。つまり、

PORTA0~7まですべてを指定することになります。

pinModeでは1つずつピン番号を引数に入れて、

出力なのか入力なのか指定しますが、DIRは

一気に指定するところが異なるところです。

具体的な使い方は、

8bitのレジスタで、

1bit目がPORTA0に対応しており、

8bit目がPORTA7に対応しています。

bitを立てる。つまり1にするとそこのピンは出力ピンに指定されます。

今回はPORTA0とPORTA1しか使用しません。

ピンのモードも入力として使用しますから、

PORTA.DIR |= 0b00;

これで十分ということですね。

スケッチのポイント②:IN

今回の主役のINです。

実際使用するときは、何か変数に置いたほうが使いやすいです。

int nowstatus = PORTA.IN;

このように記述することにより、nowstatusという変数のなかに、

現在のPORTAの各ピンの状態が10進数で格納されます。

イメージとしては、各ピンの状態がビットが立っていれば⇒HIGH

ビットが立っていなければ⇒LOWみたいな感じのほうがわかりやすいのですが、

標準では10進数で帰ってきます。

Stringを使用して、Serial.printの時だけStringを使用することで、

0or1で表示させることも可能です。

具体的には、

void setup(){
    PORTA.DIR |= 0b00;
    Serial.begin(9600);
  }
void loop(){
     int nowstatus = PORTA.IN;
    delay(1000);
    String nowstatusS = String(nowstatus,BIN);
    int pa0Status = (nowstatus & 0b01);
    int pa1Status = (nowstatus>>1 & 0b01);
    Serial.print("AllRegister:");
    Serial.println(nowstatusS );
    Serial.print("PA0Status:");
    Serial.println(pa0Status);
    Serial.print("PA1Status:");
    Serial.println(pa1Status);
}

このように変更することで、printされるときに2進数で表示されます。

スケッチのポイント③:ビット演算

PORTAのpin0とpin1それぞれの状態が確認したいわけですが、

はっきり言ってそのほかのピンは今回は必要ないわけですよね。

ただでさえ、何もつないでいないピンはHIGHになったり

LOWになったり不安定なので、

そんなところのpinの情報は不要なわけです。

ただ、先ほど紹介したINは、PORTのすべてのピンの情報を取得します。

1行で帰ってくるので便利ではありますが、

今回使用するのは2つだけ…ということで、

ビット演算をして、該当するところだけ抜き出すようにしています。

具体的にはここの部分ですね。

    int pa0Status = (nowstatus & 0b01);
    int pa1Status = (nowstatus>>1 & 0b01);

nowstatusには、portAのすべてのピンの状態が入っています。

なのでまずは0b01とANDをとることによって、1ビット目、

つまりPORTAのピン0がHIGHなのかLOWなのかを1桁の0or1で取得します。

次に、2ビット目です。

2ビット目は、1ビット右にシフトさせて、そこから0b01とANDをとることで

1桁の0or1で取得しています。

もちろん、右にビットシフトさせずに、0b10とANDをとってもできますが、

そうすると0or1ではなくなってしまい、2or0とちょっと気持ち悪いので、

今回のようにビットシフトさせています。

今回のまとめ

今回は入力側のお話でした。

ボタンを押して入力の値が変化していることが確認できれば、

実験成功となります。

ちなみに出力側は以前紹介しているので、

これでレジスタを使用したポートの入出力について解説が完成したことになります。

次回からは、もっとディープな内容についてご紹介していこうと考えています。

もうArduinoというよりAVRのマイコンの使い方の紹介になってきていますね….

コメント

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