M5StickC(ESP32)による「ELEGOO Arduino用UNO R3スターターキット」を利用したArduino入門 その4 デジタル入力

現時点の情報です。最新情報はM5StickC非公式日本語リファレンスを確認してみてください。

概要

前回はRGB LEDでした。今回は「Lesson 5 デジタル入力」になります。プッシュボタンを使ったボタン入力を説明したいと思います。

ブッシュボタンとは?

日本だとタクトスイッチと呼ぶ場合が多いです。

秋月さんだと上記みたいな商品になります。足が4本ありますが、固定のために4本あるので実際には内部でつながっていて、最低2本だけあれば用途としては問題ありません。

データシートをみたところ、上記のような回路になっていました。

色違いや、色のついたボタンを取り付けることができるものなど、いろいろなものがありますので、用途とサイズに合わせて選ぶことができます。

(非推奨)フローティング接続(3.3V→GPIO26)

一番単純な接続が上記です。

回路図だと上記になります。3.3Vをスイッチを経由してGPIO26に入力しています。LEDの場合には抵抗を間に接続していましたが、GPIO入力は実際にはほとんど電流を流しませんので抵抗などは必要ありません。

void setup() {
  // シリアル出力の初期化
  Serial.begin(115200);
  delay(50);

  // デジタル入力モードに設定
  pinMode(26, INPUT);
}

void loop() {
  // 状態を出力して1秒ウエイト
  Serial.println(digitalRead(26));
  delay(1000);
}

こんな感じのコードになります。出力はシリアルモニターという機能を利用して確かめることができます。

Arduino IDEの場合、スケッチを転送したあとにメニューからシリアルモニタを選択してください。

上記のようのシリアル出力の表示がされます。この状態で、ボタンを押してみると1が表示され、離すと0になるのが確認できると思います。

しかし、この接続は非推奨です。フローティング接続と書いてありますが、ボタンを押していない場合にGPIO26はどこにも接続されていない状態となります。

マイコンの端子になにも接続されていない場合には、その端子に電荷とよばれる静電気のようなものが残っている場合があります。つまりたまたま残っていた電荷の値を取得しているので、実際の想定とは違う結果になる可能性があります。

void setup() {
  // シリアル出力の初期化
  Serial.begin(115200);
  delay(50);

  // アナログ入力モードに設定
  pinMode(26, ANALOG);
}

void loop() {
  // 状態を出力して1秒ウエイト
  Serial.println(analogRead(26));
  delay(1000);
}

同じ接続のまま、スケッチをアナログ入力に変えてみました。こちらのほうが結果がわかりやすいです。

アナログ入力は標準では、0(0V)から4095(3.3V)までの電圧が取得できます。スイッチを押したときには4095になっていますが、スイッチを離して端子がどこにも接続されていない場合には200前後の値になっています。

この値は端子に残っている電荷を取得していますので、実際の回路の値ではありません。今回は200前後でしたが、電荷がたまたま2000前後の場合にはデジタル入力だとHIGHにもLOWにも判定されてしまうことになります。

それでは、この問題を解決するための回路を紹介したいと思います。

プルダウン接続

フローティング接続と同じように、3.3Vからスイッチに接続しGPIO26に接続されています。今回はさらにGPIO26から10kΩの抵抗経由でGNDに接続しています。

回路図は上記のとおりになります。動作的にはスイッチがOFFのときにはGPIO26は抵抗経由でGNDに接続されています。そのためGNDレベルのLOWになります。常にGNDに接続されているのでプルダウンと表現されます。

スイッチがONのときには、GPIO26は抵抗経由でのGNDと、スイッチ経由の3.3Vの両方に接続されていることになります。このときの動作としては3.3Vから抵抗経由でGNDに直結している電圧をGPIO26で測定している形になります。

このときにGPIO36は3.3Vの入力となります。抵抗の役目ですが、3.3Vを直接GNDに直結すると電流が流れすぎてマイコンが壊れてしまうます。そのための保護としてLEDなどに比べて大きめの抵抗を入れます。

LEDは数十mAを流すことで適切な明るさで光らせるのが目的でした。今回の回路の場合には電流自体は必要ないものですので、なるべく少ないほうが好ましいです。

抵抗値については、大きすぎても小さすぎても問題が起こるので、10kΩぐらいを使うことが多いですが、気になる人は検索して調べてみてください。

プルアップ接続

3.3Vからの10kΩの抵抗経由でGPIO26に接続されています。そしてGPIO26にはスイッチ経由でGNDに接続もしています。

スイッチがOFFのときには、GPIO26には抵抗経由で3.3Vに接続されているのでHIGHになります。常に電源電圧に接続されているので、プルアップと表現されます。

スイッチがONのときには、GPIO26はGNDに直結されるのでGNDレベルのLOWになります。一方3.3Vも抵抗経由でGNDに流れてしまいます。そのため、必要のない電流ですので大きめの抵抗を入れることで、流れる量を少なくしています。

プルダウンとプルアップの使い分け

スイッチOFFスイッチON
プルダウンLOWHIGH
プルアップHIGHLOW

上記のような関係になります。見た限りプルダウンの方がスイッチの状態と同じで、素直なように思えます。

実際のところ、どちらを使ってもかまいません。端子がどこにも接続されていないフローティングの状態は好ましくありませんが、プルアップでもプルダウンでも安定した端子の状態を作り出すことができます。

しかしながら、歴史的経緯によりプルアップが好まれています。昔の機材はプルアップしか対応していないものが多かったため、現在もプルアップで接続する人が多いようです。

また、GNDはわりと回路で接続しやすい場所にあることが多く、プルアップの方が便利に使えることが多いようです。

内蔵プルダウン

実はESP32には内蔵プルダウン機能があります。内部的にプルダウン回路に接続してくれますので、上記のように接続が可能です。

void setup() {
  // シリアル出力の初期化
  Serial.begin(115200);
  delay(50);

  // 内蔵プルダウン付きデジタル入力モードに設定
  pinMode(26, INPUT_PULLDOWN);
}

void loop() {
  // 状態を出力して1秒ウエイト
  Serial.println(digitalRead(26));
  delay(1000);
}

ピンモードの設定で、プルダウンを選択することで内蔵のプルダウン回路に接続されます。

擬似的に上記のような回路になります。実際にはESP32の内部プルダウン抵抗は45kΩとのことです。

しかしながら、このプルダウンモードを使っている人はほとんどいないと思います。

内蔵プルアップ

同じように内蔵プルアップも使うことができます。配線に電源があると間違ってショートさせてしまうことがありますが、GND線であれば比較的ショートさせても安全です。

void setup() {
  // シリアル出力の初期化
  Serial.begin(115200);
  delay(50);

  // 内蔵プルアップ付きデジタル入力モードに設定
  pinMode(26, INPUT_PULLUP);
}

void loop() {
  // 状態を出力して1秒ウエイト
  Serial.println(digitalRead(26));
  delay(1000);
}

ピンモードでプルアップを指定します。プルアップの場合にはスイッチONでLOW、スイッチOFFでHIGHになりますので注意してください。

まとめ

プルアップとプルダウンの説明が主となりましたが、結構重要なことなので概要は理解しておいてください。

GPIOの復習として、上記の記事をおすすめします。

続編

コメント