Serial-Port
連接到串口,發出命令,讀取結果,擷取並退出
我有一些設備,連接到串口。實際上,它是
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 命令以停止對輸入的任何特殊處理。