PR

arduino nano everyで同時にGPIOピンをオンにする方法。【AVRのレジスタいじります。】

arduino-nano-every-pin-output-at-the-same-time

今回はarduinoの中でも比較的新しいarduino nano everyのお話です。

このarduino nano everyですが、当然のことながらarduinoIDEを使って開発可能です。

例えばどこかの出力ピンをONにして、接続先のLEDをチカチカさせてみたり。

ただ、複数のGPIOピンを同時に

HIGHにするって難しいですよね?

同時です。

二行に分けてdigitalWriteしたら厳密には同時ではなくなります。

そんな時どうしたらいいのかを解説していきます。

AVRのレジスタが必要になりますから、

この記事も読んでおいたほうがいいです。

↓↓↓↓

それでは張り切っていきましょう!

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

自己紹介

サラリーマンしてます。

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

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

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

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

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

注意

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

Arduino nano everyはatmega4809搭載

Arduino nano everyには、atmega4809という

マイコンが搭載されています。

Arduinoといっても、実は搭載されているマイコンが結構バラバラです。

みんな大好きArduino UNOだと328P

マウス操作やキーボード操作ができるArduino pro microやLeonardoは

32U4を搭載しています。

マイコンがバラバラなので当然、マイコン自体に送るコマンドはバラバラです。

ただ、Arduinoというマイコンボードになっているおかげで、

どのマイコンでもdigitalWriteやdigitalReadが使えるというわけです。

今回紹介するのはArduino nano everyの話なので、

atmega4809にコマンドを送っていく形になります。

ほかのマイコンを積んでいるArduinoは同じようにはできませんので注意が必要です。

atmega4809でGPIOの操作をする方法。

さて、atmega4809を直接いじる方法ですが、

実はArduinoの拡張機能でatmega4809を追加しておくと、

そのマイコン用の指令がライブラリとして読み込まれます。

ですから、実はすべてのコマンドを覚える必要はなく、

それっぽく予測変換で表示されますし、

ライブラリに飛んで、どんな関数があるのかなど見ることも可能です。

ただ、この方法はVScodeを使用しないとライブラリに飛ぶことができなかったりして

とても不便ですから、いまのうちにArduinoIDEから、

VSCodeに移行しておくことを強くオススメしておきます。

具体的な方法についてはこちらの記事で紹介していますので、

参考にしてみてください。

vscodeでarduinoを使う方法

用意するものと配線図

前提として、Arduino nano everyに搭載されているLEDを光らせるのが簡単ですが、

今回は…

ちゃんと同時にGPIOがHIGIになっているかオシロスコープで確認しますので、

外部のGPIOピンと接続されているものしか使えません。

D13ピンは出ていますが、他のRX,TXのピンなどは外部に出てきていませんから、

いっそのこと2個のLEDと抵抗を用意して光らせることにしました。

用意するもの:4つ

用意するものはこの4つです。

  • Arduino nano every 本体
  • 抵抗:1kΩ x2
  • LED:何色でもOK x2
  • ブレッドボード

冒頭でもお話した通り、今回はマイコンに直接指令をだします。

ですから、他のArduinoとは互換性はありません。

Arduino nano everyの互換品はAmazonなどで見つけることは可能ですが、

atmega4809ではなく、atmega4808だったりするので、

ちゃんと純正のArduino nano every を購入しましょう。

↓↓↓↓↓

ちなみに、いつもは互換品しか購入したことがありませんでしたが、

今回初めて純正品のArduinoを購入しました…(いまさら)。

次に抵抗です。手元にあった1kΩの抵抗を使用しますが、

基本何オームでも大丈夫です。ただ、抵抗無しは危険ですのでやめてください。

Arduinoから出せる最大電流値を超えてしまい、最悪Arduinoが壊れます。

必ず抵抗は入れましょう。

次に、LEDです。何色でも構いません。

抵抗とLEDですが、電子工作キットというのが通販サイトで販売されています。

電子部品を取り扱っている店舗が近くにない…

なんて場合には強い味方ですから、

これを機に購入してみるのもアリではないでしょうか?

↓↓↓amazonで電子工作キットを見てみる↓↓↓

https://amzn.to/3ydCG83

LEDや抵抗はバラバラで購入するより、セットになっているほうが安上がりな場合が多いです。

もちろん単品で購入することに反対はしませんが、

今後のことを考えるとセットで1つ持っておいたほうがいいと思います。

ちなみに…模型など小さいものにもつかえるミニチュアLEDなんかもあります。

この記事で紹介していますので、とにかく小さいLEDが欲しい!

という場合は参考にしてみて下さい。

配線図

配線はこんな感じです。

arduino-nano-2led
arduino nano everyとledの配線

今回使用するGPIOピンはこちらです。

使用するGPIO番号接続先
D2(PA0)LED1
D7(PA1)LED2

さて、いつも使うデジタルピンですが、

となりのカッコ書きで表示しているものがありますね?

こちらは何かというと、実はAVRでピンの指定をするときに必要な番号なんです。

arduino nano every のpinout(公式より)

たとえばD2ピンだったら、

PA0ピンがAVR上でのピンの番号ですから、

portAの0番ピンという意味になります。

いつものとおり2,7番ピンをとソースコードに書いても何も起きないので注意です。

まずは普通にdigitalWriteしてみる。

まずは一般的なArduinoの出力をHIGH/LOWにするやり方からおさらいしましょう。

Arduinoの端子のHIGH/LOWは、digitalWriteを使用します。

具体的にはこんな感じですね。

void setup()
{
    pinMode(2,OUTPUT);
    pinMode(7,OUTPUT);
}
void loop()
{
    digitalWrite(2,HIGH);
    digitalWrite(7,HIGH);
    delay(1000);
    digitalWrite(2,LOW);
    digitalWrite(7,LOW);
    delay(1000);
}

2番pinがPA0、7番pinがPA1でしたね。

今回は一般的なArduinoのコマンドを使用するのでデジタルピンの番号を使用します。

setup関数内で、pinModeで出力モードにして、

loop関数内でHIGHやLOWにしています。

もちろん普通にやると複数のpinですから2行に分かれるわけです。

見た目では同時に光っているように見えるんですよね。

実際にずれているかどうかはオシロスコープを使わないと肉眼では厳しいです。

ショート動画を作成したので参考にしてみてください。

arduinoのdigitalWriteを2行続けて書くと、同時に光っているように見えるけど、実際には若干ズレる。対策方法あり。
ArduinoのdigitalWriteを2行で書いたときのずれ。

DIRのレジスタとOUTのレジスタを使用。

さてそれではソースコードを書いていきましょう。

どんなコードを記述すればGPIOピンを複数同時にHIGHにできるかご紹介します。

きになると思いますので、早速ソースコードをお見せします。

void setup(){
    PORTA.DIR |= 0x03; // 0b00000011と同義。PA0とPA1をout出力に指定。
  }
void loop(){
    PORTA.OUT |= 0x03; // 0b00000011と同義。portAの0番、1番ピンをHIGHにする。
    delay(1000);
    PORTA.OUT &= ~0x03; // 0b00000000と同義。portAの全ピンをLOWにする。
    delay(1000);
}

こんな感じです。

流れとして、DIRで出力なのか入力なのかを定義して、

実際にOUTでHIGHにしたりLOWにしたりしています。

一行で0番ピンも1番ピンも指定しているので、

同時にLEDが光るという仕組みです。

初見ではなかなか頭に入ってこないので、もう少し詳しく解説していきます。

DIRのレジスタ書き換え作業

DIRとは、arduinoの標準ライブラリでいうところの、

pinModeです。

毎回setup関数の中でpinModeが出力なのか、入力なのか指定していましたよね?

それがDIRを使うと同じポートであれば1行で記述可能です。

今回の例で行くと、

    PORTA.DIR |= 0x03; // 0b00000011と同義。PA0とPA1をout出力に指定。

これは、pin0とpin1をout出力にしているので、

1bit目と2bit目を1にしています。ビットを立てるというやつです。

もちろん、PA3なんかも出力に設定する場合は、

0b00001011となり、0x0Bとすれば大丈夫です。

OUTのレジスタ書き換え作業

次にOUTです。

こちらは、digitalWriteに相当するものです。

digitalWriteは、一つのGPIOピンを指定してON/OFFしていましたが、

このOUTは、同じポートであれば1行でつまり同時にON/OFFが可能です。

DIRと同じく、該当するピンのビットを立ててあげればHIGHになります。

反対にビットを立ち下げる(0にする)ことで、出力を切ってLOWにできます。

実際に同時にHIGHになっているかオシロスコープで確認。

さて、この方法と先ほど紹介したdigitalWrite2行で書く場合、

それぞれの信号をオシロスコープで見てみましょう。

digitalWriteを2行続けて書いた場合の信号

arduino_digitalWrite_delay
digitalWrite2行で送った場合の信号のずれ量。

早速オシロスコープの結果ですが、

1マス2μsなので、

1回目のdigitalWriteから3μs程度遅れてから

2行目のdigitalWriteが反応していることがわかりますね。

3μsのずれなので人間の目ではまあわからないですよね…

※3μs=0.000003秒

AVRのレジスタ操作で1行で書いた場合の信号

それではAVRのレジスタをいじって、1行で記述した場合の

オシロスコープの結果をご覧ください。

arduino_AVR_synclo
AVRのレジスタを直接操作した場合。

ピッタリ一致していますね。

つまり同時に複数のpinの出力がHIGHになっていると言っていいわけですね。

今回のまとめ

今回は、Arduino nano everyを使用して、

複数pinを同時にHIGI/LOWにする方法をご紹介しました。

digitalWrite2行でそのまま記述したとしても3μsのずれ量ですから、

普通の人は気にならないと思いますが、

タイミングがシビアな制御をする場合はちょっとのずれが致命傷になりかねないです。

ということなので、同時という難しい課題については、

レジスタを直接いじることによって実現可能だよ。

という紹介でした。

コメント

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