【コピペ可】Raspberry Piコード集20選|モーター・表示・ゲーム・通信を初心者向けに解説

Arduino 機器制作






【コピペ可】Raspberry Piコード集20選|モーター・表示・ゲーム・通信を初心者向けに解説











AI × Raspberry Pi Prototyping — Part 1

AIとRaspberry Pi。
「動かす・表示する・遊ぶ」20種類のコード。

GPIOを使って、サーボやモーターで「動かす」、LCDや7セグメントで「表示する」、ブザーやゲームで「遊ぶ」、シリアル通信やファイル保存で「やり取りする・覚えておく」ためのPythonコードを20本集めました。AIへのプロンプトの作り方も、サーボモーター制御の実例であらためて解説します。

対象読者: Raspberry Pi初級〜中級者 対象ボード: Raspberry Pi 4 / Raspberry Pi 5(Zero 2 Wでも概ね動作) コード: 20本+解説例1本
全コードCOPY対応配線付き10歳からわかる解説スマホ最適化

01

「動かすコード」をAIに書かせる意味

センサーは「値を読むだけ」なので比較的シンプルですが、サーボモーターやDCモーター、LCDや7セグメントのような出力デバイスは、決まった手順(ライブラリの初期化、I2C・SPIの設定、PWMのタイミング)を守らないと正しく動きません。この「お作法」はライブラリのドキュメントを読めば分かりますが、量が多くて最初は大変です。AIはこうした定型部分の下書きを素早く作ってくれるので、「思いついたアイデアをすぐ動く形にする」のを助けてくれます。

Raspberry Pi本体のGPIO仕様はRaspberry Pi公式ドキュメント ↗、GPIO制御ライブラリの関数はgpiozero公式リファレンス ↗など、各ライブラリのドキュメントで最終確認してください。

  • 初期化の定型処理:AngularServo()、SMBus()などのおまじない部分
  • 状態遷移の設計:信号機やゲームのような「今どの状態か」を管理する仕組み
  • デバッグの壁打ち:モーターが動かない、表示が化けるといった症状からの原因整理
02

サーボ制御プロンプトの設計図

モーターや表示器のようなアクチュエータ系では、「ボード」「部品とGPIOピン」「動く条件・動きのパターン」「安全上の制約」を必ず伝えます。

要素 内容
ボードと制約 機種、電源、GPIO電圧 Raspberry Pi 4 / USB-C給電、GPIOは3.3Vロジック
ハードウェア アクチュエータ・入力・GPIOピン SG90サーボ(信号線=GPIO18)、押しボタン(GPIO2)
動きの条件 角度、速度、きっかけ ボタンを押すと0°→90°へゆっくり動く
非機能要件 ライブラリ指定、コメントなど gpiozeroを使用、time.sleep()でループ管理、日本語コメント付き
PROMPTRaspberry Pi 4(Raspberry Pi OS)で、SG90サーボモーター(信号線=GPIO18)と押しボタン(GPIO2、内蔵プルアップを使用)を使い、Pythonのgpiozeroライブラリで自動ドアのような動きを作ってください。ボタンを押すとサーボが0°から90°までゆっくり回転して3秒間開いたままになり、その後ゆっくり0°へ戻ります。動作中に再度ボタンを押しても割り込まれないようにし、各処理に日本語コメントを付けてください。
POINT

「どんな速さで」「どのタイミングで」「動作中に別の入力が来たらどうするか」まで指定すると、実際に組み込みやすいコードになります。

03

生成されたコード全文

プロンプトから生成した「ボタンで開閉する自動ドア風サーボ」のコードです。後半の20選とは別に、AI生成コードを読む教材として掲載しています。

auto_door_servo.py
# ボタンで開閉する自動ドア風サーボ
from gpiozero import AngularServo, Button
from time import monotonic
SERVO_PIN = 18
BUTTON_PIN = 2
CLOSED_ANGLE = 0
OPEN_ANGLE = 90
STEP_INTERVAL = 0.015   # 1度動かす間隔(秒)
HOLD_OPEN_S = 3          # 開いたまま待つ時間(秒)
servo = AngularServo(SERVO_PIN, min_angle=0, max_angle=180)
button = Button(BUTTON_PIN, pull_up=True)
# 状態は文字列で管理する(CLOSED / OPENING / HOLDING / CLOSING)
state = "CLOSED"
current_angle = CLOSED_ANGLE
last_step_time = monotonic()
hold_start_time = 0.0
servo.angle = current_angle
while True:
    now = monotonic()
    # 閉まっている時だけボタンを受け付ける(動作中は割り込ませない)
    if state == "CLOSED" and button.is_pressed:
        state = "OPENING"
        print("Door: opening")
    if state == "OPENING" and now - last_step_time >= STEP_INTERVAL:
        last_step_time = now
        current_angle += 1
        servo.angle = current_angle
        if current_angle >= OPEN_ANGLE:
            state = "HOLDING"
            hold_start_time = now
            print("Door: holding open")
    if state == "HOLDING" and now - hold_start_time >= HOLD_OPEN_S:
        state = "CLOSING"
        print("Door: closing")
    if state == "CLOSING" and now - last_step_time >= STEP_INTERVAL:
        last_step_time = now
        current_angle -= 1
        servo.angle = current_angle
        if current_angle <= CLOSED_ANGLE:
            state = "CLOSED"
            print("Door: closed")
04

コード解説:ブロック単位で読む

state = "CLOSED"
「今どの状態か」を文字列で管理する書き方です。信号機やゲームなど「段階がある動き」全般に使える考え方です。Arduinoのenumに近い役割を、Pythonでは文字列や定数で表現します。
if state == "CLOSED" and button.is_pressed:
閉まっている時しかボタンを受け付けないので、動いている途中に押しても暴走しません。
now - last_step_time >= STEP_INTERVAL
time.sleep()で全体を止めず、monotonic()で経過時間を測りながら少しずつ角度を変えることでゆっくりした動きを表現しています。Arduinoのmillis()と同じ考え方です。
servo.angle = current_angle
gpiozeroのAngularServoの基本操作です。角度(0〜180程度)を代入するだけで、内部の複雑なPWMパルス制御を隠してくれます。
05

モーター・表示系コードにありがちな落とし穴

CHECK 1

GPIOピン1本あたりの出力電流はごくわずかです。サーボやDCモーターを直接GPIOやGPIOの5Vピンにつなぐと、電圧降下で本体が再起動したり、最悪の場合は故障につながることがあります。モータードライバや外部電源を必ず用意してください。

CHECK 2

Raspberry PiのGPIOは3.3Vロジックで、Arduinoのように5Vトレラントではありません。5V専用の部品を信号線に直結すると壊れる恐れがあるため、レベル変換が必要か、3.3V対応のモジュールかを必ず確認してください。

CHECK 3

I2CやSPIを使う部品(LCD、RTC、ドットマトリクスなど)は、sudo raspi-configで該当インターフェースを有効化しないと動作しません。配線後はi2cdetect -y 1でアドレスが見えているか確認しましょう。

06

実機で検証し、対話で直す

実行した後は必ずターミナルの出力や実際の動きで確認します。「動かない」だけでなく、配線、使用モデル、部品の型番、エラーメッセージ全文をAIへ伝えると修正が早くなります。

FOLLOW-UP PROMPTRaspberry Pi 4、SG90サーボ、提示コードを使用しています。ボタンを押した直後に画面右上の電源アイコンが点滅し、動作が不安定になります(アンダーボルテージ警告)。サーボはRaspberry Pi本体の5Vピンから電源を取っており、外部電源はまだ用意していません。原因として考えられることと、コード側でできる対策を教えてください。
07

20本を実行する前の共通チェック

  • 各コードは1本ずつ別の.pyファイルとして保存し、ターミナルまたはThonnyで実行する
  • sudo raspi-configで使用するインターフェース(I2C/SPI/Serial)を有効化する
  • Raspberry Piと外部電源・モジュールのGNDを共通化する
  • サーボやDCモーターは、GPIOから直接電源を取らず、外部電源とモータードライバを使う
  • I2C部品(LCD、RTCなど)はi2cdetect -y 1でアドレスを確認する
  • 仮想環境(venv)を作ってpip installすると管理しやすい
  • 最初はターミナルに状態をprint()で表示し、動きを確認しながら調整する
LIBRARY

サーボ・LED・ボタン・DCモーター・リレーの基本操作は「gpiozero」(Raspberry Pi OSに標準搭載)、7セグは「tm1637」、LCDは「RPLCD」、ドットマトリクスは「luma.led_matrix」、シリアル通信は「pyserial」、RTCとの通信は「smbus2」をpip installで追加します。それ以外は標準ライブラリのみです。GPIO番号はすべてgpiozeroの既定であるBCM表記です。

08

コピペですぐ試せるRaspberry Piコード集20選 第1弾

すべてRaspberry Pi 4/5(多くはZero 2 Wでも動作)を想定した独立Pythonスクリプトです。今回は「動かす」「表示する」「鳴らす」「遊ぶ・伝える」の4つのテーマでまとめました。検索欄に「サーボ」「LCD」「ゲーム」「通信」などと入力すると対象コードだけに絞れます。

20 / 20件を表示
No. コード ライブラリ 難易度
01 サーボモーターを0〜180度でゆっくり往復させる gpiozero 入門
02 DCモーターをL298Nドライバで正転・逆転・速度調整 gpiozero 入門+
03 ステッピングモーター28BYJ-48をULN2003で回す gpiozero 基礎+
04 ブザーで簡単なメロディーを演奏する(オリジナル音階) gpiozero 入門
05 4桁7セグメントLED(TM1637)でカウントアップタイマー tm1637 入門+
06 16x2 I2C LCDにメッセージを表示する RPLCD 入門+
07 8x8ドットマトリクス(MAX7219)でハートマークを表示 luma.led_matrix 基礎+
08 ミニ信号機シミュレーション(赤・黄・青の状態遷移) gpiozero 入門
09 LEDが左右に流れる「ナイトライダー」風点灯 gpiozero 入門
10 ボタン早押しゲーム(反応速度を測る) gpiozero 入門+
11 LEDを使ったサイコロシミュレーター gpiozero 入門
12 じゃんけんマシン(ボタンでランダムに手を出す) gpiozero 入門+
13 カウントダウンタイマー(0になったらブザーで知らせる) tm1637 / gpiozero 入門+
14 モールス信号でメッセージをLEDとブザーで送信 gpiozero 基礎+
15 ボタンの「短押し・長押し・ダブルクリック」を判定 gpiozero 基礎+
16 2台のRaspberry PiをUART(シリアル通信)でつなぐ(送信・受信) pyserial 基礎+
17 テキストファイルにボタンを押した回数を保存し電源を切っても記憶 標準ライブラリ 基礎+
18 RTCモジュール(DS3231)で現在時刻を表示する簡易時計 smbus2 基礎+
19 リレーモジュールで豆電球や小型モーターをON/OFF制御 gpiozero 入門+
20 サーボとボタンで「自動ドア」のような開閉デモ gpiozero 基礎+
該当するコードがありません。別のキーワードで検索してください。
CODE 01

サーボモーターを0〜180度でゆっくり往復させる

角度をゆっくり増減させ、首振りのような動きを作ります。すべてのモーター工作の入り口です。

入門ライブラリ:gpiozero

必要部品

SG90などの小型サーボモーター

配線

信号線(オレンジ/黄)→GPIO18、+(赤)→5V(テストは短時間のみ、常用は外部電源推奨)、-(茶/黒)→GND

コードを表示・コピー
c01_servo_sweep.py
# サーボを0〜180度でゆっくり往復させる
from gpiozero import AngularServo
from time import sleep
SERVO_PIN = 18
STEP_INTERVAL = 0.015  # 角度を1度動かす間隔(秒)
servo = AngularServo(SERVO_PIN, min_angle=0, max_angle=180,
                      min_pulse_width=0.0005, max_pulse_width=0.0025)
angle = 0
step = 1
while True:
    servo.angle = angle
    sleep(STEP_INTERVAL)
    angle += step
    if angle >= 180 or angle <= 0:
        step = -step  # 端まで来たら向きを反転

調整ポイント:STEP_INTERVALの数字を大きくするほどゆっくり、小さくするほど速く動きます。サーボが震える時はmin_pulse_width/max_pulse_widthを部品のデータシートに合わせて調整してください。

20選の一覧へ戻る ↑

CODE 02

DCモーターをL298Nドライバで正転・逆転・速度調整

2つのピンで回転方向を決め、PWMで速さを変えます。車輪を回す工作の基本です。

入門+ライブラリ:gpiozero

必要部品

DCモーター、L298Nモータードライバモジュール、外部電源

配線

IN1→GPIO23、IN2→GPIO24、ENA→GPIO18(PWM)/L298NのGNDとRaspberry PiのGNDを共通化/モーター用電源はL298NのVCC・GNDへ

コードを表示・コピー
c02_dc_motor.py
# L298NでDCモーターの向きと速さを制御
from gpiozero import Motor
from time import sleep
motor = Motor(forward=23, backward=24, enable=18, pwm=True)
while True:
    motor.forward(0.6)   # ゆっくり正転(速度は0.0〜1.0)
    sleep(2)
    motor.stop()
    sleep(0.5)
    motor.backward(0.9)  # 速めに逆転
    sleep(2)
    motor.stop()
    sleep(0.5)

調整ポイント:DCモーターはGPIOから直接動かせません。必ずL298Nと別電源(電池など)を使い、GNDだけRaspberry Piと共通にしてください。motor.forward()の数値(0.0〜1.0)が速度です。

20選の一覧へ戻る ↑

CODE 03

ステッピングモーター28BYJ-48をULN2003で回す

指定した角度分だけ正確に回転する、位置決めが得意なモーターです。

基礎+ライブラリ:gpiozero

必要部品

28BYJ-48ステッピングモーター、ULN2003ドライバボード

配線

ULN2003のIN1〜IN4→GPIO5, GPIO6, GPIO13, GPIO19/ULN2003のVCC・GNDへ外部5V電源を推奨

コードを表示・コピー
c03_stepper.py
from gpiozero import OutputDevice
from time import sleep
PINS = (5, 6, 13, 19)
STEPS_PER_REV = 4096  # 28BYJ-48の1回転あたりステップ数(半ステップ)
outputs = [OutputDevice(p) for p in PINS]
SEQUENCE = [
    [1, 0, 0, 0],
    [1, 1, 0, 0],
    [0, 1, 0, 0],
    [0, 1, 1, 0],
    [0, 0, 1, 0],
    [0, 0, 1, 1],
    [0, 0, 0, 1],
    [1, 0, 0, 1],
]
def step(count, delay=0.0015):
    direction = 1 if count >= 0 else -1
    phases = SEQUENCE if direction == 1 else list(reversed(SEQUENCE))
    for _ in range(abs(count)):
        for phase in phases:
            for pin, value in zip(outputs, phase):
                pin.value = value
            sleep(delay)
while True:
    print("Forward 1 turn")
    step(STEPS_PER_REV)             # 1回転、正転
    sleep(1)
    print("Backward half turn")
    step(-STEPS_PER_REV // 2)        # 半回転、逆転
    sleep(1)

調整ポイント:ULN2003への配線順(IN1〜IN4)がずれると逆回転したり震えたりします。動きがおかしい時はPINSの並びを入れ替えて試してください。

20選の一覧へ戻る ↑

CODE 04

ブザーで簡単なメロディーを演奏する(オリジナル音階)

TonalBuzzerで音の高さを変え、オリジナルの短いメロディーを鳴らします。

入門ライブラリ:gpiozero

必要部品

パッシブブザー

配線

+→GPIO18、-→GND

コードを表示・コピー
c04_buzzer_melody.py
# オリジナルの短いメロディーを演奏する
from gpiozero import TonalBuzzer
from gpiozero.tones import Tone
from time import sleep
buzzer = TonalBuzzer(18)
# ドレミファソラシド(オクターブ4〜5)
notes = ["C4", "D4", "E4", "F4", "G4", "A4", "B4", "C5"]
durations = [0.3, 0.3, 0.3, 0.3, 0.3, 0.3, 0.3, 0.6]
while True:
    for note, duration in zip(notes, durations):
        buzzer.play(Tone(note))
        sleep(duration * 1.2)  # 音と音の間に少し隙間を空ける
    buzzer.stop()
    sleep(2)

調整ポイント:notes配列を変えると、自分だけのオリジナルメロディーが作れます。音がガタつく場合はsudo apt install pigpiopigpiodを起動し、gpiozeroのPinFactoryをpigpioに切り替えるとなめらかになります。既存曲のメロディーをそのまま真似ると著作権の問題が起きる場合があるため、音の並びは自分で工夫しましょう。

20選の一覧へ戻る ↑

CODE 05

4桁7セグメントLED(TM1637)でカウントアップタイマー

実行してからの経過秒数を、大きな数字表示器にカウントアップ表示します。

入門+ライブラリ:tm1637

必要部品

TM1637搭載4桁7セグメントLEDモジュール

配線

CLK→GPIO23、DIO→GPIO24、VCC→5V、GND→GND

コードを表示・コピー
c05_tm1637_countup.py
# pip install tm1637
import tm1637
from time import sleep, monotonic
CLK_PIN = 23
DIO_PIN = 24
display = tm1637.TM1637(clk=CLK_PIN, dio=DIO_PIN)
display.brightness(5)  # 0〜7
start_time = monotonic()
while True:
    elapsed_sec = int(monotonic() - start_time)
    minutes = (elapsed_sec // 60) % 100
    seconds = elapsed_sec % 60
    display.numbers(minutes, seconds, colon=True)  # 中央のコロンを点灯
    sleep(0.2)

調整ポイント:「分:秒」の形で表示しています。単純な連番表示にしたい場合はdisplay.number(elapsed_sec)に置き換えてください。

20選の一覧へ戻る ↑

CODE 06

16x2 I2C LCDにメッセージを表示する

2行×16文字の液晶に文字を出す、表示器の定番の一歩目です。

入門+ライブラリ:RPLCD

必要部品

I2Cインターフェース付き16x2キャラクターLCD

配線

SDA→GPIO2(物理3番)、SCL→GPIO3(物理5番)、VCC→5V、GND→GND

コードを表示・コピー
c06_lcd_message.py
# pip install RPLCD
# 事前に sudo raspi-config で I2C を有効化しておく
from RPLCD.i2c import CharLCD
# アドレスは0x27または0x3Fが多い(不明な場合はi2cdetect -y 1で確認)
lcd = CharLCD('PCF8574', 0x27, cols=16, rows=2)
lcd.clear()
lcd.write_string('Hello, RaspberryPi!')
lcd.crlf()
lcd.write_string('LCD Ready :)')
# 表示は固定のまま。動くコードにしたい時はここでlcd.clear()と
# 新しい表示内容を書き直す

調整ポイント:何も表示されない時はコントラスト調整用の可変抵抗(モジュール裏側)を回して調整してください。アドレスが0x27で動かない場合は0x3Fも試します。

20選の一覧へ戻る ↑

CODE 07

8x8ドットマトリクス(MAX7219)でハートマークを表示

64個の点を1個ずつON/OFFして、絵文字のような簡単な絵を表示します。

基礎+ライブラリ:luma.led_matrix

必要部品

MAX7219搭載8x8ドットマトリクスモジュール

配線

DIN→GPIO10(MOSI)、CS→GPIO8(CE0)、CLK→GPIO11(SCLK)、VCC→5V、GND→GND

コードを表示・コピー
c07_dotmatrix_heart.py
# pip install luma.led-matrix
# 事前に sudo raspi-config で SPI を有効化しておく
from luma.core.interface.serial import spi, noop
from luma.core.render import canvas
from luma.led_matrix.device import max7219
serial = spi(port=0, device=0, gpio=noop())
device = max7219(serial, cascaded=1, block_orientation=0)
device.contrast(16)
# ハート型のパターン(1行8ビット×8行)
HEART = [
    "01100110",
    "11111111",
    "11111111",
    "11111111",
    "01111110",
    "00111100",
    "00011000",
    "00000000",
]
with canvas(device) as draw:
    for y, row in enumerate(HEART):
        for x, bit in enumerate(row):
            if bit == "1":
                draw.point((x, y), fill="white")

調整ポイント:「luma.led-matrix」をpip installしてください。上下左右が反転する場合はblock_orientationの数値(0/90/-90)を変えて調整します。

20選の一覧へ戻る ↑

CODE 08

ミニ信号機シミュレーション(赤・黄・青の状態遷移)

本物の信号機のように、決まった順番と時間でLEDが切り替わります。

入門ライブラリ:gpiozero

必要部品

赤LED、黄LED、青LED、220Ω抵抗×3

配線

赤→GPIO17、黄→GPIO27、青→GPIO22(各220Ω経由でGNDへ)

コードを表示・コピー
c08_traffic_light.py
# 赤→青→黄→赤 の順で切り替わる信号機
from gpiozero import LED
from time import monotonic
red = LED(17)
yellow = LED(27)
green = LED(22)
DURATIONS = {"RED": 4, "GREEN": 3, "YELLOW": 1}
state = "RED"
state_start = monotonic()
def apply_state():
    red.value = state == "RED"
    yellow.value = state == "YELLOW"
    green.value = state == "GREEN"
while True:
    elapsed = monotonic() - state_start
    if elapsed >= DURATIONS[state]:
        state = {"RED": "GREEN", "GREEN": "YELLOW", "YELLOW": "RED"}[state]
        state_start = monotonic()
    apply_state()

調整ポイント:各色の点灯時間はDURATIONS辞書の数字(秒)を変えるだけで調整できます。歩行者用の点滅を追加するなど発展させやすい構造です。

20選の一覧へ戻る ↑

CODE 09

LEDが左右に流れる「ナイトライダー」風点灯

複数のLEDを順番に光らせ、光が左右に走っているように見せます。

入門ライブラリ:gpiozero

必要部品

LED×6、220Ω抵抗×6

配線

GPIO2, 3, 4, 17, 27, 22の6ピンに、それぞれLED→220Ω→GNDの順で接続

コードを表示・コピー
c09_knight_rider.py
# 6個のLEDが左右に往復する光の帯
from gpiozero import LEDBoard
from time import sleep
leds = LEDBoard(2, 3, 4, 17, 27, 22)
position = 0
direction = 1
while True:
    leds.value = tuple(i == position for i in range(len(leds)))
    sleep(0.08)
    position += direction
    if position >= len(leds) - 1 or position <= 0:
        direction = -direction  # 端で折り返す

調整ポイント:sleep(0.08)の数字を小さくすると流れが速くなります。同時に2〜3個点灯させたい時はvalueを計算する部分に近傍のインデックスも加えます。

20選の一覧へ戻る ↑

CODE 10

ボタン早押しゲーム(反応速度を測る)

LEDが光ってからボタンを押すまでの時間をミリ秒で測定します。

入門+ライブラリ:gpiozero

必要部品

LEDと押しボタン、220Ω抵抗

配線

LED→GPIO17(220Ω経由)/ボタン→GPIO2(内蔵プルアップ使用、反対側はGND)

コードを表示・コピー
c10_reaction_game.py
# LEDが光ってからボタンを押すまでの時間を測る
from gpiozero import LED, Button
from time import monotonic, sleep
import random
led = LED(17)
button = Button(2, pull_up=True)
while True:
    print("Get ready...")
    led.off()
    sleep(random.uniform(2, 5))  # ランダムな待ち時間でフライングを防ぐ
    led.on()
    lit_time = monotonic()
    print("GO! Press the button!")
    button.wait_for_press()
    reaction_ms = int((monotonic() - lit_time) * 1000)
    led.off()
    print(f"Reaction time: {reaction_ms} ms")
    sleep(3)

調整ポイント:random.uniform(2, 5)の範囲を変えると、待ち時間の長さを調整できます。数字が小さいほど反応が速い、というゲームです。

20選の一覧へ戻る ↑

CODE 11

LEDを使ったサイコロシミュレーター

ボタンを押すと1〜6の数字にあたるLEDパターンが一瞬光ります。

入門ライブラリ:gpiozero

必要部品

LED×6、220Ω抵抗×6、押しボタン

配線

LED×6→GPIO2, 3, 4, 17, 27, 22(各220Ω経由)/ボタン→GPIO8(内蔵プルアップ使用)

コードを表示・コピー
c11_dice.py
# ボタンを押すとサイコロの目(LED本数)がランダムに光る
from gpiozero import LEDBoard, Button
from signal import pause
import random
leds = LEDBoard(2, 3, 4, 17, 27, 22)
button = Button(8, pull_up=True)
def roll_dice():
    result = random.randint(1, 6)  # 1〜6
    leds.value = tuple(i < result for i in range(6))
    print(f"Dice: {result}")
button.when_pressed = roll_dice
pause()  # イベント待ちのままプログラムを維持する

調整ポイント:gpiozeroのwhen_pressedにはボタンが押された瞬間だけ呼ばれる関数を割り当てられます。pause()でプログラムを終了させずに待機し続けます。サイコロの目の並べ方(LEDの配置)を工夫すると本物のサイコロらしくなります。

20選の一覧へ戻る ↑

CODE 12

じゃんけんマシン(ボタンでランダムに手を出す)

ボタンを押すたびに「グー・チョキ・パー」のどれかをLEDで表示します。

入門+ライブラリ:gpiozero

必要部品

赤LED(グー)、緑LED(チョキ)、青LED(パー)、押しボタン

配線

赤→GPIO17、緑→GPIO27、青→GPIO22(各220Ω経由)/ボタン→GPIO2(内蔵プルアップ使用)

コードを表示・コピー
c12_rps.py
# ボタンを押すとグー・チョキ・パーをランダム表示
from gpiozero import LED, Button
from signal import pause
import random
rock = LED(17)
scissors = LED(27)
paper = LED(22)
button = Button(2, pull_up=True)
HAND_NAMES = ["Rock", "Scissors", "Paper"]
def show_hand():
    hand = random.randint(0, 2)  # 0:グー 1:チョキ 2:パー
    rock.value = hand == 0
    scissors.value = hand == 1
    paper.value = hand == 2
    print(HAND_NAMES[hand])
button.when_pressed = show_hand
pause()

調整ポイント:友達と対戦するなら、相手も同じ仕組みで手を出し、LEDの組み合わせで勝敗をターミナルに表示するよう発展させると盛り上がります。

20選の一覧へ戻る ↑

CODE 13

カウントダウンタイマー(0になったらブザーで知らせる)

設定した秒数からカウントダウンし、0になったら音で知らせます。

入門+ライブラリ:tm1637 / gpiozero

必要部品

TM1637搭載4桁7セグメントLEDモジュール、パッシブブザー、押しボタン

配線

CLK→GPIO23、DIO→GPIO24/ブザー→GPIO18/ボタン→GPIO4(内蔵プルアップ、スタート用)

コードを表示・コピー
c13_countdown_timer.py
# pip install tm1637
import tm1637
from gpiozero import Button, TonalBuzzer
from gpiozero.tones import Tone
from time import sleep, monotonic
CLK_PIN = 23
DIO_PIN = 24
display = tm1637.TM1637(clk=CLK_PIN, dio=DIO_PIN)
display.brightness(5)
buzzer = TonalBuzzer(18)
button = Button(4, pull_up=True)
seconds_left = 10  # 10秒からスタート
running = False
last_tick_time = monotonic()
display.number(seconds_left)
while True:
    if not running and button.is_pressed:
        running = True
        seconds_left = 10
        last_tick_time = monotonic()
    if running and monotonic() - last_tick_time >= 1:
        last_tick_time = monotonic()
        seconds_left -= 1
        display.number(seconds_left)
        if seconds_left <= 0:
            running = False
            buzzer.play(Tone("A4"))  # 終了音
            sleep(0.8)
            buzzer.stop()

調整ポイント:seconds_left = 10の数字を変えるとタイマーの長さを変更できます。

20選の一覧へ戻る ↑

CODE 14

モールス信号でメッセージをLEDとブザーで送信

「SOS」を短点・長点のリズムでLEDの点滅とブザー音に変換して送ります。

基礎+ライブラリ:gpiozero

必要部品

LED、パッシブブザー、220Ω抵抗

配線

LED→GPIO17(220Ω経由)/ブザー→GPIO18

コードを表示・コピー
c14_morse_code.py
# 「SOS」をモールス信号でLEDとブザーで送る
from gpiozero import LED, TonalBuzzer
from gpiozero.tones import Tone
from time import sleep
led = LED(17)
buzzer = TonalBuzzer(18)
DOT_S = 0.2    # 短点の長さ
DASH_S = 0.6   # 長点の長さ(短点の3倍)
GAP_S = 0.2    # 信号同士の間隔
def signal_on(duration):
    led.on()
    buzzer.play(Tone("A4"))
    sleep(duration)
    led.off()
    buzzer.stop()
    sleep(GAP_S)
def send_dot():
    signal_on(DOT_S)
def send_dash():
    signal_on(DASH_S)
while True:
    # S = ・・・
    for _ in range(3):
        send_dot()
    sleep(0.4)
    # O = ー ー ー
    for _ in range(3):
        send_dash()
    sleep(0.4)
    # S = ・・・
    for _ in range(3):
        send_dot()
    sleep(2)  # メッセージ間の長い休み

調整ポイント:DOT_Sを変えると全体の速さが変わります。send_dot()とsend_dash()を組み合わせれば他の文字も送れます。

20選の一覧へ戻る ↑

CODE 15

ボタンの「短押し・長押し・ダブルクリック」を判定

1つのボタンで3種類の操作を区別する、実用的な入力判定の仕組みです。

基礎+ライブラリ:gpiozero

必要部品

押しボタン、LED

配線

ボタン→GPIO2(内蔵プルアップ使用)/LED→GPIO17(動作確認用、任意)

コードを表示・コピー
c15_click_pattern.py
# 1個のボタンで短押し・長押し・ダブルクリックを判定
from gpiozero import Button, LED
from time import monotonic, sleep
from signal import pause
button = Button(2, pull_up=True, bounce_time=0.02)
led = LED(17)
LONG_PRESS_S = 0.6
DOUBLE_CLICK_GAP_S = 0.3
press_start_time = 0.0
last_release_time = 0.0
waiting_second_click = False
def on_press():
    global press_start_time
    press_start_time = monotonic()
def on_release():
    global last_release_time, waiting_second_click
    now = monotonic()
    duration = now - press_start_time
    if duration >= LONG_PRESS_S:
        print("Long press")
        led.on()
        sleep(0.2)
        led.off()
    elif waiting_second_click and now - last_release_time <= DOUBLE_CLICK_GAP_S:
        print("Double click")
        waiting_second_click = False
    else:
        waiting_second_click = True
        last_release_time = now
def check_single_click():
    global waiting_second_click
    if waiting_second_click and monotonic() - last_release_time > DOUBLE_CLICK_GAP_S:
        print("Single click")
        waiting_second_click = False
button.when_pressed = on_press
button.when_released = on_release
while True:
    check_single_click()
    sleep(0.02)

調整ポイント:LONG_PRESS_SやDOUBLE_CLICK_GAP_Sの数値を変えると、判定の感度を自分好みに調整できます。

20選の一覧へ戻る ↑

CODE 16

2台のRaspberry PiをUART(シリアル通信)でつなぐ(送信・受信)

1台のボタン状態を、もう1台のRaspberry Piへ有線で送ってLEDを光らせます。

基礎+ライブラリ:pyserial

必要部品

Raspberry Piボード2台、ジャンパー線

配線

送信側にボタン(GPIO2)/受信側にLED(GPIO17)/送信側TX(GPIO14)→受信側RX(GPIO15)、送信側RX(GPIO15)→受信側TX(GPIO14)(クロス接続)、GND同士も接続

コードを表示・コピー(送信側)
c16_sender.py
# pip install pyserial
# 事前に sudo raspi-config で Serial Port を有効化(シリアルコンソールは無効化)
import serial
from gpiozero import Button
from time import sleep
ser = serial.Serial("/dev/serial0", 9600, timeout=1)
button = Button(2, pull_up=True)
while True:
    ser.write(b'\x01' if button.is_pressed else b'\x00')
    sleep(0.1)

コードを表示・コピー(受信側)
c16_receiver.py
# pip install pyserial
import serial
from gpiozero import LED
ser = serial.Serial("/dev/serial0", 9600, timeout=1)
led = LED(17)
while True:
    data = ser.read(1)
    if data:
        led.value = data == b'\x01'

調整ポイント:初期設定でGPIO14/15はシリアルコンソールに使われていることがあるため、raspi-configの「Interface Options → Serial Port」で「ログインシェルは無効・ハードウェアは有効」に設定してください。両方Raspberry Pi同士なので信号は3.3Vのまま共通で使えます。

20選の一覧へ戻る ↑

CODE 17

テキストファイルにボタンを押した回数を保存し電源を切っても記憶

Raspberry PiにはArduinoのようなEEPROMは無いため、SDカード上のファイルに書き込んで電源断後も値を残します。

基礎+ライブラリ:標準ライブラリ

必要部品

押しボタン

配線

ボタン→GPIO2(内蔵プルアップ使用、反対側はGND)

コードを表示・コピー
c17_persistent_counter.py
# EEPROM代わりにJSONファイルへ保存する
from gpiozero import Button
from signal import pause
import json
import os
STORAGE_FILE = "/home/pi/press_count.json"
button = Button(2, pull_up=True)
def load_count():
    if os.path.exists(STORAGE_FILE):
        with open(STORAGE_FILE) as f:
            return json.load(f).get("count", 0)
    return 0
def save_count(count):
    with open(STORAGE_FILE, "w") as f:
        json.dump({"count": count}, f)
press_count = load_count()  # 前回の続きから読み込む
print(f"Loaded count: {press_count}")
def on_press():
    global press_count
    press_count += 1
    save_count(press_count)
    print(f"Count: {press_count}")
button.when_pressed = on_press
pause()

調整ポイント:SDカードにも書き換え回数の上限があるため、毎回大量に書き込むような使い方は避け、値が変わった時だけ保存するようにしましょう。より本格的な用途では外付けのI2C EEPROMチップを追加することもできます。

20選の一覧へ戻る ↑

CODE 18

RTCモジュール(DS3231)で現在時刻を表示する簡易時計

ボタン電池でバックアップされた時計モジュールから時刻を読み取ります。ネットワークに繋がらない環境での時刻保持に便利です。

基礎+ライブラリ:smbus2

必要部品

DS3231 RTCモジュール

配線

SDA→GPIO2、SCL→GPIO3、VCC→5V(モジュールにより3.3V可)、GND→GND

コードを表示・コピー
c18_rtc_clock.py
# pip install smbus2
# 事前に sudo raspi-config で I2C を有効化しておく
import smbus2
from time import sleep
bus = smbus2.SMBus(1)
DS3231_ADDR = 0x68  # i2cdetect -y 1 で確認できるアドレス
def bcd_to_dec(bcd):
    return (bcd // 16) * 10 + (bcd % 16)
while True:
    data = bus.read_i2c_block_data(DS3231_ADDR, 0x00, 7)
    second = bcd_to_dec(data[0] & 0x7F)
    minute = bcd_to_dec(data[1])
    hour = bcd_to_dec(data[2] & 0x3F)
    day = bcd_to_dec(data[4])
    month = bcd_to_dec(data[5] & 0x1F)
    year = bcd_to_dec(data[6]) + 2000
    print(f"{year}/{month}/{day} {hour}:{minute:02d}:{second:02d}")
    sleep(1)

調整ポイント:初回だけ時刻をDS3231へ書き込む必要があります(レジスタへBCD形式で書き込み)。Raspberry Piはネットワーク経由で自動的に時刻合わせできるため、RTCは主にネットワークが無い環境での利用が中心になります。

20選の一覧へ戻る ↑

CODE 19

リレーモジュールで豆電球や小型モーターをON/OFF制御

小さな信号で、大きな電流が必要な機器のスイッチを入り切りします。

入門+ライブラリ:gpiozero

必要部品

リレーモジュール、豆電球や小型モーターなどの負荷、負荷用の専用電源

配線

IN→GPIO17、VCC→5V、GND→GND/負荷側はリレーのCOM・NO端子を経由して専用電源へ接続

コードを表示・コピー
c19_relay.py
# リレーで5秒ごとにON/OFFを繰り返す
from gpiozero import OutputDevice
from time import sleep
# 多くのモジュールはLOWでON(active_high=False)。要確認
relay = OutputDevice(17, active_high=False, initial_value=False)
while True:
    relay.on()
    sleep(5)
    relay.off()
    sleep(5)

重要な注意

このコードは豆電球や小型のおもちゃモーターのような低電圧の負荷を学習目的で試すためのものです。家庭用コンセント(AC100V)や高電圧・大電流の機器を接続する作業は感電・火災の危険があるため、専門知識のある大人が正しい安全対策のもとで行ってください。

調整ポイント:ONがHIGHかLOWかはリレーモジュールの種類(アクティブHIGH/アクティブLOW)によって異なります。動作が逆に感じたらactive_highの値を入れ替えてください。

20選の一覧へ戻る ↑

CODE 20

サーボとボタンで「自動ドア」のような開閉デモ

第3節で解説した自動ドアのコードを、そのままコピペで使える形にまとめました。

基礎+ライブラリ:gpiozero

必要部品

SG90サーボモーター、押しボタン

配線

サーボ信号線→GPIO18、+→5V、-→GND/ボタン→GPIO2(内蔵プルアップ使用、反対側はGND)

コードを表示・コピー
c20_auto_door.py
# ボタンで開閉する自動ドア風サーボ(コピペ用まとめ版)
from gpiozero import AngularServo, Button
from time import monotonic
SERVO_PIN = 18
BUTTON_PIN = 2
CLOSED_ANGLE = 0
OPEN_ANGLE = 90
STEP_INTERVAL = 0.015
HOLD_OPEN_S = 3
servo = AngularServo(SERVO_PIN, min_angle=0, max_angle=180)
button = Button(BUTTON_PIN, pull_up=True)
state = "CLOSED"
current_angle = CLOSED_ANGLE
last_step_time = monotonic()
hold_start_time = 0.0
servo.angle = current_angle
while True:
    now = monotonic()
    if state == "CLOSED" and button.is_pressed:
        state = "OPENING"
    if state == "OPENING" and now - last_step_time >= STEP_INTERVAL:
        last_step_time = now
        current_angle += 1
        servo.angle = current_angle
        if current_angle >= OPEN_ANGLE:
            state = "HOLDING"
            hold_start_time = now
    if state == "HOLDING" and now - hold_start_time >= HOLD_OPEN_S:
        state = "CLOSING"
    if state == "CLOSING" and now - last_step_time >= STEP_INTERVAL:
        last_step_time = now
        current_angle -= 1
        servo.angle = current_angle
        if current_angle <= CLOSED_ANGLE:
            state = "CLOSED"

調整ポイント:OPEN_ANGLEやHOLD_OPEN_Sの数字を変えると、開く角度や開いたままの時間を自由に調整できます。

20選の一覧へ戻る ↑

09

よくある質問とまとめ

はじめてRaspberry Piを触りますが大丈夫ですか?

Raspberry Pi OSのセットアップとPythonの基本文法(変数、if文、while文)が分かれば十分に試せます。まずは部品が少ない「サーボの往復」や「信号機」のような入門コードから始め、慣れてきたら通信やRTCなどのやや複雑なコードに挑戦するのがおすすめです。

モーター系のコードで注意することは?

サーボやDCモーター、ステッピングモーターはRaspberry PiのGPIOピンだけでは電流が不足し、本体の再起動や故障につながることがあります。特にDCモーターやステッピングモーターは、モータードライバと外部電源を使い、GNDをRaspberry Piと共通化してください。

外部ライブラリが必要なコードはありますか?

サーボ・LED・ボタン・DCモーターの基本操作はgpiozero(Raspberry Pi OSに標準搭載)、7セグはtm1637、LCDはRPLCD、ドットマトリクスはluma.led_matrix、シリアル通信はpyserial、RTCとの通信はsmbus2をpip installで導入します。それ以外は標準ライブラリだけで動作します。

Arduinoと違ってEEPROMが無いのはどうすればいいですか?

Raspberry PiにはArduinoのようなEEPROMは搭載されていませんが、SDカード上のファイル(テキストやJSON)に値を書き込むことで、電源を切っても内容を保持できます。RTCモジュールを追加すれば、本体の電源を切っても時刻を刻み続けます。

まずは部品が少ない「サーボの往復」「信号機」「ナイトライダー」のどれか1本を実行し、動きの仕組みを目で確認するところから始めると理解しやすくなります。動いたコードに対して、AIへ「ボタンで動きを止められるようにして」「LEDをブザーに変えて」「速さをボリューム(可変抵抗+ADC)で調整できるようにして」と追加依頼すれば、同じ回路から次の作品へどんどん発展させられます。

AI × RASPBERRY PI GUIDE PART 1 — 動かして、表示して、遊びながら回路とコードを育てていきましょう。



関連記事

特集記事

コメント

この記事へのコメントはありません。

TOP
CLOSE