MODBUS communication issue: Receiving back the same data in Arduino that im sending to Slave

Im working on my university of controlling and monitoring VFD through Arduino. Im using Arduino Mega and have been successful in transmitting data to my VFD (slave) via RS485 ASCII protocol but have not been able to receive data from the VFD. It goes like this, when i have to read the output frequency of the VFD, i will send a command from the Arduino to the VFD to give me the output frequency, so the VFD will act on the command and it should send back its output frequency in ASCII format, but its sending me exactly the same command that i sent to receive the frequency (e.g if i send 010321030001D7, and if the frequency is lets say 50, i should receive 01030213885F, but im receiving exactly the same data that i sent i.e 010321030001D7). No such scenario is mentioned in the manual of the VFD or anywhere. I have attached the schematic, code and Delta VFD-S1 manual (you can refer page 62 chapter 5). Need help from you guys...
937ee03f185e6dabe976891563f4fcc50a83d151

Manual Link: https://epa.de/download/en/04_Manuals/04.02_Drives/04.02.01_Inverters/04.02.01.03_Delta/DELTA_VFD-S_manual.pdf

Code:

const unsigned char readfreq[17]={':','0','1','0','3','2','1','0','3','0','0','0','1','D','7','\r','\n'};
 
const int REpin = 5;
const int DEpin = 6;


void setup()
{
  Serial.begin(9600);

  Serial2.begin(9600,SERIAL_7N2); //VFD

  pinMode(REpin, OUTPUT);
  pinMode(DEpin, OUTPUT); 
  
  digitalWrite(DEpin,HIGH); // enable Rs485 transmitter
  digitalWrite(REpin,HIGH); // disable Rs485 receiver
}

void loop()
{
  while(Serial2.available()!=0) //checking if there is something present in serial2
  {
    Serial2.read(); //reading serial2 to clear out the serial buffer
   
  }
  digitalWrite(DEpin,HIGH); // enable Rs485 transmitter
  digitalWrite(REpin, LOW); //enable Rs485 receiver
      
  for(int i=0; i<17; i++)
  {
    Serial2.write(readfreq[i]); //Sending the command to VFD so that it sends back some data to arduino
  }

  while(Serial2.available()!=0)
  {
    Serial.println(Serial2.read()); //reading the data sent from the VFD to arduino
  }
}

You enable both the RX and TX simultaneously, that is a loopback.

So i should enable transmitter first and then after some delay enable receiver?

I tried enabling trasmitter first and then enabling the receiver after sending command, now im getting no output at all and now Serial2.available()=0.

i replaced

digitalWrite(DEpin,HIGH); // enable Rs485 transmitter
  digitalWrite(REpin, LOW); //enable Rs485 receiver
      
  for(int i=0; i<17; i++)
  {
    Serial2.write(readfreq[i]); //Sending the command to VFD so that it sends back some data to arduino
  }

with

digitalWrite(DEpin,HIGH); // enable Rs485 transmitter
  digitalWrite(REpin, HIGH); //disable Rs485 receiver
      
  for(int i=0; i<17; i++)
  {
    Serial2.write(readfreq[i]); //Sending the command to VFD so that it sends back some data to arduino
  }
  digitalWrite(DEpin,LOW); // disable Rs485 transmitter
  digitalWrite(REpin, LOW); //enable Rs485 receiver

Mmmm... enable transmitter and then immediately enable receiver. Most such systems just connect the *RE and DE line together, that is why one is made active high and the other active low. Then you can switch communication direction with one pin.

Yup it was the first thing i tried but unfortunately no results

How do you know that the VFD is actually responding?

VFD is responding to other commands like RUN or STOP, but i dont need to receive anything from the VFD in these commands. But when I need to receive data from the VFD for Reading Frequency command, VFD is not showing any errors or anything else, which makes me believe it is actually sending back data and im somehow making errors in extracting it. The command is correct because the VFD is returning data in RS485 Monitoring software, but not in arduino.

Try:

const unsigned char readfreq[17] = {':', '0', '1', '0', '3', '2', '1', '0', '3', '0', '0', '0', '1', 'D', '7', '\r', '\n'};

const int REpin = 5;
const int DEpin = 6;


void setup()
{
  Serial.begin(9600);

  Serial2.begin(9600, SERIAL_7N2); //VFD

  pinMode(REpin, OUTPUT);
  pinMode(DEpin, OUTPUT);

  digitalWrite(DEpin, HIGH); // enable Rs485 transmitter
  digitalWrite(REpin, HIGH); // disable Rs485 receiver
}

void loop()
{
  while (Serial2.available() != 0) //checking if there is something present in serial2
  {
    Serial2.read(); //reading serial2 to clear out the serial buffer

  }

  modeTX();
  for (int i = 0; i < 17; i++)
  {
    Serial2.write(readfreq[i]); //Sending the command to VFD so that it sends back some data to arduino
  }
  Serial2.flush(); // wait for everything to be sent
  
  modeRX();
  while (Serial2.available() != 0)
  {
    Serial.println(Serial2.read()); //reading the data sent from the VFD to arduino
  }
}

void modeTX() {
  digitalWrite(REpin, HIGH); // disable Rs485 receiver
  digitalWrite(DEpin, HIGH); // enable Rs485 transmitter
}

void modeRX() {
  digitalWrite(DEpin, LOW); // disable Rs485 transmitter
  digitalWrite(REpin, LOW); // enable Rs485 receiver
}

By the way, you can:

const char *readfreq = ":010321030001D7";
...
Serial2.println(readfreq);

or

const char *readfreq = ":010321030001D7\r\n";
...
Serial2.print(readfreq);

instead of handling characters individually, which is a bit clumsy. If I were marking your work, I would "ding" you for that.

1 Like

Thanks bro for the efforts. But still no luck :frowning: Getting nothing

How did you come up with the transmit message? Did you calculate the checksum correctly? What about the wiring? Are you sure the RE and DE pins are actually connected properly?

BRO i just received the output. I beleive Serial2.flush() was the key. Thankyou so much bro i had almost gave up!!. :slight_smile:
Code:

const unsigned char readfreq[17]={':','0','1','0','3','2','1','0','3','0','0','0','1','D','7','\r','\n'};
const int DEpin = 6; //i shorted RE and on pin 6

void setup()
{

  Serial.begin(9600);

  Serial2.begin(9600,SERIAL_7N2); //VFD

  pinMode(DEpin, OUTPUT); 
  
  digitalWrite(DEpin,LOW); // disable Rs485 transmitter

}

void loop()
{
 digitalWrite(DEpin,HIGH); // enable Rs485 transmitter
      
  for(int i=0; i<17; i++)
  {
    Serial2.write(readfreq[i]); //Sending the command to VFD so that it sends back some data to arduino
  }

 Serial2.flush();
 
  digitalWrite(DEpin,LOW); // disable Rs485 transmitter
 
  delay(3000);

  while(Serial2.available()!=0)
  {
    Serial.println(Serial2.read()); //reading the data sent from the VFD to arduino
  }
  
}

Perfect! Make your life easier and use C string support, instead of raw character arrays.

Sure mate! thanks man.

NP. Actually it helps me because I have to use RS-485 soon, for a project here.

Oh great! good luck mate!