Raspberry Pi で I2C を利用するための設定
[履歴] [最終更新] (2017/08/18 15:54:13)
10
作品
8
技術情報
最近の投稿
ここは
趣味の電子工作を楽しむ人のためのハードウェア情報共有サイト

技術情報や作品の投稿機能、リアルタイム遠隔操作 API をご利用いただけます。
新着作品

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

Uploaded Image

I2C を選択してエンターを押します。

Uploaded Image

Yes を選択して有効化します。

Uploaded Image

Uploaded Image

Yes を選択して既定で I2C を有効化するようにします。

Uploaded Image

Uploaded Image

Finish を選択してエンターを押します。

Uploaded Image

再起動します。

Uploaded Image

シリアル通信 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 を表示するサンプルです。

Uploaded Image

この 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 で作成しました。

Uploaded Image

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.

Uploaded Image

Uploaded Image

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 でインストールされた i2cseti2cget コマンドをシステム関数で呼び出せば、ライブラリが存在しない言語でも 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