emelianov / modbus-esp8266

Most complete Modbus library for Arduino. A library that allows your Arduino board to communicate via Modbus protocol, acting as a master, slave or both. Supports network transport (Modbus TCP) and Serial line/RS-485 (Modbus RTU). Supports Modbus TCP Security for ESP8266/ESP32.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

RTU Slave keeping flooding the bus

neosoyo opened this issue · comments

i'm running a custom board using samd21 mcu running arduino framework, 2 uarts with RS-485 transceiver.

Serial1 running as master
Serial2 running as slave

The behavior captured with a logic analizer:

2023-09-13_19-15

Code:

bool cb(Modbus::ResultCode event, uint16_t transactionId, void* data) {
  if(event  != Modbus::EX_SUCCESS){
    SerialUSB.print("Request result: 0x");
    SerialUSB.println(event, HEX);
  }else{
    Request = true;
    SerialUSB.println("Sucess!");
  }
  return true;
}

void setup()
{
  Serial1.begin(19200, SERIAL_8E1); // Master mode
  master.begin(&Serial1, SERIAL1_DE, true);
  master.setBaudrate(19200);
  master.client();

  Serial2.begin(19200, SERIAL_8E1); // Slave mode
  slave.begin(&Serial2, SERIAL2_DE, true);
  slave.setBaudrate(19200);
  slave.server(2);
  slave.addHreg(1);
  slave.addHreg(2);
  slave.addHreg(3);
  slave.addHreg(4);
  slave.addHreg(5);
  slave.addHreg(6);
  slave.addHreg(7);
  slave.addHreg(8);

  ts = millis();
}

void loop{
 if(millis() - ts >= 500ul){
    if(!master.slave()){
 ///////////////// block of reading and processing for each slave holding register
      buffer1[0] = 0;
      buffer1[1] = 0;
      Request =false;
      Ser1_Pre(); // RE pin too, no echo on RX
      master.readHreg(1,2,buffer1,2,cb);
      Ser1_Post();
      while(master.slave()){
        master.task();
        delay(10);
      }
      if(Request){
        irr = buffer1[0] << 16 | buffer1[1];
        irr1 = irr/10;
        slave.Hreg(1,irr1);
        Request = false;
      }                        
// end block
    }
    ts = millis();
  }    
  slave.task();
}

the slave.task() is answering the modbus request and then start to spam NACK and ACK until the next Serial2 master routine runs again.

2023-09-13_19-33

i'm really struggling to understand the issue.

best regards

Just for the record. i realized after writing this. the reason is the RE pin from slave transceiver, it must be toggle to the api not respond for its own echo...

go to line 103 of ModbusSettings.h and uncomment the macro MODBUSRTU_REDE, now the begin() function accept the RE pin to control the transceiver RX driver.