[SOLVED]Modbus RTU MAX485 AFD Yaskawa V1000

Hi everyone, I need some help with my proyect. I want send some data to an AFD Yaskawa V1000. I have the bytes test and I send it but I cant comunicate with it. The AFD just show an 'CALL' error, means dont have connection. We have many AFD connected to a PLC Omron and the 'CALL' is an error of comunication.

AFD Config:
ID: 3
BaudRate: 19200
Parity: none

#define SerialControlPin 3
#define RS485Transmit HIGH
#define RS485Receive LOW

void setup()   
{
  Serial.begin(9600);
  
  pinMode(SerialControlPin, OUTPUT);
  digitalWrite(SerialControlPin, RS485Receive);
  Serial1.begin(19200);   
  delay(2000);
}
void loop()   
{
  digitalWrite(SerialControlPin, RS485Transmit);
  
  byte request[] = {0x03, 0x08, 0x00, 0x00, 0xA5, 0x37, 0xDA, 0x8D};   // Test loop code
  //byte request[] = {0x03, 0x10, 0x00, 0x01, 0x00, 0x02, 0x04, 0x00, 0x01, 0x02, 0x58, 0x63, 0x39};    // Change to 60Hz and turn on
  Serial1.write(request, sizeof(request));
  
  digitalWrite(SerialControlPin, RS485Receive);
  delay(10);
  
  while(Serial1.available()) 
  {
    Serial.print(Serial1.read(), HEX);
    Serial.print(" ");
  }

  Serial.println();
  
  delay(500);
}

Thanks and sorry for my english. Also, this is my second post.

modbusv1000comunicacionesenmodbus.pdf (394 KB)

loopTestCode.PNG

It looks like you've switched your RS485 line driver back to receive before the UART had a chance to send out your test message.

You may need to insert a fixed delay in before switching back to receive mode, or you may be able to user the serial flush() call to wait for all your data to be transmitted.

markd833:
It looks like you've switched your RS485 line driver back to receive before the UART had a chance to send out your test message.

You may need to insert a fixed delay in before switching back to receive mode, or you may be able to user the serial flush() call to wait for all your data to be transmitted.

Thank you for your reply, I already did that, then the response is...

The AFD is still 'CALL' error.

OK, I see what you are trying to do. The message you are sending is the loopback message from the example in the manual. I think we can therefore assume that the various bytes in the message are correct, unless the manufacturer has a misprint.

The fact that you get something back might be good news if we assume that the device would not respond at all if you had the wrong serial port settings (baud rate, parity, stop bits etc).

However, I just noticed that in your test message you have changed the address from 01 (as used in the manual) to 03. That would mean that the checksum (the last 2 bytes of the message) is now wrong. I suggest you change the address back to 01 and see if the device responds correctly.

If you have to use address 03, then the on-line checksum calculator says that for modbus, the last 2 bytes of your message should be 0xDB & 0x6F.

markd833:
OK, I see what you are trying to do. The message you are sending is the loopback message from the example in the manual. I think we can therefore assume that the various bytes in the message are correct, unless the manufacturer has a misprint.

The fact that you get something back might be good news if we assume that the device would not respond at all if you had the wrong serial port settings (baud rate, parity, stop bits etc).

However, I just noticed that in your test message you have changed the address from 01 (as used in the manual) to 03. That would mean that the checksum (the last 2 bytes of the message) is now wrong. I suggest you change the address back to 01 and see if the device responds correctly.

If you have to use address 03, then the on-line checksum calculator says that for modbus, the last 2 bytes of your message should be 0xDB & 0x6F.

Nice eyesight, but dont work neither, I put the CRC new code but same, and then the ID=1 in the AFD and use the original code, same too. The port settings are correctly.

I dont know wtf not work, its mad, I read a lot modbus rtu guies, rs485 and I see and test examples arduino modbus, but all examples Arduino-->Modbus-->Arduino.

If you change your delay(500) to something like delay(5000), how many bytes do you receive back each time you send out the loopback message?

markd833:
If you change your delay(500) to something like delay(5000), how many bytes do you receive back each time you send out the loopback message?

If I use the 5seg delay I get...

The response must be...

That's good. At least you get back the same number of bytes that you send.

I wonder if softwareserial is struggling with 19200 baud? Can you reconfigure the device to use a lower baud rate, say 9600 or 4800?

markd833:
That's good. At least you get back the same number of bytes that you send.

I wonder if softwareserial is struggling with 19200 baud? Can you reconfigure the device to use a lower baud rate, say 9600 or 4800?

I send {0x01, 0x08, 0, 0, 0xA5, 0x37, 0xDA, 0x8D} and I just get 'E0' or 'C0'.

Test through 9600 boudrate

I get 'FC' everytime.

Test through 4800 boudrate

I get 'FE' everytime.

Test through 2400 boudrate

I get 'FF' everytime.

Ok, I think you need some other way of monitoring the serial data just to eliminate some possible sources of error.

Do you have a USB-TTL serial adapter that you can connect to your PC?

If so, you can connect GND of the USB-TTL serial adapter to the GND of your Arduino. Connect the softwareserial TX pin on your Arduino to the RXI pin of the USB-TTL serial adapter. Setup a PC COM port to the same baud rate you have in your code. You will need a teminal emulator program that can display hexadecimal bytes (such as RealTerm).

You should see the bytes that you are transmitting displayed on your PC. If they are the same as the bytes in your request[] array, then you are at least transmitting the correct data.

Next connect the softwareserial RX pin on your Arduino to the RXI pin of the USB-TTL serial adapter.

You should see the response from the other device on your PC.

markd833:
Ok, I think you need some other way of monitoring the serial data just to eliminate some possible sources of error.

Do you have a USB-TTL serial adapter that you can connect to your PC?

If so, you can connect GND of the USB-TTL serial adapter to the GND of your Arduino. Connect the softwareserial TX pin on your Arduino to the RXI pin of the USB-TTL serial adapter. Setup a PC COM port to the same baud rate you have in your code. You will need a teminal emulator program that can display hexadecimal bytes (such as RealTerm).

You should see the bytes that you are transmitting displayed on your PC. If they are the same as the bytes in your request[] array, then you are at least transmitting the correct data.

Next connect the softwareserial RX pin on your Arduino to the RXI pin of the USB-TTL serial adapter.

You should see the response from the other device on your PC.

Thanks for reply, I have it, I will try. If will not work, I will test with another AFD. Maybe the communication port is broken. This cant be so hard

I have some problems with the CRC, but the code is fine. Maybe I send it bad.

byte request[] = {0x01, 0x08, 0, 0, 0xA5, 0x37, 0xDA, 0x8D}; // Test loop code

This are some results

Success. You got a message to the device!

Now, I believe that if you use the Arduino modbus library, then it will take care of the checksum calculations for you.

SOLVED...

Thanks everyone, testing with pc, passing the bytes to the pc, and the pc to the AFD, I get the problem. I will need 2 MAX485, one for read and other for writte, but well...
The problem was in wired...

#define SerialControlPin 3
#define RS485Transmit HIGH
#define RS485Receive LOW

void setup()   
{
  Serial.begin(19200);
  
  pinMode(SerialControlPin, OUTPUT);
  digitalWrite(SerialControlPin, RS485Receive);
  Serial1.begin(19200);
  delay(2000);
}
void loop()   
{
  digitalWrite(SerialControlPin, RS485Transmit);
  
  //byte request[] = {0x01, 0x08, 0, 0, 0xA5, 0x37, 0xDA, 0x8D};   // Test loop code
  //byte request[] = {0x01, 0x10, 0x00, 0x01, 0x00, 0x02, 0x04, 0x00, 0x01, 0x02, 0x58, 0x63, 0x39};    // Change to 60Hz and turn on
  byte request[] = {0x01, 0x10, 0x00, 0x01, 0x00, 0x02, 0x04, 0x00, 0x00, 0x02, 0x58, 0x32, 0xF9};    // Change to 60Hz and turn off

  Serial1.write(request, 13);

  Serial1.flush();
  delay(5);
  
  digitalWrite(SerialControlPin, RS485Receive);
  
  while(Serial1.available())
  {
    Serial.print(Serial1.read(), HEX);
    Serial.print(" ");
  }

  Serial.println();
  
  
  delay(500);
}

2 Likes

Finally, all perfect
Thanks again

2 Likes