- Written by Kyle Granat
These arms are controlled by the ArbotiX Robocontroller. This microcontroller handles the low level communications with the DYNAMIXEL servos, and the inverse kinematics engine. The goal is to be able to send a serial packet from the computer to the ArbotiX Robocontoller (using a USB-to-FTDI deive) and have the arm move to a position in space.
However before the program can start issueing commands, it must connect
- Connect to a Serial Port
- Check if an arm is present on the port
- Get the information about the arm (the arm type)
The last two parts of this can be acomplished by sending the ArbotiX an ID request. If this packet is sent on serial connection that an ArbotiX (running the ArmControl code)0 is on, the ArbotiX will send a return packet with the Arm ID. Originally the arm's initial control structure looked something like this whenever the ArbotiX is powered on/reset
Start Serial Port -> Wait 50ms -> Put Arm in Sleep Mode -> Start Accepting Packets
The problem with this structure is that therer can be a significant delay from when the ArbotiX is reset until the ArbotiX starts accepting packets. Putting the arm in sleep mode involves noving the arm to a pre-defined position, then turning the servo's torque off. Sleep mode can take several seconds if the arm is not near the 'sleep' position. Now for connecting to a serial port where you are certain of which port you are on, this delay isn't too terible - maybe 5 seconds in the worse case. But what if we want to implement Auto-Search? If we have 4 ports available, it can take 20 seconds just to connect to the arm! So I suggested a change to the control structure to this:
Power Arm On -> Start Serial Port -> Wait 50ms -> Send ID Packet -> Put Arm in Sleep Mode -> Start Accepting Packets
Now in this case, whenever the arm is reset, before it goes to sleep, it broadcasts the ID packet.
I thought I finally had a elegant solution to my problem - whenever the serial port was connected to, it would reset the ArbotiX, the ArbotiX would send the packet within 60ms - meaning I would only need to wait 60ms on any port to watch for a response. But after a bit of testing with different hardware and software I found something very odd: My FTDI-USB cable (that ships with each arm) was acting very stangley on windows 7 - after I initially connected to the arm, I could not reconnect. It seemed that the java drivers would reset the FTDI-USB device when it first connected, but not sunsequent times it was connected. Here are some of my findings.
|OS||FTDI Hardware||Software Driver||Resets on first connect?||Resets on consequential connects?|
|Mac 10.8||UartSBee||Java RX/TX Library(Processing)||Yes||Yes|
|Mac 10.8||UartSBee||Java RX/TX Library(Arduino)||Yes||Yes|
|Mac 10.8||FTDI-USB Cable||Java RX/TX Library(Processing)||Yes||Yes|
|Mac 10.8||FTDI-USB Cable||Java RX/TX Library(Arduino)||Yes||Yes|
|Mac 10.8||FTDI-USB Cable||Other(Terminal)||Yes||Yes|
|Windows 7||UartSBee||Java RX/TX Library(Processing)||Yes||Yes|
|Windows 7||UartSBee||Java RX/TX Library(Arduino)||Yes||Yes|
|Windows 7||UartSBee||Other (RealTerm)||Yes||Yes|
|Windows 7||Arduino Uno||Java RX/TX Library(Arduino)||Yes||Yes|
|Windows 7||Arduino Diecimila||Java RX/TX Library(Arduino)||Yes||Yes|
|Windows 7||FTDI-USB Cable||Java RX/TX Library(Processing)||Yes||No|
|Windows 7||FTDI-USB Cable||Java RX/TX Library(Arduino)||Yes||No|
|Windows 7||FTDI-USB Cable||Other (RealTerm)||Yes||Yes|
This problem is somewhat exacerbated by the fact that there are no good ways to turn on/off the reset behavior using the java libraries. So the lesson here is that you really can't rely on the reset behavior of FTDI devices. I was struck by the fact that this problem was only with a certain kind of FTDI-USB device, on windows 7, with the java libraries.