Packet Serial Read Loop

General discussion of using Roboclaw motor controllers
Post Reply
robof
Posts: 36
Joined: Tue Jun 27, 2017 11:21 pm
Packet Serial Read Loop

Post by robof »

I'm currently reading all the main status variables (the ones shown on 'Device Status' page in Ion Studio) in a loop, but I've found that without a sleep() inside the loop, the reads will stutter and eventually hang. I can restart the script and it will work again for a few seconds, but eventually it hangs again.

--Does this sound like a problem with the python serial package or could this be related to the roboclaw?

--Is there a recommended maximum read rate?

--Would there be any adverse affects in constantly polling a chain of Roboclaws as fast as the Roboclaws can respond (no sleep())? Such as processor heat build up? Or would the Roboclaw throttle the processor and delay responses if it got too hot?
User avatar
Basicmicro Support
Posts: 1594
Joined: Thu Feb 26, 2015 9:45 pm
Re: Packet Serial Read Loop

Post by Basicmicro Support »

I'd have to see your code to be sure. You shouldnt send the next command until the previous command has completed(eg either returned the request value or acked the command has been received). if you dont, you could eventually overflow the hardware serial buffer on the Roboclaw.

It wouldnt cause any hardware problems it would just corrupt the serial buffer. When a problem happens you would need to wait atleast 10ms for the roboclaw to clear its packet buffer(eg if the Roboclaw is in the middle of receiving a packet and there is a 10ms delay(or longer) between any byte of the packet it will drop the packet data).

In my own testing, I've run commands every 1 to 2ms. This is mainly limited to how fast the commands can be transmitted and respond.
robof
Posts: 36
Joined: Tue Jun 27, 2017 11:21 pm
Re: Packet Serial Read Loop

Post by robof »

The code is essentially just any Read command inside a while loop. Am I correct in thinking with the python code shown below it wouldn't be possible to send another read command until the previous was finished?

I can put a sleep in the while loop, >=10ms, and the problem appears to go away. I'm curious if this should work without the sleep and/or what could cause the problem.

Since my loop really doesn't look like the first code example below, it gets a bit more problematic if I need to put a 10ms sleep between every single read call.

If you're wondering what I'm getting at here, I am trying to monitor as much info as possible on all my Roboclaws in real-time, so any required sleeps, especially 10ms between each command, adds up.
Assuming I run the following commands in my loop, 24, 25, 48, 49, 82, 83, and 90, for all 8 Roboclaws, if I did the math right that would be 70ms * 8 == 560ms to get the values. Which that's not the end of the world, but I would like to be able to read faster if possible.

Simple example to show the freeze:

Code: Select all

from roboclaw import Roboclaw


rc = Roboclaw("/dev/ttyACM0", 115200)
if rc.Open():
    count = 0
    while True:
        rc.ReadMainBatteryVoltage(128)
        print(count)
        count += 1

More realistic/ real-world goal (sleeps added to show potential concern):

Code: Select all

from roboclaw import Roboclaw
import time


rc = Roboclaw("/dev/ttyACM0", 115200)
if rc.Open():
    count = 0

    while True:

        for address in range(128, 135):
            main_battery = rc.ReadMainBatteryVoltage(address)
            time.sleep(0.010)
            logic_battery = rc.ReadLogicBatteryVoltage(address)
            time.sleep(0.010)
            motor_pwms = rc.ReadPWMs(address)
            time.sleep(0.010)
            motor_currents = rc.ReadCurrents(address)
            time.sleep(0.010)
            temp1 = rc.ReadTemp(address)
            time.sleep(0.010)
            temp2 = rc.ReadTemp2(address)
            time.sleep(0.010)
            status = rc.ReadError(address)
            time.sleep(0.010)
        print(count)
        count += 1
User avatar
Basicmicro Support
Posts: 1594
Joined: Thu Feb 26, 2015 9:45 pm
Re: Packet Serial Read Loop

Post by Basicmicro Support »

1. We've had a report the Linux kernal 4.10(and possibly 4.12) has a problem with continously sending/receiving commands/data from the Roboclaw with no delays. Kernel 4.8 doesnt exhibit the problem. The problem has been traced to the kernel, the serial write/send command eventually freezes. Check your linux kernel version. If it is 10 or 12 you may need to add delays between sending commands to specific serial ports. Sleep is not specifically necessary. Interleaving multiple commands between multiple roboclaws may add the necessary delay without sleeping.

2. The python library sets a 10ms timeout on all read commands so by definition it will wait/block up to 10ms when reading status information. You may want to write your own interface if you are talking to multiple roboclaws(over different serial ports/usb ports), so you can use non-blocking read commands instead.
gdoisy
Posts: 33
Joined: Tue Oct 18, 2016 7:53 am
Re: Packet Serial Read Loop

Post by gdoisy »

@robof: I am trying to debug a similar issue here in case you want to participate: http://forums.ionmc.com/viewtopic.php?f ... 5&start=10
Which kernel are you using? (can you paste the output of a console call to "uname -r" ?)
robof
Posts: 36
Joined: Tue Jun 27, 2017 11:21 pm
Re: Packet Serial Read Loop

Post by robof »

@gdoisy, I am on 4.10 (Ubuntu 16.04)

So it sounds like that the cause of my issue.
gdoisy
Posts: 33
Joined: Tue Oct 18, 2016 7:53 am
Re: Packet Serial Read Loop

Post by gdoisy »

@robof: thanks for the details. A temporary fix that I am using is to stay with kernel 4.4 or 4.8 (default for Ubuntu 16.04.1 ad 16.04.2). You can choose which kernel to boot by default with grub customizer.

Post Reply