How to send Hex Serial commands to a servo drive

Hi !

I’m trying to send hexadecimal commands to a servo drive using RS232. I use a DFR0077 to connect the servo drive to the Arduino Mega.
The first hex command is supposed to give me the access to write on the drive and the second i supposed to enable it.
When I run my code the drive is not enabled. I try to send the same hex values using a soft and it worked. I also check that the arduino sent correct values by printing them and they are correct.

Do you have any clue on what I’m doing wrong ?

Thanks for your help

sketch_mar17b.ino (404 Bytes)

OP’s Code:

#include <SoftwareSerial.h>
SoftwareSerial mySerial(19, 18); // RX, TX CARTE MEGA


void setup() {
  // put your setup code here, to run once:
  mySerial.begin(115200);
  Serial.begin(9600);
}

void loop() {
  mySerial.listen();
byte acessWrite[] = {0xA5,0x3F,0x02,0x07,0x00,0x01,0xB3,0xE7,0x0F,0x00,0x10,0x3E};
mySerial.write(acessWrite, 12);
delay(1);
 current = mySerial.read();

 }

2 things…

  1. mySerial.begin(115200); <---- softwareSerial will not work well for that speed IMHO.

  2. you are using a MEGA but also using the SoftwareSerial library!!! Why not use one of the available Hardware serial ports!

hope that helps…

I'm trying to send hexadecimal commands

The computer stores and sends binary data, which the servo expects.

Hexadecimal is a human readable representation of binary data. For example, here the binary data are represented as hexadecimal:

byte acessWrite[] = {0xA5,0x3F,0x02,0x07,0x00,0x01,0xB3,0xE7,0x0F,0x00,0x10,0x3E};

Thanks for your quick response !

I changed my code to use the Hardware serial but the result is the same. When I ask the right access to the drive it is supposed to reply : A5 FF 00 01 00 00 CF B6 but instead all I have is FFFFFFFF …

I can’t change the baud rate as it is fixed by the servo drive I’m using.

int resp;
void setup() {
  // put your setup code here, to run once:
  Serial1.begin(115200);
  Serial.begin(9600);
}

void loop() {
byte acessWrite[] = {0xA5,0x3F,0x02,0x07,0x00,0x01,0xB3,0xE7,0x0F,0x00,0x10,0x3E};
Serial1.write(acessWrite, 12);
//byte enable[] = {0xA5, 0x3F, 0x02, 0x01, 0x00, 0x01, 0x01, 0x47, 0x00, 0x00, 0x00, 0x00};
//    Serial1.write(enable, sizeof(enable));
       byte disable[] = {0xA5, 0x3F, 0x02, 0x01, 0x00, 0x01, 0x01, 0x47, 0x01, 0x00, 0x33, 0x31};
    Serial1.write(disable, sizeof(disable));

delay(1);
 resp = Serial1.read();
 Serial.println(resp,HEX);

 }

no idea if is going to make a difference but could you try this instead?

int resp;
void setup() {
  // put your setup code here, to run once:
  Serial1.begin(115200);
  Serial.begin(115200);
}

void loop() {
  byte acessWrite[] = {0xA5, 0x3F, 0x02, 0x07, 0x00, 0x01, 0xB3, 0xE7, 0x0F, 0x00, 0x10, 0x3E};

  Serial1.write(acessWrite, 12);

  for (int i = 0; i < 12; ++i) {
    Serial1.write(acessWrite[i]);
  }

  delay(100);

  if (Serial1.available()) {
    while (Serial1.available() > 0) {
      resp = Serial1.read();
      Serial.print(resp, HEX);
      Serial.print(" ");
    }
  }
  Serial.print("\n\n");


  byte disable[] = {0xA5, 0x3F, 0x02, 0x01, 0x00, 0x01, 0x01, 0x47, 0x01, 0x00, 0x33, 0x31};
  for (int i = 0; i < 12; ++i) {
    Serial1.write(disable[i]);
  }

  delay(100);

  if (Serial1.available()) {
    while (Serial1.available() > 0) {
      resp = Serial1.read();
      Serial.print(resp, HEX);
      Serial.print(" ");
    }
  }
  Serial.print("\n\n");
}

at least with the above code you should see the WHOLE response after each request

hope that helps…

I can't change the baud rate as it is fixed by the servo drive I'm using.

The hardware serial interfaces should work OK at 115200 baud

What exactly is this "servo drive" to which you refer ?
Can you please post a link to it ?

sherzaad:
no idea if is going to make a difference but could you try this instead?

int resp;

void setup() {
 // put your setup code here, to run once:
 Serial1.begin(115200);
 Serial.begin(115200);
}

void loop() {
 byte acessWrite = {0xA5, 0x3F, 0x02, 0x07, 0x00, 0x01, 0xB3, 0xE7, 0x0F, 0x00, 0x10, 0x3E};

Serial1.write(acessWrite, 12);

for (int i = 0; i < 12; ++i) {
   Serial1.write(acessWrite[i]);

}

delay(100);

if (Serial1.available()) {
   while (Serial1.available() > 0) {
     resp = Serial1.read();
     Serial.print(resp, HEX);
     Serial.print(" ");
   }
 }
 Serial.print(“nn”);

byte disable = {0xA5, 0x3F, 0x02, 0x01, 0x00, 0x01, 0x01, 0x47, 0x01, 0x00, 0x33, 0x31};
 for (int i = 0; i < 12; ++i) {
   Serial1.write(disable[i]);
   resp = Serial1.read();
   Serial.print(resp, HEX);
   Serial.print(" ");
 }

delay(100);

if (Serial1.available()) {
   while (Serial1.available() > 0) {
     resp = Serial1.read();
     Serial.print(resp, HEX);
     Serial.print(" ");
   }
 }
 Serial.print(“nn”);
}
}




at least with the above code you should see the WHOLE response after each request

hope that helps....

The response is still the same : FFFFFFFF for the first command and FFFFFFFF for the second.

UKHeliBob:
The hardware serial interfaces should work OK at 115200 baud

What exactly is this “servo drive” to which you refer ?
Can you please post a link to it ?

The drive is the DZRALTE-02L080. I’ve attached the datasheet and here the link for the serial comunication manual :

AMC_Datasheet_DZRALTE-020L080 (6).pdf (660 KB)

Serial1.read() returns -1 (0xFFFF) if there is no character in the receive buffer.

Is there some kind of terminating character after the response? If so, you could use Serial1.readBytesUntil(). If not, you will have to interpret the bytes as they arrive.

You do this in several places:

if (Serial1.available()) {
    while (Serial1.available() > 0) {

The if is totally unnecessary. All you need is the while.

johnwasser:
Serial1.read() returns -1 (0xFFFF) if there is no character in the receive buffer.

Is there some kind of terminating character after the response? If so, you could use Serial1.readBytesUntil(). If not, you will have to interpret the bytes as they arrive.

The spec sheet shows there is an identifying byte for the start of the message, but the actual message length has to be determined by counting the words in the data section and that will will tell you where the CRCC bytes will begin.
The fact that someone is contemplating this for an Arduino tells me they are are really expert data communication programmers or will soon give up the project.
This seems to be something to be done on a PC or similar sized machine.
I see at least 6 months full time with the hardware available for testing.
Paul

Paul_KD7HB:
The spec sheet shows there is an identifying byte for the start of the message, but the actual message length has to be determined by counting the words in the data section and that will will tell you where the CRCC bytes will begin.
The fact that someone is contemplating this for an Arduino tells me they are are really expert data communication programmers or will soon give up the project.
This seems to be something to be done on a PC or similar sized machine.
I see at least 6 months full time with the hardware available for testing.
Paul

I understand that finding the data in the response can be difficult but I already know the message that the drive is supposed to respond.
I just want to send a message to enable the drive, using the Arduino, but the drive does not seem to receive the command I'm sending.

If you had posted your code in-line as is the forum standard, someone would have pointed out that software serial cannot possibly run a Baud rate necessary for your servo controller.
Paul

The responses are fairly straightforward. There is an 8-byte header starting with two constant bytes and ending in a 16-bit CRC. The 6th byte is the number of data words (16-bit values) that follow (255 max) and the data words have their own 16-bit CRC. You could write a function that waits for a complete response to arrive (or a CRC error to occur). You may want to put a timeout on that so it doesn't hang your sketch if no response arrives.