如何使用picocom获取AT命令响应?OpenWrt下EM7455脚本改造需求
用picocom替代atinout重写EM7455调制解调器控制脚本
我在搭载OpenWrt 22.03.5固件的路由器上使用EM7455调制解调器,原本用atinout编写了控制脚本,但atinout(包括echo+cat、socat)经常发送错误命令,比如截断命令、出现乱码。只有通过picocom手动执行命令时能正常工作,因此想改用picocom重写脚本。
原atinout脚本
#!/bin/sh modemPort=$(ls /dev/ttyUSB* | tail -n 1) echo "$modemPort" | grep -E -o -q -i "ttyUSB" || exit 0 status=$(echo "at!gstatus?" | atinout - $modemPort -) hexGoodBS="08199120" if echo "$status" | grep -E -o -q -i "Normal Service"; then if ! echo "$status" | grep -E -o -q -i "Cell ID:\s*$hexGoodBS\s*\(\d+\)"; then echo "at!band=09" | atinout - $modemPort - fi elif echo "$status" | grep -E -o -q -i "Attach Needed"; then if echo "at!band?" | atinout - $modemPort - | grep -E -o -q -i "Band_3"; then if echo "$status" | grep -E -o -q -i "Cell ID:\s*$hexGoodBS\s*\(\d+\)"; then echo "at!band=09" | atinout - $modemPort - sleep 3 echo "at!band=03" | atinout - $modemPort - else echo "at!band=09" | atinout - $modemPort - fi fi elif echo "$status" | grep -E -o -q -i "(No (Cell|band)|PLMN Search)"; then if ! echo "at!band?" | atinout - $modemPort - | grep -E -o -q -i "LTE ALL"; then echo "at!band=09" | atinout - $modemPort - #LTE ALL fi fi ifup EM7455
命令发送错误示例
root@Xiaomi-Mi-Router-3G:~# echo at!gstatus? | atinout - /dev/ttyUSB2 - at!b ERROR root@Xiaomi-Mi-Router-3G:~# echo at!gstatus? | atinout - /dev/ttyUSB2 - ERROR root@Xiaomi-Mi-Router-3G:~# echo at!gstatus? | atinout - /dev/ttyUSB2 - at!gstatus? !GSTATUS: Current Time: 26655 Temperature: 33 Reset Counter: 1 Mode: ONLINE System mode: LTE PS state: Not attached LTE band: No band LTE bw: 1.4 MHz LTE Rx chan: 0 LTE Tx chan: 4294967295 LTE CA state: NOT ASSIGNED EMM state: Deregistered Attach Needed RRC state: RRC Idle IMS reg state: No Srv PCC RxM RSSI: 0 RSRP (dBm): 0 PCC RxD RSSI: 0 RSRP (dBm): 0 Tx Power: -- TAC: FFFF (65535) RSRQ (dB): 0.0 Cell ID: FFFFFFFF (4294967295) SINR (dB): OK root@Xiaomi-Mi-Router-3G:~# echo at!gstatus? | atinout - /dev/ttyUSB2 - ERROR root@Xiaomi-Mi-Router-3G:~# echo at!gstatus? | atinout - /dev/ttyUSB2 - at!gren E cttacIrFat!gstatus? ERROR root@Xiaomi-Mi-Router-3G:~#
临时解决方案
发送AT命令前执行:stty -F /dev/ttyUSB2 raw -echo
重写后的picocom脚本
#!/bin/sh modemPort=$(ls /dev/ttyUSB* | tail -n 1) echo "$modemPort" | grep -E -o -q -i "ttyUSB" || exit 0 # 封装picocom发送AT命令的函数,过滤无关输出 send_at_cmd() { local cmd="$1" # 波特率115200为EM7455默认值,可根据实际调整;-t 2设置2秒超时 echo -e "$cmd\r" | picocom -b 115200 -t 2 "$modemPort" 2>/dev/null | grep -vE "(picocom|Terminal ready|exit|^$)" } hexGoodBS="08199120" status=$(send_at_cmd "at!gstatus?") if echo "$status" | grep -E -o -q -i "Normal Service"; then if ! echo "$status" | grep -E -o -q -i "Cell ID:\s*$hexGoodBS\s*\(\d+\)"; then send_at_cmd "at!band=09" fi elif echo "$status" | grep -E -o -q -i "Attach Needed"; then band_status=$(send_at_cmd "at!band?") if echo "$band_status" | grep -E -o -q -i "Band_3"; then if echo "$status" | grep -E -o -q -i "Cell ID:\s*$hexGoodBS\s*\(\d+\)"; then send_at_cmd "at!band=09" sleep 3 send_at_cmd "at!band=03" else send_at_cmd "at!band=09" fi fi elif echo "$status" | grep -E -o -q -i "(No (Cell|band)|PLMN Search)"; then band_status=$(send_at_cmd "at!band?") if ! echo "$band_status" | grep -E -o -q -i "LTE ALL"; then send_at_cmd "at!band=09" #LTE ALL fi fi ifup EM7455
脚本说明
- 新增
send_at_cmd函数,统一处理AT命令的发送与结果过滤,避免picocom自身输出干扰 - 设置2秒超时时间,防止脚本无限等待
- 屏蔽picocom的错误输出,只保留调制解调器返回的有效内容
内容的提问来源于stack exchange,提问作者vars-cat
相关产品推荐
相关产品推荐

