I²C と 1-Wire ってなに? — 通信方式の基礎
電子工作初心者向け:センサーとマイコンが「話す」仕組み
マイコンとセンサーをつなぐとき、「I²C で通信します」「1-Wire 接続です」という言葉をよく見かけます。これらは「マイコンと部品がデータをやり取りするための約束事(プロトコル)」です。配線の本数や信号の出し方が決まっているので、同じ「言葉」を話せる部品同士なら、メーカーが違ってもつなげられます。
1. そもそも「通信」とは
マイコン(Pico)が温度センサー(DHT20)から「今何度ですか」と聞くには、数字を電気信号に変えて送ってもらう必要があります。このとき、以下のことが決まっていないと混乱します:
- いつ話し始めるか(タイミング)
- 0 と 1 をどう表現するか(電圧の HIGH/LOW)
- どっちから話すか(マイコンが主導か、センサーが勝手に話すか)
- 間違いがあったらどうするか(確認の仕方)
これらを決めたのが「通信プロトコル」です。I²C も 1-Wire も、それぞれ独自の「約束事」です。
図1:マイコンとセンサーが「通信プロトコル」という共通の約束事でデータをやり取りする。
2. I²C(アイ・スクエア・シー)とは
2-1. 正式名称と特徴
I²C は Inter-Integrated Circuit の略です。フィリップス(現在は NXP)が開発した通信方式で、クロック線(SCL)とデータ線(SDA)の 2 本だけで複数のデバイスと通信できます。
| 項目 | I²C の特徴 |
|---|---|
| 配線本数 | 2 本(SCL + SDA)+ 電源・GND |
| 通信速度 | 標準モード 100kHz、高速モード 400kHz など |
| 接続できるデバイス数 | 理論上は 127 個(アドレスによる識別) |
| 主導権 | マスター(マイコン)が主導し、スレーブ(センサーなど)が応答 |
| 信号の出し方 | オープンドレイン(後述) |
2-2. 2 本の線の役割
- SCL(Serial Clock):クロック線。マスターが「今から 1 ビット目です」「次は 2 ビット目です」というタイミングを伝える線。
- SDA(Serial Data):データ線。実際の 0 と 1 が流れる線。SCL のタイミングに合わせて HIGH/LOW が変化する。
図2:I²C の信号イメージ。SCL(クロック)がタイミングを刻み、SDA(データ)がそのタイミングに合わせて 0/1 を変化する。
2-3. オープンドレインとプルアップ抵抗
I²C の大きな特徴は「オープンドレイン」という信号の出し方です。通常の GPIO は HIGH(3.3V)も LOW(0V)も自分で出力しますが、I²C のデバイスはLOW だけを作り、HIGH は「放っておく」のです。
このため、信号線が HIGH になるのは外部のプルアップ抵抗が電源から電流を流して引き上げてくれるおかげです。抵抗がないと信号線は宙ぶらりんになり、HIGH も LOW も安定しません。
図3:I²C はオープンドレイン方式。デバイスは LOW だけを作り、HIGH はプルアップ抵抗が電源から引き上げる。
複数のデバイスが同じ SDA/SCL 線を共有する場合、A が HIGH を出そうとした瞬間に B が LOW を出すと「ショート」が起きて壊れる可能性があります。オープンドレインなら「LOW を作る/放る(何もしない)」だけなので、複数デバイスが同時に信号を出しても衝突しにくい仕組みになっています。
2-4. アドレスでデバイスを選ぶ
I²C では同じ 2 本の線に複数のデバイスをつなげられます。では「誰に話しかけているのか」をどう区別するか? それがアドレスです。各デバイスには製品ごとに決まったアドレス(7 ビットの数字)があります。
DHT20 のアドレスは 0x38(56)です。マイコンが「アドレス 0x38 のデバイスに聞くよ」と送ると、DHT20 だけが応答し、他のデバイスは黙っています。
from machine import Pin, I2C
i2c = I2C(0, sda=Pin(4), scl=Pin(5), freq=100000)
print([hex(x) for x in i2c.scan()])
# [0x38] ← DHT20 が応答している!
3. 1-Wire(ワンワイヤー)とは
3-1. 正式名称と特徴
1-Wire は Maxim Integrated(現在は Analog Devices) が開発した通信方式で、データ線が 1 本だけで済みます。電源線(VDD)が不要な「寄生電源」モードもあり、極端に配線を減らせます。
| 項目 | 1-Wire の特徴 |
|---|---|
| 配線本数 | 1 本(データ)+ GND。電源線は不要な場合もある |
| 通信速度 | 16.3kbps(標準)、比較的遅い |
| 接続できるデバイス数 | 理論上は多数(ただし実用的には数十個程度) |
| 主導権 | マスター(マイコン)が常に主導 |
| 信号の出し方 | オープンドレイン(I²C と同様) |
3-2. 1 本でどうやって通信するのか
1-Wire ではデータ線 1 本で「電源供給」と「データ通信」の両方を行います。具体的には:
- マイコンがデータ線を一定時間 LOW にして「リセットパルス」を送る
- スレーブ(センサー)が存在を示す「プレゼンスパルス」を返す
- その後、マイコンが「1」を送るには短い LOW、"0" を送るには長い LOW を作る
- スレーブも同じように短い LOW/長い LOW で応答する
「短い/長い」というパルスの長さで 0 と 1 を区別するため、タイミングが I²C よりもシビアです。
図4:1-Wire の信号イメージ。リセットパルスで通信開始を告げ、パルスの長さで 0 と 1 を区別する。
4. I²C と 1-Wire の比較
| 比較項目 | I²C | 1-Wire |
|---|---|---|
| 配線本数(最小) | 2 本(SCL + SDA)+電源・GND | 1 本(データ)+ GND(電源不要の場合も) |
| 通信速度 | 比較的高速(100kHz〜400kHz) | 比較的遅い(16.3kHz) |
| タイミングの厳しさ | クロック線があるため比較的ゆるやか | マイコンが厳密な時間管理が必要 |
| 複数デバイス接続 | アドレスで識別(簡単) | 各デバイスに固有 ID(64bit ROM)あり |
| 代表的なセンサー | DHT20、BME280、SSD1306(OLED) | DS18B20(温度)、DHT11(一部実装) |
| MicroPython 対応 | 標準で I2C クラスあり | 標準ではない場合が多い(ライブラリ要) |
5. なぜ今回は I²C(DHT20)を選んだのか
今回のプロジェクトでは、ELEGOO キットに入っていた DHT11(1-Wire 方式)を使う予定でした。しかし以下の理由で DHT20(I²C 方式)に変更しました:
電圧の問題
DHT11 は 5V 系で動作するものが多く、Pico の 3.3V GPIO へ直接接続できません。電圧変換回路が必要になり、部品と配線が増えます。
通信の信頼性
DHT11 の 1-Wire 実装はメーカー独自で、タイミングがシビアです。I²C はクロック線(SCL)があるため、マイコン側が「今データを読むよ」とタイミングを制御でき、通信が安定しやすいです。
MicroPython のサポート
MicroPython には I2C クラスが標準で組み込まれています。1-Wire は標準ではない場合が多く、追加ライブラリが必要です。
データシートの明確さ
DHT20 のデータシートには「プルアップ抵抗 4.7kΩ」「デカップリング 0.1µF」が明確に示されています。要件がはっきりしているため、配線ミスが減ります。
3.3V 対応、通信が安定、MicroPython 標準サポート、データシートで外付け部品が明確。1-Wire(DHT11)より配線は 1 本多いが、全体として確実性が高い。
6. まとめ
| 言葉 | 簡単な説明 |
|---|---|
| I²C | クロック線とデータ線の 2 本で通信。複数デバイスをアドレスで区別。オープンドレイン方式でプルアップ抵抗が必要。 |
| 1-Wire | データ線 1 本だけで通信。配線は少ないがタイミングがシビア。電源線が不要な場合もある。 |
| オープンドレイン | デバイスが LOW だけを作り、HIGH は外部のプルアップ抵抗が電源から引き上げる方式。複数デバイス共有に安全。 |
| プルアップ抵抗 | 信号線を電源側(HIGH)に「引っ張り上げる」抵抗。I²C や 1-Wire で必須。なければ信号が不安定。 |
| SCL | I²C のクロック線。マスターがタイミングを刻む。 |
| SDA | I²C のデータ線。SCL のタイミングに合わせて 0/1 を送る。 |
| マスター | 通信の主導権を持つ側(今回は Pico)。 |
| スレーブ | マスターの指示に従って応答する側(今回は DHT20)。 |
| アドレス | I²C デバイスごとに決まった識別番号。DHT20 は 0x38。 |
「I²C を使う」=「SCL と SDA の 2 本にプルアップ抵抗を入れて、マスターがアドレスを指定して話しかける」ということ。ブレッドボードで I²C デバイスを動かないときは、まずプルアップ抵抗とアドレス(
i2c.scan())を確認するのが鉄則です。
7. ライブラリの階層構造 — 誰が何を担当するのか
I²C や 1-Wire を使うとき、「ライブラリを入れる」という言葉を聞きますが、実は2 種類のライブラリが存在します。どちらが何をやっているのかを整理すると、全体像が見えてきます。
7-1. 2 種類のライブラリ
| 種類 | 役割 | 例 |
|---|---|---|
| 通信プロトコルライブラリ | I²C や 1-Wire の「約束事」をプログラムから扱いやすくする。電気信号のタイミングやバイト列の送受信を担当。 | MicroPython の I2C クラス、onewire モジュール |
| 機器専用ライブラリ | その機器固有の「会話の仕方」を担当。どの命令を送れば温度が返ってくるか、返ってきた生データをどう計算するか。 | DHT20 用ドライバ、DS18B20 用ドライバ、SSD1306 用ドライバ |
7-2. 階層のイメージ
DHT20 で温度を取得する場合、階層はこうなります:
図5:DHT20 で温度を読むときの階層。機器専用ライブラリが「会話の仕方」を、I²C ライブラリが「通信の仕方」を担当する。
7-3. 機器専用ライブラリは必須ではない
機器専用ライブラリは便利な省略形ですが、必ずしも必要ではありません。DHT20 のデータシートを読めば、以下が分かります:
- I²C でアドレス
0x38に測定開始コマンド(特定のバイト列)を送る - 測定完了を待つ(データシートに待ち時間が記載されている)
- 6 バイトのデータを読み出す
- 生データを式に代入して温度・湿度に変換する
これを自分でプログラムに書けば、機器専用ライブラリなしで動かせます:
自分のプログラム
↓
I²C ライブラリ(MicroPython 標準の machine.I2C)
↓
DHT20
- I²C / 1-Wire → 通信プロトコル(通信の約束事そのもの)
- I²C ライブラリ / 1-Wire ライブラリ → その約束をプログラムから簡単に使うためのソフトウェア
- DHT20 用ライブラリ → DHT20 固有の命令やデータ形式まで面倒を見てくれるソフトウェア(省略形)