Raspberry PiのI2Cデータ転送速度と波形を見る その1
2015年後半からRASPBIAN JESSIEは各種設定がGUIベースに切り替わっています。センサや表示器などの接続に使うI2CやSPIなどのシリアル通信を有効にするのも、設定画面でチェックし再起動するだけです。2015-05-05バージョンからpiユーザは、I2Cを扱うのにsudoをつける必要がなくなっています。
※2015-11-25バージョンからsudoが必要になりました。
設定メニューから変更します。「Preferences」-「Raspberry Pi Configuration」を選びます。
表示された設定画面で、Interfacesのタブを選びます。I2Cの「Enabled」をチェックしOKを押して有効にします。この後、rebootします。再起動するとI2Cが有効になります。
●I2Cを利用するにはツールが不可欠
ツールi2c-toolsとPythonのライブラリsmbusをインストールします。
sudo apt-get install i2c-tools python-smbus |
ターミナルで、i2cdetect -y 1 と打つと、接続されているデバイスを表示できます。
●I2C接続の温度デバイスMCP9808をつなぐ
400kHzのI2Cバス転送速度対応の温度センサMCP9808を用意しました。アドレスはデフォルトで0x18です。A0~A2のピンを使って変更ができますが、ほかのデバイスはつながないので、デフォルトで使いました。
ラズパイではI2Cバスの'1'を使います。
二つをジャンパ・ピンで下記の表のように接続します。
MCP9808 | ラズパイ |
---|---|
Vdd | +3.3V 1番ピン |
GND | GND 9番ピン |
SCL | SCL 5番ピン |
SDA | SDA 3番ピン |
接続したら、ラズパイの電源をつなぎ、ターミナルを起動し、次のコマンドを入れます。
i2cdetect -y 1 |
アドレス0x18に温度センサMCP9808がつながっていることが確認できました。
|
●テスト用のpythonプログラム
MCP9808の温度は0x05レジスタに2バイトで収納されています。プログラムは、センサから温度を読んで、摂氏に直して表示するルーチンを繰り返します。ファイル名はi2c-loop.pyで保存し、sudo chmod 755 i2c-loop.pyで実行権をつけます。
#!usr/bin/env python import smbus import time i2c = smbus.SMBus(1) # 1 is bus number addr03=0x18 #MCP9808 def swap16(x): return (((x << 8) & 0xFF00) | ((x >> 8) & 0x00FF)) #main print "start" while 1: t=i2c.read_word_data(addr03,0x05) #temp reg tswap= swap16(int(hex(t),16)) temp = (int(hex(tswap),16) & 0x0fff) / 16.0 temp = round(temp,1) print t,hex(t),hex(tswap),temp |
マスタのラズパイからreadコマンドが発行されています。
これに応答してスレーブのMCP9808からデータが送られてきます。
プログラムで表示される読み取ったデータは0x8A、C1と上位と下位のバイトが逆順です。なので、上位と下位のバイトを入れ替えます(スワップ)。MCP9808のマニュアルによると、読み取ったデータを0x0FFFでマスクし、16で割ると、摂氏の温度データが得られます。それを小数点第一位で四捨五入して表示します。
●低速でも動作するかを10kHzで実験
I2Cのデータ転送速度のデフォルトは100kHzです。変更するときは、/boot/config.txtに、
dtparam=i2c_baudrate=10000 |
を追加します。10000は10kHzのデータ転送速度です。
sudo nano /boot/config.txt |
エディタを立ち上げて、カーソル・キーで最下行付近に移動し、下記のように追加します。
Ctrl+oで保存し、Ctrl+xでエディタを終了します。rebootで再起動します。
立ち上がったらターミナルで、下記のプログラムを動かします。
python i2c-loop.py |
I2C通信が行われて、MCP9808から温度のデータが送られてきています。
オシロスコープの画面です。
拡大してクロックSCLの周波数を測ります。10kHzのクロックだとわかります。
コラム USBオシロスコープでI2C信号を表示してシリアル・デコードする
オシロスコープを見ると、1,0に相当する電圧や中途半端な電圧が表示されて、信号の素な状態が見れます。しかし、I2Cのコマンドやデータを頭の中でデコードするのは大変です。そういうときはロジック・アナライザを使います。Analog Discovery2のロジック・アナライザの画面です。
周波数を上げていったときに、どのような波形になるかを見たかったので、PicoScope 5242Bを使って、アナログ信号とI2Cでコードを同時に表示します。その手順は次のようになります。
事前に、A,Bのプローブの両方を5V/div、1/10アッテネータ、15ビット(解像度は19ビット相当に上げる)に設定します。使っているソフトウェアはBeta 6.12.2.1871です。
メニューにあるツールのシリアルデコードを選びます。
作成をクリックし、I2Cを選びます。
2本あるプローブを、DataとClockどちらにつなぐかを設定します。
チャネルAをData=SDAに、チャネルBをClock=SCLに設定します。
中央部にThresholdの電圧が入力されています。まだSDA、SCLには信号が出ていないのでHigh状態で、そのピークの電圧が入っていますが、このままではデコードするには高すぎます。3.0Vに変更しました。
OKを押すと前の画面に戻ります。ここでもOKを押します。
繰り返し温度データを読み取りをするプログラムをpython i2c-loop.pyで実行します。上の青色の波形がデータSDAで、その真下に、デコードした値が16進で表示されています。一番下の赤色はクロックのSCLです。