第7号(2022年05月30日)

Raspberry Piのデジタル入力

はじめに

 簡単に機器の稼働監視がしたい!ということで初心者がRaspberry Piを使って機器の運転信号を監視する装置を作成してみたので紹介します。

Raspberry PiとPython

 まずはどのように運転信号を監視するか、ですが今回は大きさや手軽さの面からRaspberry Piを採用しました。
 Raspberry Piはシングルボードコンピュータで、大きさも名刺サイズなのにインターフェースが充実していますし、
 教育目的で開発されたのもあって、値段も安価です。
 開発言語はPythonを使用しました。Pythonとは世界的に人気のあるプログラミング言語の一つです。
 PythonはWindows、Mac、Linuxなど様々なOSに対応しており、Raspberry Piでも標準でインストールされています。
 開発環境を作らなくて良いというのは非常に助かります。

デジタル入力値監視

 取得したい運転信号は24Vデジタル値です。
 Raspberry PiはGPIOが掲載されているのでほかのデバイスと簡単に信号をやり取りできるようになっています。
 ブレッドボードを使って回路を作成するといろいろな機器に接続できますが、今回は簡単に拡張ボードを使用することにします。
 今回取得したい運転信号は24Vデジタル値なのでデジタル入出力の拡張ボードを購入しました。
 使用した拡張ボードはこちらの製品です。
 拡張ボードRaspberry Piに乗せるだけでOKです。
 様々な拡張ボードがあるのもRaspberry Piの魅力の一つですね。
 24Vの出力は機器が手元にないので24Vパワーサプライにスイッチをつけてデバッガにします。
 写真にはたくさんスイッチがありますが、使用するのは1つだけにします。
 スイッチ側のケーブルと拡張ボードのケーブルを繋げたらデバッグの準備は完成です。

デジタル入力監視プログラム

 拡張ボードのサイトにあるサンプルプログラムを参考に、デジタル入力値を監視します。
 せっかくなので取得した値はソケット通信でPCに送ってみたいと思います。
 Raspberry Piをクライアント側、WindowsPCをサーバ側とします。
クライアント側
                                                     import socket
import time
import smbus

PCA9535_REG_INPUT_PORT1 = 1
PCA9535_REG_OUTPUT_PORT0 = 2
PCA9535_REG_CONFIG_PORT0 = 6
HOST_IP = "XXX.XXX.XXX.XXX" # 接続するサーバーのIPアドレス
PORT = 9999 # 接続するサーバーのポート
DATESIZE = 10 # 受信データバイト数

class DIO_8_4RD_IRC():
    i2c = smbus.SMBus(1)

    def __init__(self, slave=0x23):
        self.address = slave
        self.i2c.write_byte_data(self.address, PCA9535_REG_CONFIG_PORT0, 0xf0)

    # デジタル出力
    def output(self, value):
        self.i2c.write_byte_data(self.address, PCA9535_REG_OUTPUT_PORT0, ~value)

    # デジタル入力
    def input(self):
        return ~self.i2c.read_byte_data(self.address, PCA9535_REG_INPUT_PORT1) & 0xff

            
if __name__ == '__main__':
    expander = DIO_8_4RD_IRC()
    client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)      
    client_socket.connect((HOST_IP, PORT))
    
    intputStatus = 99
    while True:
        # IOInputの確認
        nowStatus = expander.input()
        # 値が変わっていればソケット送信
        if intputStatus != nowStatus:
            input_data = nowStatus.to_bytes(2, 'little')
            client_socket.send(input_data) # データ送信
            print('Send data : ',input_data)    
 
            sendReturn = client_socket.recv(DATESIZE) # データ受信
            sendReturn = sendReturn.decode('utf-8')
            print('recv data : ',sendReturn)
            
            # 
            intputStatus = nowStatus
        time.sleep(1)
 DIO_8_4RD_IRCクラスでデジタル値を取得しています。
 毎秒デジタルI/Oを監視し、値が変わったときに値がSocket通信されます。
サーバ側
                                        import socket

HOST_IP = "XXX.XXX.XXX.XXX" # 接続するサーバーのIPアドレス
PORT = 9999 # 接続するサーバーのポート

if __name__ == '__main__':
    
    recvline = ''
    sendline = ''
    num = 0

    # Socket接続
    socket1 = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    socket1.bind((HOST_IP, PORT))
    socket1.listen(1)

    while True:
        
        print('クライアントからの入力待ち状態')

        # コネクションとアドレスを取得
        connection, address = socket1.accept()
        print('接続したクライアント情報:'  + str(address))

        # 無限ループ byeの入力でループを抜ける   
        while True:
            
            # クライアントからデータを受信
            recvline = connection.recv(5)
            recv = int.from_bytes(recvline, 'little')
            print('クライアントで入力された文字=[' + str(recv)+"]")

            sendline = 'OK'.encode('utf-8')
            connection.send(sendline)
 サーバ側は値を受け取ったらOKを返します。
 異常処理等は割愛しています。
 このソースを動かしてデバッガのスイッチのOFFの状態からON→OFFすると、実行結果は以下のようになります。
サーバ側
                                        クライアントからの入力待ち状態
接続したクライアント情報:('XXX.XXX.XXX.XXX', 99999)
クライアントで入力された文字=[0]
クライアントで入力された文字=[1]
クライアントで入力された文字=[0]
クライアント側
                                        Send data :  b'\x00\x00'
recv data :  OK
Send data :  b'\x01\x00'
recv data :  OK
Send data :  b'\x00\x00'
recv data :  OK
 Raspberry Piのデジタル値がサーバ側で受信出来ていることがわかります。

まとめ

 Raspberry Piでデジタル値を取得することができました。
 Socket通信でPCに稼働状況を送っているため、このデータを使って稼働監視することが可能です。
 Raspberry Pi自体も小さいですし、拡張モジュールもスタッキングできるので省スペースなので様々な場所で使用できると思います。
 また、今回初めてPythonで開発を行ってみたのですが、ソケット通信プログラムが他の言語に比べて比較的簡単だと感じました。
 別の言語を学習済みの方であれば、多少の文法の書き方の違いに戸惑うこともあれどすぐに習得出来るのではないでしょうか。
 Pythonの魅力はライブラリの豊富さや、汎用性の高さにあると思いますので、今後も勉強していきたいです。
一覧へ戻る