【Raspberry Pi Pico入門 – 4】スイッチのON/OFFを検出

2023年12月3日Raspberry Pi Pico入門,基本編Raspberry Pi Pico

概要

タクトスイッチを使用して、スイッチが押されているかどうかを判断する回路を組んでみます。

実行環境

IDE:Arduino IDE 2.1.1
MCU:Raspberry Pi Pico

今回のテーマ

  • GPIO入力を学ぶ

回路

図のようにブレッドボードとスイッチを配線します。抵抗は3.3kΩ~10kΩのものを使用します。

コーディング

新しくスケッチを作成し、以下の内容をコピペしてください。

const int SW_PIN = 16;

void setup() {
  Serial.begin(115200);
  pinMode(SW_PIN, INPUT);
  pinMode(LED_BUILTIN, OUTPUT);
}

void loop() {
  if (digitalRead(SW_PIN) == LOW) {
    digitalWrite(LED_BUILTIN, HIGH);
  } else {
    digitalWrite(LED_BUILTIN, LOW);
  }
}

動作確認

スイッチを押したときにRaspberry Pi PicoのLEDが点灯すれば成功です。

解説

デジタルとアナログの違い

今回から回路の電圧を意識することになるので、電子回路におけるデジタル回路とアナログ回路の違いを整理します。

  • デジタル回路
    High、Lowの2種類の電圧だけを使用して回路を作っていきます。HighはICやマイコンの電源電圧を使うことが多く、Lowは0Vを使う場合がほとんどです。High/Lowの組み合わせやタイミングよく切り替えることで、モールス信号のように部品同士を通信させて機能を実装していきます。このような信号を「デジタル信号」と呼びます。
  • アナログ回路
    絶えず変化する電圧を取り扱う回路です。センサーのほとんどは反応すると電圧が変化するものがおおく、電圧が高いか低いかの2択ではなく何ボルトが出力されているかを扱います。このような信号を「アナログ信号」と呼びます。デジタル信号以外はすべてアナログ信号との認識でOK。
    例えばマイクの場合、無音の時は一定の電圧を出力しますが、周囲で音が鳴るとそれに応じて電圧が変化します。

プルアップ抵抗とは

回路図は以下になります。
GP16はHigh/Lowを読み取る機能がついています。ただ、スイッチは「電気を流す/流さない」を切り替える部品なので単体で電圧を変化させる機能はありません。
そこで「プルアップ抵抗」というものを追加します。これが無い場合、スイッチを押していない時はGP16がどこにも繋がっていないことになるので電圧が決まりません。(この状態を「電圧が不定」といいます)このような状態だと基本的には0Vで、周囲のノイズ等に応じて電圧がフラフラとした状態となります。

プルアップ抵抗を使って+3.3Vに接続すると、スイッチを押されていない時の電圧を+3.3Vに固定することが出来ます。(逆に0Vに接続する抵抗をプルダウン抵抗と呼びます)
これを 等価回路 で表すと以下のようになります。
※空気の抵抗値は1TΩ~100TΩですが、ソフトの仕様で書けないので便宜的に1GΩにしています。

これを 分圧の法則 に当てはめるとGP16の電圧は約3.3Vになります。
$$V=\frac{1000000000}{3300+1000000000}\times3.3=3.299≒3.3[V]$$

また、スイッチが押されるとGND(0V)に接続され、GP16の電圧はほぼ0Vとなります。このときの 等価回路 は以下となります。
※銅線の抵抗値は太さ1mm・長さ10cmで約0.0005Ωと、ほぼ0Ωとみなすことが出来ます。

これを 分圧の法則 に当てはめるとGP16の電圧は0Vになります。

$$V=\frac{0}{3300+0}\times3.3=0[V]$$

プルアップ抵抗の選定

プルアップ抵抗は回路に流れる電流をどれくらいにするかを基準にして選定します。
Raspberry Pi PicoのGPIO入力の抵抗値は数MΩなので、スイッチを押していない時には電流はほぼ0Aで、スイッチを押したときはプルアップ抵抗を通してGNDに電流が流れることになります。
この電流値をいくつくらいにするかの説明はかなり長くなるので割愛します。基本的には0.1~2mA程度に設定することが多いです。

プルアップとプルダウンの違い

今回の回路ではプルアップで電圧を確定させましたが、他にも「プルダウン抵抗」を付ける方法もあります。
回路図では以下のようになります。

今回のようにマイコンの入力端子をプルアップ/プルダウンする場合は基本的にどちらでも問題ありません。
それぞれの違いは以下になります。

プルアップ

  • 入力端子の電圧はOFFでHigh、ONでLowとなり、論理が反転するのでプログラムがややわかりにくくなる
  • マイコンの内蔵プルアップ抵抗を使うことで部品点数を減らすことが出来る
  • トランジスタ駆動に置き換えるときはNPNトランジスタを使う

プルダウン

  • 入力端子の電圧はOFFでLow、ONでHighとなり、論理が反転しないプログラムがわかりやすい
  • 内蔵プルダウン抵抗があるマイコンはほとんどないので必ず抵抗が必要になる
  • トランジスタ駆動に置き換えるときはPNPトランジスタを使う

マイコンを使う回路ではプルダウンが選ばれることが多いです。
理由を説明しているサイトが見つからなかったので個人的な意見になりますが、プルアップで設計したほうが回路的なメリットが大きいことが多いです。

  • 実際にプリント基板を作る際、ノイズ対策等の観点でGNDは基板全体に引き回すことになります。なのでマイコンの近くでマイコンの電源にプルアップしておけば、スイッチはマイコンの入力端子と近くにあるGNDに接続するだけで済むので配線は1本です。
    逆にプルダウンで設計した場合、スイッチのある場所まで3.3Vを引っ張っていかないといけないので、配線は2本になってしまいます。
  • スイッチの配線を誤ってショートさせてしまった際、プルアップであれば3.3Vのすぐ後にプルアップ抵抗があるので、電流値は1mA程度しか流れず被害を最小限に食い止められます。しかしプルダウンの場合は3.3Vから抵抗を介さずに直接配線しているので、GNDや金属部分に触れると大電流が流れてしまう危険性があります。

回路シミュレーション

ここまで解説した内容を実際に触って確認できるよう、シミュレーションを用意しました。
↓このリンク先にシミュレーション用の回路を作りました。

回路シミュレーション

コードの解説

今回のコードで新しく出てきた関数を解説します。

  • digitalRead()
    ピンに印可されている電圧がHighかLowかを返す関数です。Arduino IDEでは「HIGH=1」「LOW=0」と定義されており、digitalRead()の返り値は1か0となります。