ArduinoからRaspberryPiなどにシリアル通信でデータを送信する


Arduinoからシリアル通信でデータを送信する

IoTのシステムを作ってるとarduinoでセンサからのデータを受信してそれをraspberrypiなどに送信したい場合があると思います。
そこで今回はarduinoからのシリアル通信についてまとめていきたいと思います。
特に今回はデータをJSON形式で送ってあげることで受信側で処理しやすくしています。

システムの部分

今回は受信側にJetson Xavier NXを用いています。
受信側はpython環境があればなんでも大丈夫です。USBで直接arduinoと受信側をつないでいる形になります。

センサは今回は溶存酸素センサをを用いていますが特になんでも大丈夫です。

Arduinoの実装

Arduino側ではデータの送信を行います。
データの送信と言っても単純にシリアルボードに表示させているだけなので特に難しいことはありません。

Serial.println(data);

dataに送りたいデータが入っています。
ポイントとなるのはprintlnを用いている部分になるかと思います。
println関数を用いることでデータの最後に改行コードが挿入されます。
そうすることで後の受信側のコードでデータ1つあたりの区切りとして認識することが可能になります。

JSON形式で送る場合

 データを受信した際に処理をしやすくするためにJSON形式で送ってあげたい場合もあるかと思います。
 そのような場合はArduino公式がだしているArduinoJsonが非常に便利です。

ツール=>ライブラリを管理を選択

Arduino_Jsonを選択

Jsonの作成

まずライブラリのインポートします

#include <Arduino_JSON.h> 

次にJson用に変数docを用意します。これはsetup関数の前で宣言しておきます。

JSONVar doc;

docに対してキーを指定して入れることでJSONの完成です

doc["DO"] = do_data; //センサの値を辞書に登録
Serial.println(doc); //Jsonが出力される

forで繰り返しデータを取得し、表示している例になります。うまくJSONになってくれています。

受信側

受信側はpythonで実装しています。
pythonにはpyserialという便利なライブラリがあるので利用します。

pip3でインストールを行います。

pip3 install pyserial

コードの実装はこのようになります。

import serial
import time

ser = serial.Serial('/dev/ttyACM0', 9600)
time.sleep(5)

while True:
    String_data = ser.readline()
    #print(String_data)
    print(String_data.strip().decode())
ser.close()

ポイントとしてはrealline関数でデータを受信する部分になります。
改行コードがあるまでを1行として認識して読み取りを行っています。

そのままでは改行コードが残ってしまうためstrip関数で除去し、最後にバイト列からデコードをして文字列に変換しています。

最後に

シリアル通信は非常に簡単に実装できると思いました
JSONで送ってるのでセンサが増えても受信側で問題なく対応できると思います!