🙆

Zao SDKを使ってPythonでシリアルデータを扱う方法:Socatを活用

2023/06/29に公開

はじめに 🚀

シリアル通信 (UART, RS232C) はPC間の通信だけでなく各種電子機器との通信やセンサーデータを収集したりする際に幅広く利用されています。

Zao SDKでは、映像信号だけでなくシリアルデータを送受信することができます。
基本的にはJetson側、PC側それぞれに動作確認済みのUSBシリアルケーブルを接続するだけで、Zao SDKが仮想的なクロスケーブルとなり、遠隔の機器とシリアル通信が可能となります。

この記事では、USBシリアルケーブルを通じて通信をするのではなく、Zas SDK for Jetsonが動作しているJetson上のPythonスクリプトでZao SDKのシリアルトンネリング通信を行う方法を解説します。

仕組み 🔍

この記事ではsocatを用いて Jetson 内部に仮想的なシリアルクロスケーブルを作り出します。
socatがクロスケーブルの両端に相当する仮想シリアルポート 2個を生成しますので、Pythonスクリプト、Zao SDK for Jetsonはそれぞれの仮想シリアルポートに向かって通信を行います。

ログイン

既にZao SDKが動作している場合は、Jetson Nano の画面はZao SDKのTUI画面になっているはずです。 以降の操作をするためにログインが必要ですのでAlt+F2を押下してtty2のログイン画面に移ってログインして下さい。 TUI画面に戻る場合はAlt+F1入力で戻れます。

仮想シリアルクロスケーブルの作成 🧙‍♂️

sudo vim /etc/systemd/system/socat-cross.service等でテキストエディタ起動し、以下内容のファイルを配置します。

/etc/systemd/system/socat-cross.service
[Unit]
Description=socat virtual serial cross cable
Before=zao-remote-endpoint.service

[Service]
User=zao
Group=zao
UMask=027
Type=simple
ExecStart=/usr/bin/socat pty,raw,echo=0,link=/run/zao/ttyZAOV0,group=dialout,mode=660 pty,raw,echo=0,link=/run/zao/ttyZAOV1,group=dialout,mode=660
Restart=always

[Install]
WantedBy=multi-user.target

以下コマンドでサービスを有効化しておきます。

sudo systemctl enable socat-cross.service

これで再起動以後は自動的に仮想シリアルケーブルが存在する形となりました。
/run/zao/ttyZAOV0, /run/zao/ttyZAOV1という2つの仮想シリアルポートが作られますので、それぞれをZao SDK for Jetson、Pythonスクリプトがアクセスするようにします。

Zao SDK for Jetson の設定調整

Zao SDK for Jetsonのシリアルトンネリングが仮想シリアルポート/run/zao/ttyZAOV0にアクセスするように設定ファイルを調整します。

sudo vim /usr/local/etc/zao/SerialProxyTty.conf等としてテキストエディタ起動し、以下内容に編集します。

/usr/local/etc/zao/SerialProxyTty.conf
# ファイル内でSERIAL_TTY_DEVICEの値を編集します
SERIAL_TTY_DEVICE=/run/zao/ttyZAOV0

これで再起動以後は、Zao SDK for Jetsonのシリアルトンネリングは仮想クロスケーブルに向いて動作するようになりました。✨

Pythonスクリプトの作成 🧙‍♀️

Python でシリアルポートを使うためにあらかじめ pyserial をインストールします。

sudo apt install python3-serial

以下は、Pythonでシリアルデータを送受信する簡単な例です。
sudo vim /usr/local/bin/serial-app.py等としてテキストエディタ起動し入力してください。

/usr/local/bin/serial-app.py
import serial
 
port = "/run/zao/ttyZAOV1"
baud = 115200

#シリアルポートをオープン
ser = serial.Serial(port, baud)

while True:
  #シリアルデータを受信    
  data_received = ser.read(1)

  #シリアルデータを送信	
  ser.write(b'Rx:')
  ser.write(data_received)
  ser.write(b'\r\n')

次にJetson起動時に自動的に起動されるように/etc/systemd/system/serial-app.serviceを作成します。

/etc/systemd/system/serial-app.service
[Unit]
Description=Serial App for Zao SDK
Before=zao-remote-endpoint.service

[Service]
User=zao
Group=zao
UMask=027
Type=simple
ExecStart=/usr/bin/python3 /usr/local/bin/serial-app.py
Restart=always

[Install]
WantedBy=multi-user.target

以下のコマンドでサービスを有効化しておきます。

sudo systemctl enable serial-app.service

動作確認

  1. Jetsonを再起動して、Zao Cloud ViewでJetsonからのライブ配信を受信している状態にします。
  2. ライブ配信画面左上のシリアルアイコンをクリックしシリアルトンネリング動作を開始します。
  3. PC側のシリアルポートに何かデータを送信すると、Jetsonへ送られPythonスクリプトが返信した内容が受信されるはずです。

あとは、Jetson側のPythonスクリプトを拡張していけば、様々な通信・処理が可能となります。🚀🚀

関連資料

Discussion