Romba 651 and reading sensors via bash

Inside the Roomba and Scooba and more, Cool mods, Repair and Upgrades - including the all new iRobot Create Kit. Let's void that warranty baby!

Romba 651 and reading sensors via bash

Postby Schievel » February 3rd, 2017, 5:04 pm

Hello my fellow Roomba hackers!

I am having some trouble with my Roomba 651 lately. But first, what am I trying to do:
I connected a RaspberryPi3 with USB to Serial FTDI-Board. The onlyt stuff I want to do later is setting the Roomba to 'Start cleaning', setting it to 'Search for Dock' and to check the Battery-Charge.
Since this is so basic I didn't choose to use a 'real' Programming language, bash scripting should be enough. Well, at least I thought so.
So what I am doing is the following:
I set my /dev/ttyUSB0 up with

stty -F /dev/ttyUSB0 speed 115200

and send it commands with

echo -ne '\x80' > /dev/ttyUSB0 or
echo -ne '\x87' > /dev/ttyUSB0

Whereas the '\x80' is the command in Hex. Hex80 is 130 in decimal. Hex87 is start cleaning. This works alright. (I got these values from this document http://www.robotappstore.com/files/KB/R ... Manual.pdf)
Now when I am trying to read the battery charge status, at least from what I understand I should be sending 142 to request the sensors values followed by a 3 to select the subset with the battery charge status. So from what I understand my command should be

echo -ne '\x8E\x03' > /dev/ttyUSB0

And this is where things go crazy.
When I send 8E 03 in hterm, it sends be back something which looks like it is the stuff I am looking for. (see screenshot) This even works, when I send the 8E 03 in a terminal. So I send it in my terminal and get the same response in hterm as I would get when I would send it in hterm.
So what I am doing to test this for my script in terminal is, I wrote a short bash script. This runs in one terminal, echoes everything incoming from the serial port, and also stores the last line in a file. Looks like this:

#!/bin/bash

stty -F /dev/ttyUSB0 115200 cs8 -cstopb -parenb
while true; do
read -n 10 LINE < /dev/ttyUSB0
echo $LINE
echo $LINE > text.txt
done

(I know this wont give me anything useable, because I need to record the data in anything other than ASCII, but it should at least return something.)
Now I open up a second terminal and send
echo -ne '\x8E\x03' > /dev/ttyUSB0

And then my Roomba starts in 'Spot' mode. At least I think this is Spotmode, because it starts cleanung and the Spotbutton on it is blinking.
Also the script is returning gibberish, well that's good.

Now I thought maybe I'm a bit too dump for this, so I got me pycreate for Python. (https://github.com/mgobryan/pycreate)
Thing is, when I give it a r.getSensor('BATTERY') it does exactly the same! Starts spot cleaning. It doesnt do anything when I try to read the other sensors.

So do you guys have any idea what I should do with this? I also saw many people build their own boards for serial communication. So is my method with the FTDI even working properly? Because sometimes my Roomba stops talking over serial altogether and I need to reset it by disconnecting the battery.

Hope you can help me. I am a bbit confused by now. :(
Schievel
 
Posts: 6
Joined: February 3rd, 2017, 9:30 am

Re: Romba 651 and reading sensors via bash

Postby mfortuna » February 4th, 2017, 9:19 am

This is what I did with my Intel Edison card. The BAUD rate is for the older 400 series.

root@mike_edison:~# stty -F /dev/ttyUSB0 speed 57600
57600
root@mike_edison:~# stty -F /dev/ttyUSB0 raw
root@mike_edison:~# stty -F /dev/ttyUSB0 -echo -onlcr
root@mike_edison:~# printf '\x80\x82' > /dev/ttyUSB0
root@mike_edison:~# cat /dev/ttyUSB0 | hexdump -n 26 &
root@mike_edison:~# printf '\x8e\x00' > /dev/ttyUSB0
root@mike_edison:~# 0000000 0002 0000 0000 0000 0000 00ff 0200 feff
0000010 3c00 ffaa 1e64 8b09 8e0a

I can also turn on and off the side brush motor:

printf '\x8a\x01' > /dev/ttyUSB0
printf '\x8a\x00' > /dev/ttyUSB0
Mike
Reds x 3, Dirt Dog, Disco (now a parts bot), Create, Scooba 350, and Security Dawg
Evolution Mint
Neato XV-11
User avatar
mfortuna
Robot Master
 
Posts: 5771
Joined: February 5th, 2006, 10:35 am
Location: NH

Re: Romba 651 and reading sensors via bash

Postby Schievel » February 6th, 2017, 5:17 pm

Thanks man, that really helped me.

While I figured out a third way to read the raw data via
socat /dev/ttyUSB0,raw,echo=0,readbytes=26 SYSTEM:'tee sensvalraw'
i found that sending this with an echo command makes the Roomba act weird, while sending it via printf works.

This is where things get a bit weird, because both commands shouldn't act any different in this case.
Anyway, huge thanks for pointing me in the printf direction. :thumbup: :thumbup: :thumbup:
Schievel
 
Posts: 6
Joined: February 3rd, 2017, 9:30 am

Re: Romba 651 and reading sensors via bash

Postby Schievel » February 6th, 2017, 5:37 pm

Alright, so for anyone who comes around here, these are my two scripts for reading the battery sensor.
Unfortunately comments are in german, because it's a school project.

Code: Select all
#!/bin/bash
stty -F /dev/ttyUSB0 115200 raw
stty -F /dev/ttyUSB0 -echo -echoe -echok

# socat /dev/ttyUSB0,raw,echo=0,readbytes=26 SYSTEM:'tee sensvalraw'

cat /dev/ttyUSB0 | hexdump -n 10 -v -e '10/1 "%03u " "\n"' > sensval

#hexdump -v -e '10/1 "%03u " "\n"' sensvalraw > sensval # ueberspringe 5 bytes und konvertiere den inhalt von sensvalraw zu dezimalen zahlen uns speichere dies in sensval
echo $(cat sensval)       
exit 0


Code: Select all
#!/bin/bash

minbat="255"
maxbat="2295"

while read -t 0 var < /dev/ttyUSB0; do continue; done # flushe serial port

./inreader & # rufe skript zum leasen des Inputstreams der Seriellen IO als Deamon auf
sleep 1
printf '\x80' > /dev/ttyUSB0
printf '\x8e\x03' > /dev/ttyUSB0
printf '\x8e\x03' > /dev/ttyUSB0
printf '\x8e\x03' > /dev/ttyUSB0 # sende sensor-request drei mal um mit Sicherheit die 10 bytes fuer inreader zu fuellen.

sleep 2 # gib inreader etwas zeit zum einlesen der daten
input=$(cat ./sensval)
echo Input: $input
inputlaenge=$(echo $input | wc -c)
echo Laenge: $inputlaenge
stringend=$(cut -c37-39 sensval)
echo Stringende: $stringend
if [ $stringend -ne "136" ]; then
    echo "Inputende Fehlerhaft"
    exit 0
fi

if [ $inputlaenge -ne "40" ]; then
    echo "Inputlaenge fehlerhaft"
    exit 0
fi

oktett1=$(cut -c25-27 sensval)
oktett2=$(cut -c29-31 sensval)
    echo Oktett1: $oktett1
    echo Oktett2: $oktett2

    wert=$(echo $((($((10#$oktett1))*255) + (10#$oktett2))))
    echo Chargewert: $wert
    echo $wert >> werte.txt

if [ $wert -lt $minbat ]; then
    echo Unter $minbat
    exit 1
fi

if [ $wert -gt $maxbat ]; then
    echo Ueber $maxbat
    exit 2
fi

echo Zwischen $minbat und $maxbat
exit 0


So right now hexdump is converting every byte into a three digit decimal number. Output of the first script looks like this:
000 123 435 010 009 102 etcetc...

For my purpose that is enough, but the batteries charge is send in a 2-byte value, so one has to acutally combine these two bytes. But other sensor values are stored in 1-byte values, so you need to change your way of conversion during conversion. hexdump can help you with this:
https://www.suse.com/communities/blog/m ... e-hexdump/

Hope this is helpful for anyone.
Schievel
 
Posts: 6
Joined: February 3rd, 2017, 9:30 am

Re: Romba 651 and reading sensors via bash

Postby mfortuna » February 11th, 2017, 9:48 am

Glad you got it working and thanks for sharing the code.
Mike
Reds x 3, Dirt Dog, Disco (now a parts bot), Create, Scooba 350, and Security Dawg
Evolution Mint
Neato XV-11
User avatar
mfortuna
Robot Master
 
Posts: 5771
Joined: February 5th, 2006, 10:35 am
Location: NH


Return to Robotic Hacking

Who is online

Users browsing this forum: 3kgt, a1robotrepair, vic7767 and 401 guests