読者です 読者をやめる 読者になる 読者になる

<IoT>加速度センサの値をMQTTを使ってネット越しにやりとりする

MQTT Raspberry pi IoT

今回はRaspberry pi に接続された加速度センサの値をMQTTでネット越しにやりとりするプログラムを作成する。
手順は
1 ラズパイで加速度センサの値を取れるようにする
2 センサの値をMQTTブローカーを介してやりとりする
※ MQTTブローカーの構築については2つの記事を参照 
<IoT>mqttブローカーmosquittoを試してみた - xhatenenの日記

<IoT>-前回修正記事-mqttブローカーmosquittoを試してみた - xhatenenの日記

1 ラズパイで加速度センサの値を取れるようにする

加速度センサは秋月電子のADXL345(3軸加速度センサモジュール ADXL345(SPI/IIC): センサ一般 秋月電子通商 電子部品 ネット通販)を購入した、ブレッドボードにさすためにはんだ付けでくっつける
はんだ付け後のセンサ
f:id:xhatenen:20141231005054j:plain

ADXL345とラズパイの接続は以下のように行った
ADXL345接続部分が9穴ぐらいあるので
今回はその中から4穴使う

RasPi     ADXL345
3.3V <==> VDD
GND <==> GND
SCL <==> SCL
SDA <==> SDA


ラズパイの設定は以下の記事を参考にしながら作成した
http://www.stuffaboutcode.com/2014/06/raspberry-pi-adxl345-accelerometer.html

英語なので和訳しながら、解説する

<以下自分の状況に合わせながら和訳(かなり意訳、順番もめちゃくちゃ)>
ADXL345はSPI,I2Cに対応しているが今回はI2Cを使う

ラズパイの設定にI2Cモジュールを加える

sudo nano /etc/modules

そして以下の2文を加える

i2c-bcm2708
i2c-dev

ブラックリストからI2Cを除く

sudo nano /etc/modprobe.d/raspi-blacklist.conf

以下の文をコメントアウト(文頭に#をつける)

blacklist i2c-bcm2708

再起動して変更を反映させる

sudo shutdown -r now

必要なソフトウェアのインストール

sudo apt-get install python-smbus i2c-tools git-core

ADXL345のテスト

sudo i2cdetect -y 1

するとアドレスが表示される(アドレスは1dだった)

0 1 2 3 4 5 6 7 8 9 a b c d e f
00: -- -- -- -- -- -- -- -- -- -- -- -- --
10: -- -- -- -- -- -- -- -- -- -- -- -- -- 1d -- --
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
70: -- -- -- -- -- -- -- --

ADXL345 のライブラリをDL

git clone https://github.com/pimoroni/adxl345-python

サンプルコードを動かす

cd adxl345-python
sudo python example.py

しかし動かしたところ以下のエラーが出た

IOError: [Errno 5] Input/output error

可能性を色々探ったがライブラリにアドレスが設定されていないことが問題だった
ということで
adxl345.pyの45行目のアドレス設定を以下のように変更

def __init__(self, address = 0x53):
↓
def__init__(self, address = 0x16):

すると動いた!
ちなみに完成した写真は以下
f:id:xhatenen:20141231005020j:plain

2 センサの値をMQTTブローカーを介してやりとりする

つぎに加速度センサをMQTTでやりとりできるプログラムを作成
まず、取得したx軸の値を一回だけ送信するプログラムを作成

from adxl345 import ADXL345
import sys
try:
    import paho.mqtt.publish as publish
except ImportError:
    import os
    import inspect
    cmd_subfolder = os.path.realpath(os.path.abspath(os.path.join(os.path.split(inspect.getfile( inspect.currentframe() ))[0],"../src")))
    if cmd_subfolder not in sys.path:
        sys.path.insert(0, cmd_subfolder)
    import paho.mqtt.publish as publish

adxl345 = ADXL345()

axes = adxl345.getAxes(True)
print "ADXL345 on address 0x%x:" % (adxl345.address)
print "   x = %.3fG" % ( axes['x'] )
print "   y = %.3fG" % ( axes['y'] )
print "   z = %.3fG" % ( axes['z'] )

publish.single("message", axes['x'], hostname="**********")

ラズパイ(Pub側)での結果

ADXL345 on address 0x1d:
   x = 0.004G
   y = 0.524G
   z = 0.792G

Sub側での結果

rc: 0
Subscribed: 1 (0,)
message 0 0.004

次に上記のコードを無限ループさせて加速度センサの値を取り続けるようにする

from adxl345 import ADXL345
import sys
try:
    import paho.mqtt.publish as publish
except ImportError:
    import os
    import inspect
    cmd_subfolder = os.path.realpath(os.path.abspath(os.path.join(os.path.split(inspect.getfile( inspect.currentframe() ))[0],"../src")))
    if cmd_subfolder not in sys.path:
        sys.path.insert(0, cmd_subfolder)
    import paho.mqtt.publish as publish

adxl345 = ADXL345()
num = 0
while num < 1:
        axes = adxl345.getAxes(True)
        print "ADXL345 on address 0x%x:" % (adxl345.address)
        print "   x = %.3fG" % ( axes['x'] )
        print "   y = %.3fG" % ( axes['y'] )
        print "   z = %.3fG" % ( axes['z'] )

        ax = str(axes['x'])
        ay = str(axes['y'])
        az = str(axes['z'])
        s = ":".join([ax,ay,az]);
        publish.single("message", s, hostname="**********")

Pub側の結果

ADXL345 on address 0x1d:
   x = 0.000G
   y = 0.056G
   z = 0.912G
ADXL345 on address 0x1d:
   x = 0.000G
   y = 0.052G
   z = 0.932G
ADXL345 on address 0x1d:
   x = -0.004G
   y = 0.040G
   z = 0.924G
ADXL345 on address 0x1d:
   x = 0.000G
   y = 0.044G
   z = 0.916G
ADXL345 on address 0x1d:
   x = 0.004G
   y = 0.060G
   z = 0.924G
ADXL345 on address 0x1d:
   x = -0.004G
   y = 0.056G
   z = 0.920G
ADXL345 on address 0x1d:
   x = 0.000G
   y = 0.048G
   z = 0.908G
ADXL345 on address 0x1d:
   x = -0.012G
   y = 0.064G
   z = 0.916G
ADXL345 on address 0x1d:
   x = 0.000G
   y = 0.052G
   z = 0.928G
ADXL345 on address 0x1d:
   x = -0.008G
   y = 0.060G
   z = 0.928G

Sub側の結果

rc: 0
Subscribed: 1 (0,)
message 0 0.0:0.056:0.912
message 0 0.0:0.052:0.932
message 0 -0.004:0.04:0.924
message 0 0.0:0.044:0.916
message 0 0.004:0.06:0.924
message 0 -0.004:0.056:0.92
message 0 0.0:0.048:0.908
message 0 -0.012:0.064:0.916
message 0 0.0:0.052:0.928
message 0 -0.008:0.06:0.928

ということでセンサの値をMQTTでやりとりできた