Loopback/Echo bytes received over serial port - linux

On an embedded Linux system running Busybox I am trying to receive bytes over a serial port and echo back everything received.
The system setup is like this:
Linux <-USB-> FTDI chip <-UART-> MCU
On the UART line I have a logic analyser monitoring the data between the FTCI chip and the MCU. Both the MCU and Linux have the same UART configuration.
The script I have written runs on the Linux system and is supposed to send back all data it received from the MCU.
So far I have this simple Bash script which is to receive bursts of data 62 bytes long. The timeout is set to 5 seconds as a sort of alive signal.
#!/bin/bash
# Enable debugging
set -x
# Set the baudrate of the port
stty -F /dev/ttyUSB0 1500000
while true
do
# Read 62 bytes with a timout of 5 seconds to variable RESP.
read -N62 -t5 RESP < /dev/ttyUSB0
# Print out how many bytes we received
echo ${#RESP}
# Send back the data, -n for no trailing new line
echo -n $RESP > /dev/ttyUSB0
done
There are a few problems I have with this script:
Not all bytes are received consistently. I've been testing now for some time an only seen the full number of bytes once.
It outputs only 0xFF values on the UART bus, this is observed through the logic analyser.
What am I missing here in order to receiving the correct data and send it back correctly?

Through the suggestions made by #sawdust I was able to get a working script.
In the end I stopped using the read command. I was unable to get it to work in raw mode. I could not use termios as this in to available on my Busybox system. I got a working setup using dd:
#!/bin/bash
stty -F /dev/ttyUSB0 raw
stty -F /dev/ttyUSB0 1500000
dd if=/dev/ttyUSB0 count=62 of=/dev/ttyUSB0

Related

Reading from a USB device using bash and raspberry pi 3?

I'm trying to catch the response from a device that is connected to the USB.
With this code:
sudo stty -F /dev/ttyUSB0 speed 115200 cs8 -cstopb -parenb -echo
sudo stty raw; cat > /home/received.log < /dev/ttyUSB0
echo "Monitor started"
On port ready, send the command request to the device
echo -en '\x5A\x00\x00\x0D\x0A\x71' > /dev/ttyUSB0
then read the log and paste the response in another file converting it properly
xxd -plain /home/received.log > /home/output.txt
so I can show the data,
cat -v < /home/output.txt
But I'm needing something more stable, that code is showing me this error:
stty: 'standard input': Inappropriate ioctl for device
which is weird, because it was working...
I would like to catch the response and store it in a variable.
i suggest getting rid of the stty raw.
Unless you are sending/receiving special characters that the tty subsystem will process, which is unlikely - because you said it is working - you almost certainly won't need it.
If it did work, you might find some undesirable side effects such as:
backspace does not erase a character that you miss-typed
control-c won't terminate your process
and other things that you might rely on in your terminal session.
FWIW, i am doing a similar thing with Arduino to Mac, Windows (cygwin) & Linux (read from the usb/serial port) and i have not been tempted to stty raw in any of those environments.

How to determine cause of weird characters from serial console

Good Morning,
i'm trying to work out the reason to weird characters being outputted in a serial console in linux.
Device:
12d1:15c1 Huawei me906s module in a WWAN to USB adapter (working for normal operations and switches modes etc
The device is connected initially with the PID 15c1 and the output of lsusb -v below:
12d1:15c1 Output
When the device is sent the AT Command of AT^GODLOAD, it switches into download mode which changes its PID too 1568. Output of lsusb -v below:
12d1:1568 Output
OS:
Ubuntu 16.10
Speed:
9600 baud as reported by stty -F /dev/ttyUSB0
Expected: Send AT Commands through /dev/ttyUSB0 with minicom or echo/cat
Result and Description:
When the device is in normal mode (15c1) the device ttyUSB0 is used to send AT Commands, this works perfectly and we can set the chip into download mode (PID 1568)
After Download mode is enabled the chip reboots and reconnects too ttyUSB0, however weird characters show up in minicom and through terminal using 'cat
The weird characters are the same in both monitors and the hex is:
7e 03 00 06 9e 4c 7e
When we send any AT command in download mode the characters show up, except for one AT command as shown in the pictures. This command is significantly larger than any other ones.
Command examples which don't work in GODLOAD:
AT+CMGR?
ATI
-Results in the weird characters ~[][][][]L~
Command which does work:
AT^SIGNVER=5,0,1234567891011121314151617181920, 8502
We have used wireshark to capture the update process on a windows machine.
I actually have screen shots of the operation, commands etc but cannot post them due to limit.
Questions:
-Does the packet size matter for serial commands sent to the module?
-Are we missing some form of a line ending, carriage return or termination to start/end the message correctly?
Thanks for your help in advance

Using gnu screen to access serial port

I am trying to access a device which is attached to a USB-serial port. The settings are 57600 baud, 8 bit, 1 stop bit, no parity. The device outputs a status line every second and accepts typed commands.
I would like to use GNU screen to initiate 2 way communications, so I am using this command:
screen /dev/ttyS2 57600,cs8
However I just get a blank screen, nothing received from the device.
The communication is fine using teraterm, and I can also do this
stty -F /dev/ttyS2 57600 cs8
cat /dev/ttyS2
to see the status output from the device.
I've tried various combinations of ixon, ixoff, crtscts, and clocal but nothing makes any difference.
How can I determine what the correct command should be?
I am using Cygwin on Windows 10.
I faced the same issue with gnu-screen, I started using plink.exe instead from the PuTTY suite. It's not optimal, but it does the job. In my case serial is just for recovery, not for everyday usage.
Start PuTTY, create a profile with your serial connection.
Name and save the connection.
From cygwin, run: '/cygdrive/c/Program\ Files\ (x86)/PuTTY/plink.exe -load SerialProfile'

echo command to serial port in Linux

I want to echo something from my Ubuntu host to some device.
It works well if I use putty or minicom.
However, it doesn't work if I do echo from the shell terminal:
echo "cmd" > /dev/ttyUSB0
From my device, I saw that the first letter of the cmd is received correctly while the second one received is ASCII bigger than 200. I also have tried to use the "stty" command to adjust the serial communication settings but didn't help. Does anythone know why?
Thanks,
First You need to set the tty device settings and then you need to transmit the data whatever you want
stty -F /dev/ttyUSB0 9600 -parity cs8 -cstopb
OR
stty -speed 9600 < /dev/ttyUSB0
Now Send data:
echo "cmd" > /dev/ttyUSB0

How i can read tty file with timeout?

I have tty device in /dev , where I send AT commands. I want to read line by line and stop reading file after timeout.
You can use the program stty to configure the tty device. To see the settings for terminal /dev/ttyS0, try
stty -a -F /dev/ttyS0
The default settings regarding timeout are min = 1; time = 0, which means that the reading program will read until at least one character has been read and there is no timeout. Using e.g.
stty -F /dev/ttyS0 min 0 time 10
the reading program (e.g. cat) will finish reading after one second whether anything has been read or not. The unit for the parameter time is tenths of a second; you can check out man stty for more information.
Compiling some info from here, you can have a script in the sorts of:
#!/bin/bash
#SPECIFYING THE SERIAL PORT
SERIAL=ttyS0
#SETTING UP AN ERROR FLAG
FLAG="GO"
#OPENING SERIAL PORT FOR READING
exec 99</dev/${SERIAL}
#READING FROM SERIAL
while ["${FLAG}" == "GO" ]
do
#IF NO INPUT IS READ AFTER 5 SECONDS, AN ERROR FLAG IS RAISED
read -t 5 INPUT <&99
STATUS=$?
if test $STATUS -ne 0;
then
FLAG="ERROR"
fi
done
#CLOSING SERIAL PORT
exec 99>&-
While FLAG==GO, the script will read one line at a time from the serial port. The STATUS variable gets the return of READ command. According to the manual READ will return anything different than 0 if the specified timeout is reached; when that happens, FLAG is updated, exiting the read loop.

Resources