ラズパイ(Raspberry Pi)で取得した温度データ、距離センサデータなどをM5stackの画面に表示したい。M5stackにはWifi通信機能が付いているが、今回のデータ通信は、あえてシリアル通信とする。M5stackのボタンを押してテキストでコマンドをラズパイに送信すると、ラズパイからM5stackに数値データが返信されてくるというスクリプトを書く。
M5stackの画面に表示するデータをラズパイから送信したい。M5stackのボタン3つに音波距離センサーの'Sonic'や'Date'、'Time'というテキストを送信するスクリプトを割り当てする。ラズパイはそれらのテキストを受信したら、対応するスクリプトを実行して結果をM5stackへ送信する。M5stackはループ処理でデータ受信を調べ、ラズパイはデータ受信を割り込み処理で受け付ける。
配線図
最初に[ttyAMA0]を無効にしておくこと。
sudo systemctl status serial-getty@ttyAMA0.service sudo systemctl stop serial-getty@ttyAMA0.service sudo systemctl disable serial-getty@ttyAMA0.service
pythonで書いたラズパイ側のスクリプト。
#!/usr/bin/env python # -*- coding: utf-8 -*- import serial import threading import datetime import time import wiringpi as pi serCom = serial.Serial('/dev/ttyAMA0', 115200, timeout = 1 ) class serialRead(): def __init__(self): self.threadRead = threading.Thread( target = self.target ) self.threadRead.start() def target(self): flag=True while flag: if( serCom.inWaiting() > 0 ): strC = serCom.read( serCom.inWaiting() ) print( "[%s]" % strC ) if( strC == "Sonic"): num = 0 while num < 10: num = num + 1 strDistance = mesure() serCom.write( strDistance ) print( strDistance ) time.sleep(1.0) if( strC == "Date" ): objDate = datetime.date.today() strDate = objDate.strftime("%Y/%m/%d") serCom.write(strDate) print(strDate) if( strC == "Time"): objTime = datetime.datetime.now() strTime = objTime.strftime("%H:%M:%S") serCom.write(strTime) print(strTime) def quit(self): flag=False def main(): print( "Start reading..." , serCom.portstr ) while True: try: strA = raw_input("send: ") serCom.write( strA ) print( "[%s] sent" % strA ) if( strA == "exit" ): serCom.close() threadRead.quit() exit() except: serCom.close() threadRead.quit() exit() def sonicInit(): global TRIG_PIN global ECHO_PIN global pi TRIG_PIN = 18 ECHO_PIN = 17 pi.wiringPiSetupGpio() pi.pinMode( TRIG_PIN, pi.OUTPUT ) pi.pinMode( ECHO_PIN, pi.INPUT ) pi.digitalWrite( TRIG_PIN, pi.LOW ) def mesure(): pi.digitalWrite( TRIG_PIN, pi.HIGH ) time.sleep(0.00001) pi.digitalWrite( TRIG_PIN, pi.LOW ) while ( pi.digitalRead( ECHO_PIN ) == pi.LOW ): sigoff = time.time() while ( pi.digitalRead( ECHO_PIN ) == 1 ): sigon = time.time() strTemp = str( round((( sigon - sigoff ) * 34000) / 2, 5 )) + "cm" time.sleep(1.0) return ( strTemp ) if __name__ == '__main__': sonicInit() threadRead = serialRead() main()
Arduino IDEでコンパイルしてM5stackに書き込む。
#include <M5Stack.h> HardwareSerial Serial2(2); void setup() { M5.begin(); // Serial2.begin(unsigned long baud, uint32_t config, int8_t rxPin, int8_t txPin, bool invert) Serial2.begin(115200, SERIAL_8N1, 16, 17); M5.Lcd.setTextColor(TFT_WHITE,TFT_BLACK); M5.Lcd.setTextSize(2); M5.Lcd.setCursor(0, 0, 4); M5.Lcd.println("M5 UART start...(^^)/~~~"); M5.Lcd.setTextColor(RED); M5.Lcd.setCursor(0, 200, 2); M5.Lcd.println("
M5stackのボタンを押したらテキストコマンドが送信される。ラズパイがコマンドに応じた処理結果を返信してM5stack画面に表示する。
ラズパイの'/dev/ttyAMA0'デバイスを無効にしないとシリアル通信が出来ないことを知らず1ヶ月近く悩んだ。ついにはラズパイをもう1台買ってきて、ラズパイ対ラズパイのシリアル通信で検証してみてttyAMA0デバイスがデフォルトで有効になっていることが分かり、これを無効化したらシリアル通信が出来る事をようやく確認できた。今回はテキストを送受信するスクリプトの検証が出来たので、次は本当にやりたかったことに着手する。