DYNAMIXEL Actuator
XC330-T181-T (V46 firmware)
Issue Description
I am trying to update the firmware on my XC330 motors (from V46 to V50) using Dynamixel Wizard 2.0.
I have an Arduino MKR Zero with Dynamixel Shield for Arduino MKR and was wondering if it is possible to perform a firmware update using this controller, or if I need to use a different setup (e.g. U2D2 + SMPS2Dynamixel).
I found several examples for USB passthrough to make Arduino + Dynamixel Wizard 2.0 work together, e.g.:
OpenCR github repo (usb_to_dxl.ino)
OpenRB-150 github repo (usb_to_dynamixel.ino)
Dynamixel2Arduino github repo (partial implementation: add_custom_SerialPortHandler.ino)
I āwroteā a minimum working example based on the three code samples above:
#include <DynamixelShield.h>
#define COMPUTER_USB Serial
#define DXL_PACKET_BUFFER_LENGTH 1024
uint8_t packet_buffer[DXL_PACKET_BUFFER_LENGTH];
unsigned long led_update_time = 0;
DynamixelShield dxl;
void setup() {
// put your setup code here, to run once:
// set USB connection for communication with Dynamixel Wizard 2.0
COMPUTER_USB.begin(57600);
// set DXL direction pin to baseline
digitalWrite(DXL_DIR_PIN, LOW);
while(digitalRead(DXL_DIR_PIN) != LOW);
// Set Port baudrate to 57600bps. This has to match with DYNAMIXEL baudrate.
dxl.begin(57600);
}
void loop() {
// put your main code here, to run repeatedly:
dataTransceiver();
}
void dataTransceiver()
{
int length = 0;
int i = 0;
// USB -> DXL (set dxl direction pin high during TX to dxl)
length = COMPUTER_USB.available();
if( length > 0 )
{
digitalWrite(DXL_DIR_PIN, HIGH);
while(digitalRead(DXL_DIR_PIN) != HIGH);
for(i = 0; i < length; i++)
{
DXL_SERIAL.write(COMPUTER_USB.read());
}
DXL_SERIAL.flush();
digitalWrite(DXL_DIR_PIN, LOW);
while(digitalRead(DXL_DIR_PIN) != LOW);
}
// DXL -> USB
length = DXL_SERIAL.available();
if( length > 0 )
{
if( length > DXL_PACKET_BUFFER_LENGTH )
{
length = DXL_PACKET_BUFFER_LENGTH;
}
for(i = 0; i < length; i++)
{
packet_buffer[i] = DXL_SERIAL.read();
}
COMPUTER_USB.write(packet_buffer, length);
}
}
This works fine to receive data from the XC330 and modify the control table (screenshot example):
Unfortunately, the firmware update gets stuck at the following screen:
I tried the āRecoveryā option but it gets stuck here (to āturn off powerā I am just unplugging the 12V SMPS, and then plugging it in a few seconds later, because the DynamixelShield for MKR doesnāt have a power switch):
Any advice is appreciated! If there is a reason this wonāt be possible, I can just buy the separate U2D2 + SMPS2Dynamixel, but it seems so close to actually working. At least, I hope this can help anyone trying to get the Dynamixel Wizard 2.0 working with DynamixelShield.
One thing I noticed is that the code example from OpenCR has:
drv_dxl_tx_enable(TRUE);
for(i=0; i<length; i++ )
{
DXL_PORT.write(CMD_PORT.read());
DXL_PORT.flush();
}
drv_dxl_tx_enable(FALSE);
While my example has:
digitalWrite(DXL_DIR_PIN, HIGH);
while(digitalRead(DXL_DIR_PIN) != HIGH);
for(i = 0; i < length; i++)
{
DXL_SERIAL.write(COMPUTER_USB.read());
}
DXL_SERIAL.flush();
digitalWrite(DXL_DIR_PIN, LOW);
while(digitalRead(DXL_DIR_PIN) != LOW);
Because putting DXL_SERIAL.flush()
inside the for loop made most writes to DXL fail (for example, ping and reboot worked, but writing to control table or turning torque on did not).
So maybe I am missing something else with the buffering/serial reading/flushing to allow for the (larger?) firmware communication to occur. Or, the implementation is too slow reading one byte at a time and the buffer fills up? Or, there is some other limitation related to firmware updates Iām unaware of.
Thank you for reading!