Home > Software design >  Arduino MODBUS RTU communication Delay?
Arduino MODBUS RTU communication Delay?

Time:12-05

There is a problem in writing the MODBUS RTU code using Arduino.

First, the communication was successful. However, communication is performed in the order of request -> request -> response -> request -> request -> response.

Please refer to the video below. https://youtu.be/Z8tkmY7l-oo

I don't know what's wrong with my code.

help me..

my code is...

#include <Crc16.h>
Crc16 crc;

#define EN0 2

uint8_t n8ID = 1;
uint8_t FunctionCode = 3;

const int DIP_1 = 6;
const int DIP_2 = 7;
const int DIP_3 = 8;
const int DIP_4 = 9;

uint8_t MODBUS_Request[10];

uint8_t Data[12] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};

void setup() 
{
  pinMode(EN0, OUTPUT);

  pinMode(DIP_1, INPUT_PULLUP);
  pinMode(DIP_2, INPUT_PULLUP);
  pinMode(DIP_3, INPUT_PULLUP);
  pinMode(DIP_4, INPUT_PULLUP);
  
  digitalWrite(EN0, LOW);
  
  Serial.begin(9600);

}

void loop() 
{
  digitalWrite(EN0, LOW);

  n8ID = 0;
  n8ID  = (!digitalRead(DIP_1)) << 0;
  n8ID  = (!digitalRead(DIP_2)) << 1;
  n8ID  = (!digitalRead(DIP_3)) << 2;
  n8ID  = (!digitalRead(DIP_4)) << 3;

  if (Serial.available())
  {
    uint8_t leng = Serial.readBytes(MODBUS_Request, 8);    
    
    if(MODBUS_Request[0] == n8ID && MODBUS_Request[1] == FunctionCode && MODBUS_Request[2] == 0 && MODBUS_Request[3] == 0)
    {
      uint8_t Request_dataBuff[6];

      for (int i = 0; i < 6; i  )
      {
        Request_dataBuff[i] = MODBUS_Request[i];
      }
      
      unsigned short RequestCRC = (unsigned short)(MODBUS_Request[7] << 8 | MODBUS_Request[6]);
      crc.clearCrc();

      for (uint8_t i = 0; i < 6; i  )
        crc.updateCrc(Request_dataBuff[i]);

      unsigned short CRC_Check = crc.getCrc();
      CRC_Check = crc.Modbus(Request_dataBuff, 0, 6);

      if(RequestCRC == CRC_Check)
      {
        uint8_t send_dataBuff[15] = {n8ID, FunctionCode, 12, Data[0], Data[1], Data[2], Data[3], Data[4], Data[5], Data[6], Data[7], Data[8], Data[9], Data[10], Data[11]};

        crc.clearCrc();
        
        for (uint8_t i = 0; i < 15; i  )
          crc.updateCrc(send_dataBuff[i]);

        unsigned short ResponseCRC = crc.getCrc();
        ResponseCRC = crc.Modbus(send_dataBuff, 0, 15);

        uint8_t Response_CRC_H = ResponseCRC >> 8;
        uint8_t Response_CRC_L = ResponseCRC & 0xFF;

        uint8_t MODBUS_Response[17] = {n8ID, FunctionCode, 12, Data[0], Data[1], Data[2], Data[3], Data[4], Data[5], Data[6], Data[7], Data[8], Data[9], Data[10], Data[11], Response_CRC_L, Response_CRC_H};
        
        digitalWrite(EN0, HIGH);
        
        for(int i = 0; i < 17; i  )
        {
          Serial.write(MODBUS_Response[i]);
          Serial.flush();
        }
        digitalWrite(EN0, LOW);
      }
    }
  }
}

CodePudding user response:

Your code is adding most of the delay. You are introducing a huge overhead by writing to the port one byte at a time.

Maybe you can try replacing this part:

for(int i = 0; i < 17; i  )
    {
      Serial.write(MODBUS_Response[i]);
      Serial.flush();
    }

With something simpler:

Serial.write(MODBUS_Response,17);
Serial.flush();

which just writes the whole Modbus frame in one go.

If that change alone is not fixing your issues you might need to give more details on your question about the other side of the link.

CodePudding user response:

You cannot send two requests in a row.

What will happen if you send two requests to two slaves and they both respond at the same time?

Serial communication does not have any mechanism to avoid collisions.

It must be the master that synchronizes following a strict order: request -> response -> request -> response ... etc.

You cannot send a new request before you have received the response from the previous one.

  • Related