Hello everyone,
I have been trying to work with Dynamixels for a while now, and I thought I was making progress, but I have hit a wall. I am not sure what I am doing wrong, but hopefully I can find some help here.
I have a Dynamixel MX-28AR connected to an Arduino Nano through a MAX13488E translator chip. This is the smallest solution I could come up with, and for communications it works well so far.
The problem I am having is this: I am trying to use the PING command to check if the Dynamixel is connected, but it is behaving erratically. Most of the time, even when it is unplugged, it reports that it is connected and I do not understand why. This functionality is integral to what I am trying to do, and if anyone could offer some help it would be immensely helpful.
Here is the code I have written so far:
#include <SoftwareSerial.h> // Software serial library, necessary to communicate with the Dynamixel
int MX28_Tx = 2; // Software Serial Tx-Out to MX-28AR
int MX28_Rx = 3; // Software Serial Rx-In from MX-28AR
// The Arduino is connected to the Dynamixel using a MAX13488E chip. This translates between TTL and RS-485
word Response[10]; // This is an array of 10 bytes. Whenever the Dynamixel Responds, it responds with some number of bytes, usually 6, but can be more. 10 just to be safe.
byte ID1 = 1; // Holds the ID of the Dynamixel
byte Error; // Contains the Error Bits. There are 8 possible error bits, so 1 byte is enough to store it.
byte Checksum; // This holds the calculated checksum
byte Ping_Status; // The connection status of the Dynamixel
SoftwareSerial DXL(MX28_Rx, MX28_Tx); // (Rx, Tx) Sets up the software serial port for communicating with the MX-28 Dynamixel servo
void setup() {
Serial.begin(115200); // Sets the PC serial port Baud Rate
DXL.begin(57600); // Sets the Dynamixel servo port Baud Rate
}
void loop() {
Ping_Status = Ping(ID1); // Ping the Dynamixel
}
// This is the function to ping the Dynamixel
byte Ping(byte ID) // Pings the Dynamixel to see if it is present. If it is present, the checksum will match, if not, it will fail
{
DXL.write(0xFF); // Header byte 1
DXL.write(0xFF); // Header byte 2
DXL.write(ID); // Dynamixel ID
DXL.write(0x02); // Length of Packet (Only 2 for Ping Command)
DXL.write(0x01); // Ping type of instruction
DXL.write(lowByte(~(ID + 0x02 + 0x01))); // Checksum. This is the NOT (~) of the SUM of everything else.
DXL.flush(); // Waits for the serial transmission to finish
delay(5); // Wait for Dynamixel to respond
if (DXL.available()) // If the Dynamixel has sent a response
{
for(int n=0; n<8; n++) // Read 8 bytes
{
Response[n] = DXL.read(); // and put them into the response array
}
}
// The checksum of the response is always the lowest byte of the NOT (~) of the ID, Length, Error, and Parameters Added Together.
Checksum = lowByte(~(Response [2] + Response [3] + Response [4]));
/*
Serial.print ("Header 1: ");
Serial.println(Response[0], HEX);
Serial.print ("Header 2: ");
Serial.println(Response[1], HEX);
Serial.print ("ID: ");
Serial.println(Response[2], HEX);
Serial.print ("Length of Packet: ");
Serial.println(Response[3], HEX);
Serial.print ("Error: ");
Serial.println(Response[4], HEX);
Serial.print ("Checksum Received: ");
Serial.println(Response[5], HEX);
Serial.print ("Checksum Calculated: ");
Serial.println(Checksum, HEX);
*/
if (Response [5] == Checksum && Response [2] == ID) // If the calculated checksum matches the actual checksum and the Dynamixel returns the correct ID, let me know
{
Serial.println("Checksum Matches, Dynamixel Found!");
return (1);
}
else
{
Serial.println("Checksum Error, Dynamixel Not Found!");
return (0);
}
}
Thanks in advance!