bertmelis / esp32ModbusRTU

modbus RTU client for ESP32
MIT License
70 stars 44 forks source link

get Slave address and etc inside Error handler? #24

Closed zekageri closed 4 years ago

zekageri commented 4 years ago

Hi! I just want to know if it is possible to get the address of the slave device wich is sending the error.

like:

modbus.onError([](esp32Modbus::Error error, uint8_t slaveAddress) {});

I tried like this:

IN esp32ModbusRTU.h

void onError(esp32Modbus::MBRTUOnError handler,uint8_t slaveAddress);

IN esp32ModbusTypeDefs.h

typedef std::function<void(esp32Modbus::Error,uint8_t)> MBRTUOnError;

IN esp32ModbusRTU.cpp

void esp32ModbusRTU::onError(esp32Modbus::MBRTUOnError handler,uint8_t slaveAddress) {
  _onError = handler;
}

void esp32ModbusRTU::_handleConnection(esp32ModbusRTU* instance) {
  while (1) {
    ModbusRequest* request;
    xQueueReceive(instance->_queue, &request, portMAX_DELAY);  // block and wait for queued item
    instance->_send(request->getMessage(), request->getSize());
    ModbusResponse* response = instance->_receive(request);
    if (response->isSucces()) {
      if (instance->_onData) instance->_onData(response->getSlaveAddress(), response->getFunctionCode(), request->getAddress(), response->getData(), response->getByteCount());
    } else {
      if (instance->_onError) instance->_onError(response->getError(),response->getSlaveAddress());
    }
    delete request;  // object created in public methods
    delete response;  // object created in _receive()
  }
}

And i get: _error: no matching function for call to 'esp32ModbusRTU::onError(ModBus_Begin()::<lambda(esp32Modbus::Error, uint8t)>)'

Thanks.

zekageri commented 4 years ago

Okay! I was able to compile it like this:

In esp32ModbusRTU.cpp:

void esp32ModbusRTU::_handleConnection(esp32ModbusRTU* instance) {
  while (1) {
    ModbusRequest* request;
    xQueueReceive(instance->_queue, &request, portMAX_DELAY);  // block and wait for queued item
    instance->_send(request->getMessage(), request->getSize());
    ModbusResponse* response = instance->_receive(request);
    if (response->isSucces()) {
      if (instance->_onData) instance->_onData(response->getSlaveAddress(), response->getFunctionCode(), request->getAddress(), response->getData(), response->getByteCount());
    } else {
      if (instance->_onError) instance->_onError(response->getError(),response->getSlaveAddress());
    }
    delete request;  // object created in public methods
    delete response;  // object created in _receive()
  }
}

In esp32ModbusTypeDefs.h:

typedef std::function<void(esp32Modbus::Error,uint8_t)> MBRTUOnError;

In the call:

modbus.onError([](esp32Modbus::Error error, uint8_t serverAddress) {
  });

And no more modification.

But i get address 0 always.

bertmelis commented 4 years ago

You don't have to change the onError setter, you've already changed the handler's signature.

But the other changes seem to be correct. Don't know (yet) what is causing the slaveId to be always zero.

zekageri commented 4 years ago

I don't know how should i get the address in the error handler. I really need it because i'am trying to handle multiple slaves and if one of them is not responding i have to delete it from an array wich is containing all the salves in the bus. I don't want to communicate with a dead slave.

Did you investigated this issue? No matter what i do, can't get the slave address in the error handler. :|

bertmelis commented 4 years ago

I'll look into the matter.

zekageri commented 4 years ago

Thank you!

bertmelis commented 4 years ago

So I've made a branch "develop" with the slaveAddress added to the onError callback. Could you try that one?

zekageri commented 4 years ago

Yes! Of course.

zekageri commented 4 years ago

Still address 0. :/

static const inline void Handle_Error(String Code, String SlaveAddress){
  String Error = "Error Code: ";Error += Code;
  Error += " From Address: ";Error += SlaveAddress;
  Send_Async(Error," ~ModBus");
}
modbus.onError([](esp32Modbus::Error error, uint8_t slaveAddress) {
    Bus_is_Busy = false;
    if(Can_Check_Array){Check_Loop_Count();}
    Handle_Error(String(error,HEX),String(slaveAddress,HEX));
  });