Polivia Bot Python Raspberry Pi Pico プログラム ロボット制御 電子工作 高専3年生

【Poliviabot】【Raspberry Pi Pico】ロボット制御入門④デジタル入力とif文【Python】

本サイトでは様々な環境で気軽に本格的なロボット教育を行ってもらうべく、独自のロボット教材を開発しました。

現在、一般販売へ向けて準備をしております。

本Webページではβ版の先行体験をしていただく方向けに公開している資料になっております。

一般の方は販売をお待ちください。

前回はこちらです

1 この章の目的

この章では、PoliviaBot UMEの プッシュスイッチ入力を使って、

  1. スイッチ回路(プルダウン抵抗)の意味を理解する
  2. Pythonでスイッチ状態を読み取る
  3. if 文で「押されたら〇〇する」という判断を書けるようにする

ことを目標にします。対象はPython初心者です。

2 本章で使うピン

  • スイッチ1(SW1):GP13
  • スイッチ2(SW2):GP14

LEDは前章の通り

  • LED1:GP11、LED2:GP12
    です。

2 デジタル入力とは何か

マイコンのデジタル入力ピンは、基本的に次の2つの状態しか認識しません。

状態意味電圧の目安(Pico W)
LOW0約0V
HIGH1約3.3V

プッシュスイッチは、 電気を「つなぐ」か「切る」だけの部品です。

しかし、スイッチが押されていないとき、 マイコンの入力ピンはどこにもつながっていない状態になります。

この状態を、フローティング(浮いた状態)と呼びます。

フローティングのままにすると、

  • ノイズを拾う
  • 勝手にHIGH / LOWが変わる

といった、不安定な動作が発生します。

3 プルアップ抵抗とプルダウン抵抗

この不安定な状態を防ぐために使うのが、 プルアップ抵抗プルダウン抵抗です。

プルアップ抵抗

入力ピンを、何もしていないときは「HIGH」に引っ張っておく回路構成です。

  • スイッチOFF → HIGH
  • スイッチON → LOW

プルダウン抵抗

入力ピンを、何もしていないときは「LOW」に引っ張っておく回路構成です。

  • スイッチOFF → LOW
  • スイッチON → HIGH

これらは、ボタンが押下されていないときの入力レベルを固定する(引き下げる/引き上げる)とともに、ボタンが押下されたときに電源とGNDがショートすることを防ぐ役目があります。1k~10kΩ程度の炭素皮膜抵抗を使用することが多いです。

例えば、7番ポートにアクティブLの押しボタンスイッチを接続した場合を考えます。

  • 状態① SWが押されていないHレベル が7番ポートに入力
    • 7番ポート入力電圧V = ∞Ω / 10kΩ+∞Ω ×5V = 5V(Hレベル
  • 状態② SWが押されているLレベル が7番ポートに入力
    • 7番ポート入力電圧V= 0Ω / 10kΩ+0Ω ×5V = 0V(Lレベル

4 PoliviaBot UMEの入力回路仕様

この教材で使用するPoliviaBot UMEでは、 プッシュスイッチ入力に「プルダウン抵抗方式」を採用しています。

採用理由

  • 押していない状態を「0(LOW)」として扱える
  • プログラムの条件分岐が直感的になる
  • センサ入力との論理構成を統一しやすい

ピン割り当て

機能ピン
プッシュスイッチ1GP13
プッシュスイッチ2GP14

回路の動作

状態GP11 / GP12の電圧読み取り値
押していない約0VLOW (0)
押している約3.3VHIGH (1)

5 Pythonでスイッチを読む準備

1 ピンを「入力」として設定する

LEDのときは Pin.OUT でしたが、今回は入力なので Pin.IN です。

from machine import Pin

SW1 = Pin(13, Pin.IN)  # GP13
SW2 = Pin(14, Pin.IN)  # GP14

2 value() で読む

print(SW1.value())

押していないときは 0、押すと 1 が表示されます。

3「読めているか」確認する(whileで監視)

スイッチが反応しているかを確認します。

from machine import Pin
import time

SW1 = Pin(13, Pin.IN)

while True:
    print(SW1.value())   # 0 or 1
    time.sleep(0.2)

スイッチを扱う場合はロボットの電源をONにしないと動きませんのでご注意ください。

6 if文とは何か

if文は「条件で分ける」

if は「もし〜なら」という意味です。

基本形:

if 条件:
    条件がTrueのときだけ実行する処理

Pythonでは 条件が成り立つとき、その中が実行されます。

条件は「True / False」で決まる

例えば、

  • SW1.value() == 1 → 押されているなら True
  • SW1.value() == 0 → 押されていないなら True

というように書きます。

インデントが命

whileと同じで、字下げされた部分がifの中身です。

正しい例:

if SW1.value() == 1:
    print("押されました")

if文で「押したらLED点灯」

ここで入力(スイッチ)と出力(LED)をつなげます。

  • SW1(GP13)を押したら LED1(GP11)を点灯
  • 離したら消灯
from machine import Pin
import time

LED1 = Pin(11, Pin.OUT)
SW1  = Pin(13, Pin.IN)

while True:
    if SW1.value() == 1:     # 押された?
        LED1.value(1)        # 点灯
    else:
        LED1.value(0)        # 消灯

    time.sleep(0.01)

ここで else

「それ以外の場合」
です。

2つのスイッチで2つのLEDを操作(if / elif / else)

  • SW1 → LED1
  • SW2 → LED2
  • どちらも押されていない → 両方消灯
  • 両方押されている → 両方点灯(確認用)
from machine import Pin
import time

LED1 = Pin(11, Pin.OUT)
LED2 = Pin(12, Pin.OUT)
SW1  = Pin(13, Pin.IN)
SW2  = Pin(14, Pin.IN)

while True:
    s1 = SW1.value()
    s2 = SW2.value()

    if s1 == 1 and s2 == 1:
        LED1.value(1)
        LED2.value(1)
    elif s1 == 1:
        LED1.value(1)
        LED2.value(0)
    elif s2 == 1:
        LED1.value(0)
        LED2.value(1)
    else:
        LED1.value(0)
        LED2.value(0)

    time.sleep(0.02)

7 チャタリングとは何か

スイッチを押した瞬間、 内部の金属接点は一度で安定するわけではありません

実際には、 ON / OFF / ON / OFF... という細かい振動が、数ミリ秒発生します。

この現象を、**チャタリング(バウンス)**と呼びます。

チャタリングがあると、

  • 1回押したつもりが、何回も押されたことになる

という問題が発生します。

対策として、この教材では ソフトウェア・デバウンス(一定時間同じ状態なら確定)を使います。

デバウンス付き:SW1でLED1を制御する

  • 押されたらLED1 ON
  • 離されたらLED1 OFF
  • チャタリングがあっても安定して動く
from machine import Pin
import time

LED1 = Pin(11, Pin.OUT)   # LED1: GP11
SW1  = Pin(13, Pin.IN)    # SW1 : GP13 (pulldown -> pressed=1)

DEBOUNCE_MS = 20          # デバウンス判定時間(目安:10〜30ms)
last_read = SW1.value()   # 直近の読み取り値
stable = last_read        # 確定した安定値
last_change = time.ticks_ms()

# 初期状態を反映
LED1.value(stable)

while True:
    now = time.ticks_ms()
    reading = SW1.value()

    # 変化を検出したらタイマをリセット
    if reading != last_read:
        last_read = reading
        last_change = now

    # 一定時間同じ状態が続いたら「確定」
    if time.ticks_diff(now, last_change) >= DEBOUNCE_MS:
        if stable != last_read:
            stable = last_read
            LED1.value(stable)  # stable=1なら点灯、0なら消灯
            print("SW1 stable =", stable)

    time.sleep_ms(1)

課題 4

SW1を押したら、LED1を3回点滅させてください(for文を使う)。
※押しっぱなしで何度も反応しないように、「押した瞬間」だけ動作させること。

解答例はこちら
from machine import Pin
import time

LED1 = Pin(11, Pin.OUT)
SW1  = Pin(13, Pin.IN)

DEBOUNCE_MS = 20
last_read = SW1.value()
stable = last_read
last_change = time.ticks_ms()

prev_stable = stable  # 1つ前の確定値(押した瞬間を検出するため)

def blink3():
    for _ in range(3):
        LED1.value(1)
        time.sleep(0.2)
        LED1.value(0)
        time.sleep(0.2)

LED1.value(0)

while True:
    now = time.ticks_ms()
    reading = SW1.value()

    if reading != last_read:
        last_read = reading
        last_change = now

    if time.ticks_diff(now, last_change) >= DEBOUNCE_MS:
        if stable != last_read:
            stable = last_read

            # 押した瞬間(0→1)だけ反応
            if prev_stable == 0 and stable == 1:
                blink3()

            prev_stable = stable

    time.sleep_ms(1)

次回はこちら

Follow me!

-Polivia Bot, Python, Raspberry Pi Pico, プログラム, ロボット制御, 電子工作, 高専3年生
-, , , , ,

PAGE TOP