width ラズベリーパイとTWELITEを無線で接続する

ラズベリーパイとTWELITEを無線で接続する
目次

TWELITEとつなぐには
作成するソフト


TWELITEとつなぐには
無線機能を有するマイコンTWELITEとRaspberry Piをつなぐにはどうするか?
まずTWELITEが必要です。(当たり前!)

通信するためのインターフェースはどうする?
I2C      これはセンサーなどを接続するために使うので候補外。
UART     ラスベリーパイと端子電圧が3Vで同じなので使えそう。
デジタルIO  通信が遅ければつかえる。しかしこれは面倒。

UARTなら簡単にできそうだが、折角無線機能があるのに有線接続ではもったいない。また長い距離に対応できない。

そこで無線通信をするためのデバイスとしてMONOSTICを使うことにしました。

USBコネクタに接続します。ラズベリーパイから見るとUARTデバイスです。

ラスベリーパイとMONOSTICは親機にします。子機(TWELITE)から送られてくるセンサーのデータを受信します。送信はしません。sad取得したデータをシリアル通信を介してラスベリーパイに送信します。

TWELITEは子機にします。I2Cで接続した温度・湿度・気圧センサーBME280と接続します。I2Cのセンサーは知っている限り2種類あり、SCLとSDAのピンは位置が違っています。悪いことに見た目が似ています。よく説明書をみて結線してください。
TWELITEはセンサーから取得したデータを1秒に1回送信します。受信はしません。

作成するソフト

以下はC++のソースなので説明は割愛します。
TWELITE
温度・湿度・気圧センサーBME280 のデータを取得する機能
取得したデータを無線で送信する機能
ダウンロード:sensor.zip

MONOSTIC
子機から送信されてデータを受信
受信したデータをシリアル通信でラズベリーパイへ送信
ダウンロード:Sensor-MONOSTICK.zip

そしていよいよラズベリーパイによるシリアル通信のプログラムです。ファイル名はtwe-lite.pyです。早速コードを

# -*- coding: utf-8 -*-
import serial
import threading

g_Serial = None
g_rxData = None
g_bRxFinish = False
g_bQuit = False
#RX232C受信スレッド関数
def rx232c():
    global g_bRxFinish, g_rxData, g_bQuit
    while(True):
        if(g_bQuit == True):
            break
        rxData = g_Serial.read()
        if(rxData == b'\n'):
            g_bRxFinish = True
        else:
            if(g_rxData == None):
                g_rxData = rxData
            else:
                g_rxData += rxData
            
def isRxData():
    global g_rxData
    if(g_rxData == None):
        return False
    if(g_rxData.find(b'T=') == -1):
        return False
    if(g_rxData.find(b'H=') == -1):
        return False
    if(g_rxData.find(b'P=') == -1):
        return False
    return True
    



def main():
    global g_Serial,g_bRxFinish, g_rxData, g_bQuit
    g_Serial = serial.Serial('/dev/ttyUSB0', 115200)
    threadRx = threading.Thread(target=rx232c)
    threadRx.start()
    num = 1
    try:
        while(g_bQuit == False):
            if(g_bRxFinish == True):
                g_bRxFinish = False
                if(isRxData() == True):
                    print('{:4d}  {}'.format(num, g_rxData))
                else:
                    print('RX data is invalid.')
                g_rxData = None
                num += 1
    except KeyboardInterrupt:
        #print('control C')
        g_bQuit = True
        threadRx.join()
        g_Serial.close()

if __name__ == "__main__":
    main()
シリアル通信を行うにはスレッドという仕組みをつかう必要があります。逆に使わないとどうなるか? 受信データが来ないと受信データ待ちでプログラムが停止してしまいます。これでは他の処理が動かなくなってしまいます。こ れを解決するためにスレッドを使って並列処理を実現します。 パソコンでワープロで文書をつくりながら表計算でグラフを見るというのは当たり前ですが、並列にワープロと表計算が動いているわけです。 もちろんOSも並列に動いています。

シリアル通信:
pySerialが必要です。最新版のOSをインストールしたのならすでに入っています。
確認の方法
pip3 list
で表示されます。入ってないのなら
pip3 install pyserial
でインストールできます。

シリアルの使い方:
インポートが必要
import serial

初期化
main()内で、
g_Serial = serial.Serial('/dev/ttyUSB0', 115200)
これだけです。ボーレートを115200に設定しています。また、ttyUSB0は環境によって違います。自分で調べてください。

スレッドの開始:
main()内で、
threadRx = threading.Thread(target=rx232c)
threadRx.start()

rx232cという関数がスレッドになります。この関数で受信の処理をします。
スレッド:rx232c
TCCOSTICから送られてくる通信データは、
T=18 H=45 P=1013 '\n'
です。
1文字受信してそれが改行なら受信完了とします。
そうでなければ受信バッファに蓄えます。

受信完了のフラグが立つと
main()内で、
isRxData()で受信データの正誤を判定して、データを表示します。

終了:
コントロールCによる割込みで終了します。
except KeyboardInterrupt:
のところです。
出力:


これだけだと地味過ぎすので、
取得したデータを
記録する
グラフで表示する
webページにのせる
などいろいろ考えられます。