How can I get a response to an at-command using picocom?

269 Views Asked by At

I am using a router with OpenWrt 22.03.5 firmware and an EM7455 modem. I wrote a script using atinout to control the modem, but for some reason atinout (as well as echo+cat and socat) often sends incorrect commands. Commands work correctly only through picocom, so I want to rewrite the script using picocom.

Script:

#!/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

Example of sending incorrect commands

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:~#

Solution: execute 'stty -F /dev/ttyUSB2 raw -echo' before sending at-commands.

3

There are 3 best solutions below

0
larsks On

picocom is designed for interactive use; it's not going to be easy to use it as a replacement for atinout. You can try something like this:

status=$(
  echo 'at!gstatus?' | picocom -q -x 1000 -b 9600 /dev/ttyUSB0
)

The -x 1000 means "exit after 1 second"; without this picocom would exit before receiving any data.


I think atinout looks like a better tool for the job; it might be worth spending some time figuring out why you're getting errors.

1
TooTall On

echo+cat and socat aren't sending incorrect commands...the modem is in a constant state of output and the scripted commands are trying to execute in the middle of some of the output. I'm trying to figure out the same issue. How to interact via script with the modem. We need to wait for the "OK" then run our AT commands. I'm researching empty(1) and expect(1).

0
TooTall On

stty -F /dev/ttyUSB2 raw -echo

prior to running my AT command via echo/socat does not prevent the modem from continuously reporting status information. When my bash script runs AT commands, there are still errors returned periodically. It is luck of the draw whether a random AT command is running when socat tries to send my command.