Packet Serial Read Loop
Packet Serial Read Loop
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?
--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?
- Basicmicro Support
- Posts: 1594
- Joined: Thu Feb 26, 2015 9:45 pm
Re: Packet Serial Read Loop
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.
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.
Re: Packet Serial Read Loop
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:
More realistic/ real-world goal (sleeps added to show potential concern):
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
- Basicmicro Support
- Posts: 1594
- Joined: Thu Feb 26, 2015 9:45 pm
Re: Packet Serial Read Loop
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.
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.
Re: Packet Serial Read Loop
@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" ?)
Which kernel are you using? (can you paste the output of a console call to "uname -r" ?)
Re: Packet Serial Read Loop
@gdoisy, I am on 4.10 (Ubuntu 16.04)
So it sounds like that the cause of my issue.
So it sounds like that the cause of my issue.
Re: Packet Serial Read Loop
@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.