I2C とは
I2C (Inter Integrated Circuit; アイ スクエア シー) はシリアル通信の方式の一つです。この規格に準拠したデバイス同士は、二本の信号線だけでデータのやりとりを行えます。デバイス同士は対等ではなく、マスターに一つ以上の I2C スレーブを接続します。これらスレーブは同じ種類の IC である必要はありません。各種センサー、LCD、モータードライバ、A/D コンバータなど、様々な IC が I2C に対応しています。
二つの信号線
- IC 同士でクロックを同期するための SCL (シリアルクロック)
- データ通信のための SDA (シリアルデータ)
また、似たインターフェースとして Raspberry Pi はシリアル通信の SPI 規格にも対応しています。
初期設定
Raspberry Pi は I2C のマスターとして動作可能なデバイスです。既定では I2C が無効化されているため、初期設定が必要です。今回使用した Raspberry Pi は Model B+ です。リビジョンは以下のとおりです。
pi@raspberrypi:~ $ cat /proc/cpuinfo | grep Revision
Revision : 0010
または
pi@raspberrypi:~ $ sudo python
>>> import RPi.GPIO as GPIO
>>> GPIO.RPI_REVISION
3
NOOBS のバージョンは以下のとおりです。
pi@raspberrypi:~ $ cat /etc/issue
Raspbian GNU/Linux 8 \n \l
pi@raspberrypi:~ $ uname -r
4.1.19+
ライブラリのインストールおよび I2C の有効化
以下のコマンドで必要なライブラリをインストールします。
sudo apt-get update
sudo apt-get install i2c-tools
初期設定画面を起動します。
sudo raspi-config
本ページで利用している OS のバージョンは上述の通り 4.1.19+
です。その場合は以下の画像のように Advanced Options を選択してエンターを押します。ただし、下記フォーラムにも記載のとおり、最新の Raspbian を利用している場合は 5 Interfacing Options
を選択します。
advanced options I2C not showing
I have the same options to choose from in Advanced Settings as in your picture, but in 5 Interfacing Options I found the option P5 I2C
https://raspberrypi.stackexchange.com/questions/63076/advanced-options-i2c-not-showing
I2C を選択してエンターを押します。
Yes を選択して有効化します。
Yes を選択して既定で I2C を有効化するようにします。
Finish を選択してエンターを押します。
再起動します。
シリアル通信 baudrate の設定
I2C の動作周波数は、低速モード、高速モード等、デバイスによって異なります。以下のコマンドを実行して i2c-dev
が記載されていることを確認します。
sudo vi /etc/modules
シリアル通信 baudrate を設定するために以下のコマンドを実行します。
sudo vi /boot/config.txt
最終行に dtparam=i2c_baudrate=50000
を追記して再起動します。
sudo reboot
設定が反映されていることを確認します。
dmesg | grep i2c
実行結果
[ 4.607918] i2c /dev entries driver
[ 12.712102] bcm2708_i2c 20804000.i2c: BSC1 Controller at 0x20804000 (irq 79) (baudrate 50000)
これは sudo raspi-config
を実行して I2C 設定を変更すると初期化されますので注意してください。
I2C コマンドの使用確認
適切にインストールされた場合、例えば i2cdetect
コマンドが使用できるようになっています。以下のコマンドで I2C バス一覧を確認します。
sudo i2cdetect -l
実行結果
i2c-1 i2c 20804000.i2c I2C adapter
I2C バス 1 について、Raspberry Pi に接続された I2C デバイス一覧およびそれらのアドレスを確認します。
sudo i2cdetect -y 1
I2C デバイスには出荷時に 0x03 - 0x77
の範囲でアドレスが割り当てられています。I2C のマスターが複数のスレーブから適切な対象を識別して問い合わせるためにこれらのアドレスを用います。デバイスによっては検出できないものがあります。その場合はデータシートを参照して調べます。
I2C プログラミング
ACM1602NI に文字列 XYZ
を表示するサンプルです。
この I2C デバイスは i2cdetect
でアドレスを取得できません。データシートを参照すると 0x50
であることが分かります。
Slaver address could only set to 1010000, no other slaver address could be set.
LCD のピンは左から順に 1-7 です。
ピン番号 | シンボル | 機能 | 備考 |
---|---|---|---|
1 | VSS | Ground | |
2 | VDD | 3.3V | Raspberry Pi から供給可能 |
3 | V0 | LCD contrast adjust | バックライトのコントラストを調整 (アナログ入力 0-3.3V) |
4 | SCL | SERIAL CLOCK INPUT | |
5 | SDA | SERIAL DATA INPUT | |
6 | BL+ | Power Supply for BL+ | デジタル入力 (ON/OFF) |
7 | BL- | Power Supply for BL- | グランド 0V |
Raspberry Pi のピン配置を参考に回路を組みます。SCHEMATICS.COM で作成しました。
gpio コマンドでバックライトの ON/OFF を試してみましょう。
gpio -g mode 4 out
gpio -g write 4 1
データシートによると、制御時は 0x00
、データ送信時は 0x80
に書き込めばよいことが分かります。
When the control byte is 0x00, the next folling byte is command byte.
When the control byte is 0x80, the next folling byte is data byte.
Python
言語によっては Raspberry Pi 用に I2C ライブラリが存在しています。以下に Python の例を記載します。smbus-cffi を利用します。
sudo apt-get install python-smbus
sudo reboot
sample.py
#!/paty/to/python
# -*- coding: utf-8 -*-
import smbus
import time
i2c = smbus.SMBus(1)
# 画面初期化 (カーソル表示。点滅あり)
i2c.write_byte_data(0x50, 0x00, 0x01)
time.sleep(0.2)
i2c.write_byte_data(0x50, 0x00, 0x38)
time.sleep(0.1)
i2c.write_byte_data(0x50, 0x00, 0x0f)
time.sleep(0.1)
i2c.write_byte_data(0x50, 0x00, 0x06)
time.sleep(0.1)
# `XYZ` 出力
i2c.write_byte_data(0x50, 0x80, 0x58)
i2c.write_byte_data(0x50, 0x80, 0x59)
i2c.write_byte_data(0x50, 0x80, 0x5a)
# アドレス `40h` にカーソル移動 (DDRAM Address という一般的な 7 ビットの形式で指定)
i2c.write_byte_data(0x50, 0x00, 0xc0)
time.sleep(0.1)
# `xyz` 出力
i2c.write_byte_data(0x50, 0x80, 0x78)
i2c.write_byte_data(0x50, 0x80, 0x79)
i2c.write_byte_data(0x50, 0x80, 0x7a)
任意の言語
i2c-tools
でインストールされた i2cset
と i2cget
コマンドをシステム関数で呼び出せば、ライブラリが存在しない言語でも gpio コマンドで制御する場合と同様に I2C プログラミングできます。
画面初期化 (カーソル表示。点滅あり)
i2cset -y 1 0x50 0x00 0x01
i2cset -y 1 0x50 0x00 0x38
i2cset -y 1 0x50 0x00 0x0f
i2cset -y 1 0x50 0x00 0x06
XYZ
出力
i2cset -y 1 0x50 0x80 0x58
i2cset -y 1 0x50 0x80 0x59
i2cset -y 1 0x50 0x80 0x5a
アドレス 40h
にカーソル移動 (DDRAM Address という一般的な 7 ビットの形式で指定)
i2cset -y 1 0x50 0x00 0xc0
xyz
出力
i2cset -y 1 0x50 0x80 0x78
i2cset -y 1 0x50 0x80 0x79
i2cset -y 1 0x50 0x80 0x7a
関連記事
- 任意の言語で Raspberry Pi デジタル入出力、アナログ出力 (PWM)python を用いた例 書籍や公式ドキュメントなどを見ると、Raspberry Pi は python を (発音が似ているからでしょうか) 標準的な言語としてサポートしているように思われます。python には GPIO を操作するライブラリが標準で導入されています。 デジタル出力 #!/usr/bi
- Android Things による LED 点灯 (Raspberry Pi 3)電子工作や製品のプロトタイピング (例『地球規模で遠隔操作できるブルドーザー』) で利用される Raspberry Pi 3 について、 Android Things アプリケーションを開発できます。 本ページでは、簡単な例として LED を点灯させるアプリケーションを扱います。より実用的なアプリケーションを開発する際には [GitHub (Android Thin
- Raspberry Pi 無線接続時の IP 固定wlan0 の IP 固定方法 Raspberry Pi の SSID とパスワード設定は終わっている前提で以下のファイルを編集します。 $ sudo vi /etc/network/interfaces 以下の 4 行を一番最後に追加します。適宜自分の環境用に IP を変えてください。 iface wlan0 inet static address 192.168.179.1
- Raspberry Pi アナログ入力 (I2C A/D コンバータ)ADS1015 について Raspberry Pi には A/D コンバータが内蔵されていません。デジタル入出力、アナログ出力に加えてアナログ入力を行うためには外部 IC を利用する必要があります。ここでは I2C デバイスの ADS1015 を利用します。事前に I2C 設定を行っておいてください。 ![](
- Raspberry Pi ピン配置などを公式ドキュメントで調べる公式ドキュメント Raspberry Pi 公式ドキュメントにはインストール方法や初期設定などが記載されています。 Raspberry Pi Documentation ピン配置 / GPIO [GPIO: Models A+, B+, Raspberry Pi 2 B and Raspberry Pi