2015年4月12日日曜日

【Ruby】 Raspberry Pi とArduinoでI2C通信

RaspberryPiとArduinoでI2C通信をして、Arduinoに接続したセンサで読み取った値をRaspberryPiに送信してみます。マスター側のRaspberryPiの処理をRubyで書いていきます。


使用したもの


この測距モジュールはGNDがオレンジでVccが黒というトラップがあるので注意。(図1)

 

図1 GP2Y0A21YK

 

Raspberry Pi側の準備

/boot/config.txt の末尾に以下の1行を追加。
dtparam=i2c_arm=on

/etc/modules の末尾に以下の1行を追加。
i2c-dev

/etc/modprobe.d/raspi-blacklist.conf の以下の1行をコメントアウト。
blacklist i2c-bcm2708

また、I2C通信をする際 /dev/i2c-1 を使用するため権限が必要ですが、以下のようにすると毎回sudoしなくてよくなります。(usernameはi2cグループに追加したいユーザで置き換えてください piとか)
1
$ sudo gpasswd -a username i2c
$ sudo usermod -G i2c username でも可能ですが、追加する操作でないためそのユーザに設定されている他のグループの設定まで変わってしまうので gpasswd の方がいいです。

ここで一度再起動します。
1
$ sudo shutdown -r now

I2C通信の確認をするためのツールをインストールし、試しに実行してみます。
1
2
3
4
5
6
7
8
9
10
11
$ sudo apt-get install i2c-tools
$ i2cdetect -y 1
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00:          -- -- -- -- -- -- -- -- -- -- -- -- --
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
70: -- -- -- -- -- -- -- --

sudoなしで実行することができました。まあまだどこにも繋いでないので特になにも表示されないですが。
Error: Could not open file `/dev/i2c-1': Permission denied
Run as root?
とか言われたらグループに追加するのがうまくいってない可能性があります。


配線

RaspberryPiは第3ピン(GPIO 2)がSDA第5ピン(GPIO 3)がSCL
Arduinoはアナログピン4がSDAアナログピン5がSCLとなっています。

RaspberryPi内蔵のプルアップ抵抗があるようなのでそのままArduinoに繋いで大丈夫です。

センサーの出力はアナログピン1に繋いでいます。

 

図2 配線の例

 

図3 実際に配線した様子

図2のRaspberryPiはB+ではありませんが、ピンの位置は同じなので大丈夫です。

Arduino(スレーブ)側

以下のスケッチを書き込みます。
psd.ino
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include <Wire.h>
 
void setup()
{
    Wire.begin(8); // スレーブのアドレスを8に設定
    Wire.onRequest(psd); // マスターに呼ばれたときに呼び出す関数
}
 
void loop()
{
    delay(100);
}
 
void psd()
{
    // 以下は距離[cm]を求める近似計算
    int temp, distance;
    temp = analogRead(1);
    if(temp<4) temp = 4; // 0除算を回避
    distance = (6787 / (temp - 3) );
 
    Wire.write(distance);
}

Raspberry Pi(マスター)側

i2cというgemを使用します。
1
$ sudo gem install i2c
main.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
require 'i2c'
 
device = I2C.create('/dev/i2c-1')
 
begin
  loop do
    # アドレス0x08のスレーブからサイズ1バイトで受信
    data = device.read(0x08, 1)
    puts "#{data.bytes[0]} cm"
    sleep(1)
  end
 
rescue Interrupt
  exit 0
end

これを実行すると、Arduinoからセンサの値が送られていることが確認できます。

参考サイト

以下のサイトを参考にさせていただきました。

Raspberry PiによるIoT(M2M)【I2C温度センサー/xively/Python】

最近の Raspberry Pi で I2C を有効化する方法

0 件のコメント:

コメントを投稿