Serial-Port

連接到串口,發出命令,讀取結果,擷取並退出

  • March 26, 2020

我有一些設備,連接到串口。實際上,它是Arduino基於溫度感測器的。

我希望編寫一個腳本,它將連接到串列埠,向設備發送命令,接收它的答案,將其列印到stdout並退出。

這樣做的正確方法是什麼?

通常,當訪問本地程序時,可以重定向它的輸出。例如,這就是我讀取CPU溫度的方式。

datetime=$(date +%Y%m%d%H%M%S)
cputemp=$(sensors atk0110-acpi-0 | sed "s/CPU Temperature:[^0-9]*\([0-9\.]\+\).*/\1/;tx;d;:x")
echo "$datetime\t$cputemp"

不幸的是,$()依賴於顯式程序結束,而串列通信則不是這樣。串列伺服器始終線上並且沒有明確的“會話”。

當然,我可以檢查換行符。但這是正確的做法嗎?可能我應該編寫我的Arduino程序,以便它Ctrl-Z在每次響應後發送還是什麼?

正如您所說,您無法從串列埠讀取文件結尾。(Ctrl-Z 是微軟的東西)。因此,通常,您會一直閱讀,直到獲得所需的字元數,或者直到找到一個分隔符(如換行符)來表示數據的結束。

例如,我有一個 USB 串列埠,其輸出連接回輸入,因此對設備的任何寫入都可以直接返回。以下腳本可以檢索設備發送的內容:

#!/bin/bash
tty=/dev/ttyUSB0
exec 4<$tty 5>$tty
stty -F $tty 9600 -echo
echo abcdef >&5
read reply <&4
echo "reply is $reply"

該腳本將串列設備連接為文件描述符 4 用於輸入,5 用於輸出,設置速度並停止為 tty 獲得的回顯,然後將“abcdef”和換行符寫入設備。每個字元都會被立即發回,但是核心驅動程序會緩沖一些輸入,所以我不需要在寫入之前開始從設備讀取。預設情況下,讀取會在看到換行符時結束,並將其保存在變數reply中,然後將其回顯到標準輸出。您可以將此腳本放在v=$()類型用法中。

如果您的串列設備數據不以換行符結尾,您可以為 bash 讀取指定不同的分隔符,使用-d. 或者,如果回复的長度恆定,您可以使用 指定長度-n。如果您有二進制數據,您可能應該添加raw到 stty 命令以停止對輸入的任何特殊處理。

引用自:https://unix.stackexchange.com/questions/231975