I have 3 motor controllers (18V7) connected thru USB to a Raspberry PI 2 My program is in Python 3.2 and uses pyserial to access the 18V7’s thru USB serial. My problem is that binary commands that should return responses sometimes don’t return a response (3 second timeout). Forward commands turn the motor so commands seem to be working even when responses are no longer returning. A linux reboot will sometimes fix the problem but not always. Power off everything fixes the problem most of the time.
My python3 probram does write() and read() to send commands and receive the response.
Any idea’s on how I can fix this problem or at least diagnose where I’m having the problem?
It sounds like you are using the Simple Motor Controller (SMC) 18v17, but it is not clear from your description what could be causing the issue. You mentioned that you have 3 SMCs connected to your Raspberry Pi. Each motor controller is directly connected to your Raspberry Pi with a USB cable, right?
Can you post your entire code here so that I can see if there is something in your code that could be causing the problem? Also, can you post pictures of your setup and provide more information about the motors you are using? (A link to the motor’s product page would be great.)
Thanks Amanda. I found the problem is that the SMC USB gives you less than 10 milliseconds to read the response before it flushes the response and the read must wait for the timeout.
serial.write( b'\xA1\x01' ) # get errors variable
time.sleep(0.01) # delay 10 milliseconds before read
serial.read(2) # read response fails because it's too late
Controllers (e.g. UNO) don’t have a problem because they are dedicated to a single program where you can easily avoid delays…
Computers can easily have this problem because they are multi-process and multi-threaded. Many things can be scheduled at any time. I won’t go all things that can cause delays because it’s complicated to understand system internals.
Embedded computers tend to be slow and limited on memory.so they will tend to have this problem much more frequently.
The solution is
Sorry, accidentally hit reply.
The solution is to use a very small timeout and immediately retry the write and read if the read failed. In my case, I’m now using TIMEOUT=0.003 and retry 3 times.
Great! I am glad that you figured out the issue; thank you for letting us know how you resolved it. I am sure others, who encounter a similar issue, will find your solution helpful.
By the way, for future reference, you can make edits to your posts (e.g. including missing information, adding updates, and making corrections).
Hello, Jon. We did not design the Simple Motor Controllers to flush or erase a USB serial response like that. There might be a problem with your serial library, or maybe some other program on your computer is reading data from the serial port every 10 milliseconds, preventing your program from getting the data.
I tried to reproduce your problem here, but was unable to. I used a Raspberry Pi Model B+ v1.2 and a Simple Motor Controller 24v12 with firmware version 1.04 and the default settings. The Raspberry Pi was running Python 3.4.2, pySerial 3.0.1, and Raspbian Jessie. The output of “uname -src” was “Linux 4.1.13+ #826 PREEMPT Fri Nov 13 20:13:22 GMT 2015”. Here is the code I used, which worked fine for me every time I ran it:
serial = serial.Serial('/dev/ttyACM0')
result = serial.read(2)
for c in result: print('0x' + format(c, '02x'))
The code above sleeps for 100 milliseconds. I also tried sleeping for 1 second and saw no issues.