DYNAMIXEL servos: Difference between revisions
Ida Allander (talk | contribs) No edit summary |
Ida Allander (talk | contribs) No edit summary |
||
| Line 5: | Line 5: | ||
== Dependencies == | == Dependencies == | ||
* Install the library DynamixelShield in the Arduino IDE | * Install the library DynamixelShield in the Arduino IDE | ||
** GitHub: https://github.com/ROBOTIS-GIT/DynamixelShield | ** GitHub: https://github.com/ROBOTIS-GIT/DynamixelShield | ||
| Line 12: | Line 13: | ||
This script is based on the example code provided with the DynamixelShield Arduino library. | This script is based on the example code provided with the DynamixelShield Arduino library. | ||
Some modifications were required to make it work with the MKR Zero board, MKR | Some modifications were required to make it work with the MKR Zero board, the MKR shield, and the Dynamixel motor used in this setup. | ||
The main changes are: | The main changes are: | ||
* The shield communicates through '''Serial1''' on the MKR Zero. | * The shield communicates through '''Serial1''' on the MKR Zero. | ||
* The port baudrate had to be set to '''1,000,000''' | * The port baudrate had to be set to '''1,000,000''' because the motor did not respond when using the default baudrate in the original example. | ||
* Debug output is sent to the Arduino Serial Monitor. | * Debug output is sent to the Arduino Serial Monitor. | ||
| Line 25: | Line 26: | ||
In the loop the motor is commanded to move to different positions. | In the loop the motor is commanded to move to different positions. | ||
The position is set once using a raw value and once using degrees, and the current motor position is printed to the Serial Monitor. | The position is set once using a raw value and once using degrees, and the current motor position is printed to the Serial Monitor. | ||
A raw position value corresponds to the internal encoder value of the motor, while '''UNIT_DEGREE''' allows the position to be set using degrees. | |||
== Source code == | == Source code == | ||
| Line 87: | Line 90: | ||
} | } | ||
</pre> | </pre> | ||
== Alternative simple test == | |||
The following script is a simpler test program that only moves the motor between two positions (0° and 90°). | |||
This can be useful to quickly verify that the motor and shield are working correctly. | |||
<pre> | |||
#include <DynamixelShield.h> | |||
#define DXL_SERIAL Serial1 | |||
#define DEBUG_SERIAL Serial | |||
DynamixelShield dxl(DXL_SERIAL); | |||
const uint8_t ID = 1; | |||
void setup() { | |||
DEBUG_SERIAL.begin(115200); | |||
while(!DEBUG_SERIAL); | |||
dxl.begin(1000000); | |||
dxl.setPortProtocolVersion(2.0); | |||
DEBUG_SERIAL.println("Motor connected!"); | |||
dxl.torqueOff(ID); | |||
dxl.setOperatingMode(ID, OP_POSITION); | |||
dxl.torqueOn(ID); | |||
} | |||
void loop() { | |||
DEBUG_SERIAL.println("Move to 90°"); | |||
dxl.setGoalPosition(ID, 90, UNIT_DEGREE); | |||
delay(3000); | |||
DEBUG_SERIAL.println("Move to 0°"); | |||
dxl.setGoalPosition(ID, 0, UNIT_DEGREE); | |||
delay(3000); | |||
} | |||
</pre> | |||
== Find motor ID == | |||
If the motor ID is unknown, the following script can be used to scan for connected Dynamixel motors. | |||
The script tries to ping motors with ID values between 0 and 19 and prints the detected ID in the Serial Monitor. | |||
This is useful if the motor does not respond to commands because the wrong ID is used in the control script. | |||
<pre> | |||
#include <DynamixelShield.h> | |||
#define DXL_SERIAL Serial1 | |||
#define DEBUG_SERIAL Serial | |||
DynamixelShield dxl(DXL_SERIAL); | |||
void setup() { | |||
DEBUG_SERIAL.begin(115200); | |||
while(!DEBUG_SERIAL); | |||
dxl.begin(1000000); | |||
dxl.setPortProtocolVersion(2.0); | |||
DEBUG_SERIAL.println("Scanning for motors..."); | |||
for(int id=0; id<20; id++){ | |||
if(dxl.ping(id)){ | |||
DEBUG_SERIAL.print("Motor found with ID: "); | |||
DEBUG_SERIAL.println(id); | |||
} | |||
} | |||
} | |||
void loop(){} | |||
</pre> | |||
== Troubleshooting == | |||
Common issues when working with Dynamixel motors: | |||
* The motor does not respond → check that the correct '''baudrate''' is used. | |||
* The motor is not detected → verify the '''motor ID''' using the scan script. | |||
* No movement → make sure '''torque''' is enabled. | |||
* Communication problems → confirm that the shield switch is set to '''TTL'''. | |||
* Motor not powered → check the external power supply connected to the shield. | |||
Revision as of 11:30, 6 March 2026
Dynamixel motor control (MKR Zero)
- Product DYNAMIXEL Shield for Arduino MKR Series: https://store.arduino.cc/products/dynamixel-shield-for-arduino-mkr-series?srsltid=AfmBOoq7ptPLfwzykpUecfmQo3vii_8N3padSzJVAQ7RiUqJHuECxUOW
- Product Dynamixel XL-320 Servo: https://store.arduino.cc/products/dynamixel-xl-320
Dependencies
- Install the library DynamixelShield in the Arduino IDE
Description
This script is based on the example code provided with the DynamixelShield Arduino library. Some modifications were required to make it work with the MKR Zero board, the MKR shield, and the Dynamixel motor used in this setup.
The main changes are:
- The shield communicates through Serial1 on the MKR Zero.
- The port baudrate had to be set to 1,000,000 because the motor did not respond when using the default baudrate in the original example.
- Debug output is sent to the Arduino Serial Monitor.
The script first checks if the motor is connected using ping(). If the motor responds, torque is enabled and the operating mode is set to position control.
In the loop the motor is commanded to move to different positions. The position is set once using a raw value and once using degrees, and the current motor position is printed to the Serial Monitor.
A raw position value corresponds to the internal encoder value of the motor, while UNIT_DEGREE allows the position to be set using degrees.
Source code
/*******************************************************************************
* ROBOTIS Example - Fixed for MKR Zero
*******************************************************************************/
#include <DynamixelShield.h>
#define DXL_SERIAL Serial1
#define DEBUG_SERIAL Serial
const uint8_t DXL_ID = 1;
const float DXL_PROTOCOL_VERSION = 2.0;
DynamixelShield dxl(DXL_SERIAL);
//This namespace is required to use Control table item names
using namespace ControlTableItem;
void setup() {
DEBUG_SERIAL.begin(115200);
while(!DEBUG_SERIAL);
// Set Port baudrate (motor responded at 1,000,000)
dxl.begin(1000000);
dxl.setPortProtocolVersion(DXL_PROTOCOL_VERSION);
DEBUG_SERIAL.println("Pinging motor...");
if(dxl.ping(DXL_ID))
DEBUG_SERIAL.println("Motor connected!");
else
DEBUG_SERIAL.println("Motor NOT detected!");
dxl.torqueOff(DXL_ID);
dxl.setOperatingMode(DXL_ID, OP_POSITION);
dxl.torqueOn(DXL_ID);
}
void loop() {
dxl.setGoalPosition(DXL_ID, 512);
delay(1000);
DEBUG_SERIAL.print("Present Position(raw) : ");
DEBUG_SERIAL.println(dxl.getPresentPosition(DXL_ID));
delay(1000);
dxl.setGoalPosition(DXL_ID, 90, UNIT_DEGREE);
delay(1000);
DEBUG_SERIAL.print("Present Position(degree) : ");
DEBUG_SERIAL.println(dxl.getPresentPosition(DXL_ID, UNIT_DEGREE));
delay(2000);
}
Alternative simple test
The following script is a simpler test program that only moves the motor between two positions (0° and 90°). This can be useful to quickly verify that the motor and shield are working correctly.
#include <DynamixelShield.h>
#define DXL_SERIAL Serial1
#define DEBUG_SERIAL Serial
DynamixelShield dxl(DXL_SERIAL);
const uint8_t ID = 1;
void setup() {
DEBUG_SERIAL.begin(115200);
while(!DEBUG_SERIAL);
dxl.begin(1000000);
dxl.setPortProtocolVersion(2.0);
DEBUG_SERIAL.println("Motor connected!");
dxl.torqueOff(ID);
dxl.setOperatingMode(ID, OP_POSITION);
dxl.torqueOn(ID);
}
void loop() {
DEBUG_SERIAL.println("Move to 90°");
dxl.setGoalPosition(ID, 90, UNIT_DEGREE);
delay(3000);
DEBUG_SERIAL.println("Move to 0°");
dxl.setGoalPosition(ID, 0, UNIT_DEGREE);
delay(3000);
}
Find motor ID
If the motor ID is unknown, the following script can be used to scan for connected Dynamixel motors. The script tries to ping motors with ID values between 0 and 19 and prints the detected ID in the Serial Monitor.
This is useful if the motor does not respond to commands because the wrong ID is used in the control script.
#include <DynamixelShield.h>
#define DXL_SERIAL Serial1
#define DEBUG_SERIAL Serial
DynamixelShield dxl(DXL_SERIAL);
void setup() {
DEBUG_SERIAL.begin(115200);
while(!DEBUG_SERIAL);
dxl.begin(1000000);
dxl.setPortProtocolVersion(2.0);
DEBUG_SERIAL.println("Scanning for motors...");
for(int id=0; id<20; id++){
if(dxl.ping(id)){
DEBUG_SERIAL.print("Motor found with ID: ");
DEBUG_SERIAL.println(id);
}
}
}
void loop(){}
Troubleshooting
Common issues when working with Dynamixel motors:
- The motor does not respond → check that the correct baudrate is used.
- The motor is not detected → verify the motor ID using the scan script.
- No movement → make sure torque is enabled.
- Communication problems → confirm that the shield switch is set to TTL.
- Motor not powered → check the external power supply connected to the shield.