2014年4月26日土曜日

Raspberry pi で Hydroponic に挑戦 (5) MinipH I2C pH interface から Rawデータ取得

今日は MinipH I2C pH Interface board をRaspberry pi に繋いで pH のRaw データを取得することを目指す。このボードを使用した Arduino のサンプルプログラムはネット上にあるのだが、Raspberry pi、Python 上で使用するサンプルプログラムが見つからない。そこでこのボードで使用している A/Dコンバータ MCP3211 を使用したPython のサンプルプログラムを探してみるが、これも全く見つからない。困ったなぁ。自力でコードを書かなければ・・・・・・・
3枚のインターフェースボードを入手したのだが、そのうちの2枚が同じアドレスのため一つのI2Cバス上では2枚までしか使用できない。とりあえずは2枚のインターフェースボードを使用することにし、残りの一枚は別のアドレスのボードに交換してもらうよう製作者に依頼する。


2枚のボードを繋ぐ。

このインターフェースボードは I2C プロトコルでRaspberry pi と通信を行う。Raspberry pi はすでに I2C セットアップを済ませてあるので、sudo i2cdetect -y 1 とタイプし、2枚のボードのアドレスが認識されることを確認する。


アドレスは 0x4c と 0x4e

Raspbian には SMBus (System Management Bus) という I2Cのサブセット通信プロトコルが用意されているので、このプロトコルを使用して I2C 機器と通信を行う。
1枚のボードに pHプローブシュミレータを繋ぎ、 pH を 4,7,10 と変化させて、データを読み取るSMBusコマンドをいくつか試してみる。データは取得できるのだが、どれもpH の変化に対応していない。困ったなぁ。
そこで、A/Dコンバータ MCP3211 のデータシートSMBus Protocol Summary を見比べてみる。すると MCP3211 の12bit データは Upper Data Byte、Lower Data byte の順に送り出されるのに対して、 SMBus プロトコルで i2c_smbus_read_word_data() はLower Data byte、 Upper Data byte の順に読み込まれることになっている。それなら i2c_smbus_read_word_data() でデーターを読み、その 16bit データーの上位バイトと下位バイトを入れ替えれば良いはずだ。そこで ネット上にある バイトを入れ替えるプログラムを参考に Python でコードを書いてみる。


############################################################
#                                                          #
#    Read pH data from 2 MinipH I2C pH interface boards   #
#                                                          #
############################################################

import smbus
import time

bus = smbus.SMBus(1)
pH_address = [0x4c, 0x4e]

def readRawpH(address):
    raw_word= bus.read_word_data(address, 1)
    swapped_word = swap_bytes(raw_word)
    
    return swapped_word

def swap_bytes(word):
    byte_low = word & 0x00FF
    byte_high = (word & 0xFF00) >> 8
    swapped_high = byte_low << 8
    swapped_word = swapped_high + byte_high

    return swapped_word   

while True:
    for ad_index in range(len(pH_address)):
        i = 0
        raw_ph = 0
        while i < 100:
            raw_ph += readRawpH(pH_address[ad_index])
            time.sleep(0.01)
            i += 1
        raw_ph = raw_ph / 100
        print'Sensor#%d: %d,' % (ad_index,raw_ph), 
    time.sleep(1)
    print



このプログラムを走らせてみると、


pH4の時 Rawデータ は約1000、 pH7で約2000、pH10で約3000 となった。pH0 で 0, pH14 で 4095(12bit) とすればおおよそ合っているようだ。

0 件のコメント:

コメントを投稿