View Full Version : [Question(s)] Ping Dynamixels with a Broad Cast ID

10-07-2012, 02:51 AM
Hi guys,

Its been a while since my last posts. I have to thank this forum for a great start into Robotics and its been a year since I started with the Arbotix board.

I want to get back to basics and implement some of the core Dynamixel Instructions. Till today I have not seen someone who has implemented the AX-12 Dynamixel Instruction Packet. I have read and understood the document well. I have implemented the Ping Instruction. However its never consistent.

Would someone please show me a working example of a Dynamixel Ping Instruction that uses "ax12ReadPacket(length)" correctly and works 100% of the time.

Here is a good start for all.

ax12writeB(255-((pinId + 0x02 + AX_PING) % 256));

if (ax12ReadPacket(6) > 0)
Serial.write(ax_rx_buffer[2]); // Servo ID
Serial.write(ax_rx_buffer[4]); // Error
Serial.write((255-((ax_rx_buffer[2] + 0x02 +ax_rx_buffer[4]) % 256)));

Here is my question :

1. If you use a Broadcast ID the line "if (ax12ReadPacket(6) > 0)" can not have a value of 6. And since you don't know the number of Dynamixels attached at any given time, how do you implement it correctly? I would love to see some code or improvements to the ax12ReadPacket(length).

2. If someone could shed some light/experience would be greatly appreciated. There are times when I run the Ping instruction I get an ID back, there are other times only a hand full of the servos attached to the Arbotix respond back and after a few pings the rest of the ID return.

3. Look at the following code in AX12.h file

#define AX12_BUFFER_SIZE 32

extern unsigned char ax_rx_buffer[AX12_BUFFER_SIZE];
extern unsigned char ax_tx_buffer[AX12_BUFFER_SIZE];
extern unsigned char ax_rx_int_buffer[AX12_BUFFER_SIZE];

Surely the above (32) is a limitation and needs to be changed. If I execute the "Read Data" instruction and request to read the "complete" Control Table, I would be requesting to read 50 Bytes or 0x32. Is that a miss type? As in did the original creators intend to write 0x32 and not 32 ? Or have I simply lost my marbles ? Which is entirely possible :)

1. I do have ample amount of Volts and Amps (30Vx30A) Power supply currently set to 13.5V.
2. Using FTDI Cable
3. Running all sorts of Serial speeds ranging from 19200 - 115200
4. 6 x AX-12A Dynamixels

I am by no means an expert here. I am just a hobbyist who loves his robotics and know programming well enough to be dangerous. :cool: (Currently using C# / Visual Studio 2012 / Visual Micro Plugin)

Thanks in advance as always.

10-07-2012, 06:28 AM
1 & 2) You cannot use the PING or READ instructions with the broadcast ID. None of the servos will know how many other servos are on the bus, and all packets with the broadcast ID are treated exactly the same by all servos on the bus. If Robotis did not include a filter in the servo code to ignore PING and READ commands using the Broadcast ID, then every single servo on the bus would attempt to simultaneously send a response packet to each request resulting in mostly garbage on the bus (if you actually get any useful packets, it is very surprising to me). If you want to find out how many servos are on the bus and what their ID's are, then use a loop to read the ID register of each servo ID in sequence up to some number. Something like:

short servos;

for (int id=1; id<17; id++)
int receivedID = ax12GetRegister(id, AX_ID, 1);
if (receivedID == id)
servos |= (1<<(id-1)); // store valid/existing servo ID's in a bit mask (0x08 means servos 1 and 4 are found)
// could just as easily use a byte array for recording available servos, but using a bit mask would be more memory efficient

3) That buffer length is enough to receive 4 packets reporting a servo's current position. Rarely will you ever need to read more than 2 bytes from a single servo, so a buffer length of 32 works fine for controlling the dynamixels with an interpolating motion engine (arbotix with poses or NUKE). This does have the expectation that one will read the incoming packet very shortly after sending the command packet.

10-10-2012, 07:48 AM
Spot on Tician.

Here is an extract from the AX-12 manual.

"Regardless of whether the Broadcasting ID is used or the Status Return Level (Address
16) is 0, a Status Packet is always returned by the PING instruction."

It clearly tells me that it's OK to use the Broadcast ID. That's how I interpreted that. However Tician, you make perfect sense. Using the Broadcast ID causes ALL the servos to respond at the same time. Giving you unpredictable results. This has been the case with me which explains why when you continuously ping with Broadcast ID will eventually give you all the servos.

Solution as stated by Tician.
Change the code to loop through all the possible servos : 0 - 253 inclusive. Once I did that, I got consistent information every time.

Thank again to this forum, and especially Tician to point out what now seems so obvious.


10-10-2012, 08:38 AM
Spot on Tician.
"Regardless of whether the Broadcasting ID is used or the Status Return Level (Address
16) is 0, a Status Packet is always returned by the PING instruction."

It clearly tells me that it's OK to use the Broadcast ID.

It is simply saying a servo will always respond to a ping request. If anything that quote is a warning.