電子工作やRaspberry Pi(ラズパイ)で「物体までの距離を測定したい」と思ったことはありませんか?
今回は SHARP製 赤外線距離センサ「GP2Y0E03」 を使って、Raspberry Pi 3B と I2C 接続し、Pythonで距離を測定する方法を、電子工作初心者の方にも分かるように丁寧に解説します。
この記事で分かること
GP2Y0E03とは?(初心者向け解説)
GP2Y0E03 は、SHARPが製造している赤外線方式の距離センサです。
特徴
- 測定距離:約 4〜64cm
- 出力:I2C(デジタル)+アナログ
- 電源電圧:2.7〜5.5V
- Arduino / Raspberry Pi 両対応
- 小型でロボット・自動化用途に最適
こんな用途におすすめ
- 障害物検知
- 近接センサ
- ロボット制御
- 自動ドア・人感代替
- 電子工作の入門教材
配線方法(3.3V・I2C接続)

⚠️ 電圧の注意点(重要)
Raspberry Pi の I2C は 3.3V専用です。
そのため GP2Y0E03 も 3.3V動作で使用します。
配線対応表
| GP2Y0E03 | Raspberry Pi |
|---|---|
| VDD | 3.3V(Pin1) |
| VIN(IO) | 3.3V(Pin1) |
| GND | GND(Pin6) |
| SDA | GPIO2(Pin3) |
| SCL | GPIO3(Pin5) |
| GPIO1 | 3.3V(常時ON) |
| Vout(A) | 未接続 |
※ GPIO1 は動作ON/OFF端子です。
今回は 常時ON のため 3.3V に接続します。
Raspberry Pi 側の設定
① I2Cを有効化
sudo raspi-config
- Interface Options
- I2C → Enable
- 再起動
② 必要なツールをインストール
sudo apt update
sudo apt install -y i2c-tools python3-pip
pip3 install smbus2
③ センサが認識されているか確認
i2cdetect -y 1
0x40 が表示されれば接続成功です。
0 1 2 3 4 5 6 7 8 9 a b c d e f
00: -- -- -- -- -- -- -- --
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
40: 40 -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
Pythonで距離を測定するプログラム
距離データの仕組み(簡単解説)
GP2Y0E03 は
- 距離データ(12bit)
- スケール調整用「Shift Bit」
を組み合わせて距離(cm)を計算します。
サンプルコード
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import time
from smbus2 import SMBus
I2C_BUS = 1
ADDR_7BIT = 0x40 # GP2Y0E03: Slave ID 0x80/0x81(8-bit) -> 0x40(7-bit) :contentReference[oaicite:10]{index=10}
REG_SHIFT = 0x35
REG_DIST_H = 0x5E # Distance[11:4] :contentReference[oaicite:11]{index=11}
REG_DIST_L = 0x5F # Distance[3:0] :contentReference[oaicite:12]{index=12}
def read_u8(bus, reg):
return bus.read_byte_data(ADDR_7BIT, reg)
def get_shift_n(bus):
"""Shift Bit(0x35) の下位3bitが n(アプリノートの説明に従う)"""
v = read_u8(bus, REG_SHIFT)
n = v & 0x07
return n
def read_distance_cm(bus):
"""
測距値 = (Distance[11:4]*16 + Distance[3:0]) / 16 / 2^n :contentReference[oaicite:13]{index=13}
ここでは raw12 = (H<<4) | (L & 0x0F) を使い、distance = raw12 / (16*(2^n))
"""
n = get_shift_n(bus)
h = read_u8(bus, REG_DIST_H)
l = read_u8(bus, REG_DIST_L) & 0x0F
raw12 = (h << 4) | l
dist_cm = raw12 / (16.0 * (2 ** n))
return dist_cm, n, raw12
def main():
with SMBus(I2C_BUS) as bus:
# 起動直後は最大距離側を出すことがあるため、少し待つ :contentReference[oaicite:14]{index=14}
time.sleep(0.2)
while True:
dist_cm, n, raw12 = read_distance_cm(bus)
print(f"Distance: {dist_cm:6.2f} cm (shift n={n}, raw12={raw12})")
time.sleep(0.2)
if __name__ == "__main__":
main()
実行結果例
Distance: 4.02 cm (shift n=2, raw12=257)
Distance: 4.02 cm (shift n=2, raw12=257)
Distance: 4.02 cm (shift n=2, raw12=257)
コード解説
このプログラムは何をする?
Raspberry Pi の I²C(SDA/SCL)を使って GP2Y0E03 という距離センサから値を読み取り、
**距離(cm)**としてターミナルに表示し続けるプログラムです。
処理の流れはシンプルで、次の繰り返しです。
- センサ内部のレジスタから「距離の生データ」を読む
- 生データを「cm」に変換する
- 0.2秒ごとに表示する
I²Cアドレスとレジスタ(重要)
I2C_BUS = 1
ADDR_7BIT = 0x40
I2C_BUS = 1:Raspberry Pi の I²C-1 を使うADDR_7BIT = 0x40:GP2Y0E03 の I²C アドレス(7bit表記)
どのレジスタを読んでいる?
REG_SHIFT = 0x35
REG_DIST_H = 0x5E
REG_DIST_L = 0x5F
GP2Y0E03 はセンサ内部に「レジスタ」と呼ばれるメモリ領域があり、
I²Cで **指定した番地(レジスタ番号)**を読むと情報が取れます。
0x5E:距離データの上位(Distance[11:4])0x5F:距離データの下位(Distance[3:0])0x35:距離のスケールに関係する Shift 情報(後述)
1バイト読む関数(基本部品)
def read_u8(bus, reg):
return bus.read_byte_data(ADDR_7BIT, reg)
read_byte_data(アドレス, レジスタ)で **1バイト(8bit)**読みます- ここでは「指定したレジスタの値を1バイト読む」共通処理を関数化しています
初心者向けポイント:
同じ処理を何度も書くとミスが増えるので、関数にすると読みやすくなります。
Shift値 n を読む(距離変換に必要)
def get_shift_n(bus):
v = read_u8(bus, REG_SHIFT)
n = v & 0x07
return n
REG_SHIFT(0x35) を読むと、距離換算に使う シフト値 n が入っています。
つまり「n は下位3ビットに入っている」という前提で抜き出しています
v & 0x07 の意味:
0x07は2進数で00000111- AND(&)を取ることで 下位3ビットだけを取り出す
- つまり「n は下位3ビットに入っている」という前提で抜き出しています
距離の生データ(12bit)を作る
h = read_u8(bus, REG_DIST_H)
l = read_u8(bus, REG_DIST_L) & 0x0F
raw12 = (h << 4) | l
ここが初心者が最初に戸惑うところです。
なぜ “12bit” なの?
GP2Y0E03 の距離データは 12bit(0〜4095)で返ってきます。
- 上位8bit(Distance[11:4])が
0x5E - 下位4bit(Distance[3:0])が
0x5Fの下位4bit
& 0x0F の意味
0x0F は2進数で 00001111
ANDを取ることで 下位4bitだけ残す ためです。
(上位4bitは他の用途の可能性があるので捨てます)
(h << 4) | l の意味
h << 4:上位8bitを4bit左にずらして「上位側」に配置| l:そこに下位4bitを足して合体(ORで結合)
例(イメージ):
- h =
10101010 - l =
00000101(下位4bitが0101) - raw12 =
10101010 0101(12bit値)
生データ → cm に変換
dist_cm = raw12 / (16.0 * (2 ** n))
GP2Y0E03 の仕様(アプリノート)で、距離は次の式で求めます。
raw12を一定の倍率で割ることで cm になるn(shift)によって倍率が変わる
ここでは読みやすいように式を整理して
16.0 * (2 ** n)で割っています
初心者向け補足:2 ** n は「2のn乗」です。
n=2なら 2**2 = 4 になります。
main() の動き(繰り返し表示)
with SMBus(I2C_BUS) as bus:
time.sleep(0.2)
while True:
dist_cm, n, raw12 = read_distance_cm(bus)
print(...)
time.sleep(0.2)
with SMBus(...) as bus の意味
- I²Cバスを開いて使う
withを使うと、終了時に自動でクローズしてくれて安全です
最初に 0.2秒待つ理由
センサーは起動直後に値が安定しないことがあり、最大距離側を出す挙動があるため少し待っています。
よくあるトラブルと対策
| 症状 | 対策 |
|---|---|
| i2cdetectに表示されない | 配線・I2C有効化を再確認 |
| 距離が最大値のまま | 起動後1秒ほど待つ |
| 値が不安定 | 反射物の色・角度を確認 |
| 通信できない | VIN(IO)を3.3Vに接続 |
使用した部品一覧
| 部品 | 補足 | リンク |
|---|---|---|
| Raspberry Pi 3 Model B | 他のPiでも可 | Amazonで見る |
| GP2Y0E03 距離センサ | SHARP製 | Amazonで見る |
| ジャンパワイヤ | オス-メス,メス–メス等 | |
| microSD / 電源 | 通常のPi環境 | SanDisk 高耐久 |
まとめ
- GP2Y0E03は初心者でも扱いやすい距離センサ
- Raspberry Piとは I2C(3.3V)で安全に接続
- Pythonで簡単に距離(cm)を取得できる
- 電子工作・IoT入門に最適
今回は、赤外線センサーを用いて電子工作する一例を紹介しました。是非、皆さんも使用してみて下さい。
