debevv / nanoMODBUS

A compact MODBUS RTU/TCP C library for embedded/microcontrollers
MIT License
282 stars 58 forks source link

Communication problem with 2 servers and 1 client #26

Closed kopierreko closed 1 year ago

kopierreko commented 1 year ago

Hi,

All is working good in the RTU configuration (2x ESP32 with max485-like RS485). The client send a read holding register to server ID 1 and 3.

When I only have ID 1 or ID 3, it's OK, but when I have both, the first ID the client request answer, and the second doesn't.

I'm trying to find the solution since many days. I already check the RE/DE pins and the RS485 communication with my oscilloscope, the only thing I can see is that I'm trying to explain.

On the server which doesn't answer, there is this debug which I'm not sure to understand properly :

NMBS req <- client_id 3 fc 0 NMBS req <- client_id 49 fc 0 NMBS req <- client_id 1 fc 213 NMBS req <- client_id 3 fc 3 a 49 q 1 NMBS req <- client_id 3 fc 3 a 512 q 193

If you have an idea... I precise that sometimes it's working, but very rarely

Thanks !

debevv commented 1 year ago

I checked, and it looks like a big oversight from my side on the way the serial RTU communication is performed. Turns out the simple TCP-like byte by byte read/writes doesn't adapt well to Modbus' frame-based serial protocol, or at least it stops working once there are more than 2 devices on the network. I'll try to fix this by today or tomorrow, and it would be very useful if you could test with with your hardware.

kopierreko commented 1 year ago

You comfort me, I've been looking for almost 60 hours if it's my electronic bus that isn't working, and after a day of research with the oscilloscope, I really don't see what could be causing this other than a coding/decoding error. I tried to add delays, increasing buffer sizes, nothing changes. I had the impression that a bigger RX Buffer was working a little better but it's because the client tried more times to send the message.

For my part, the purpose is to connect 4 servers with a client. I will be able to test it yes, I am actively looking for a solution. I had started to do something myself based on another idea but it can't be as fast as modbus can, so it's not a very good solution for me.

If I can give me more details, the it's very systematic, if you send 2 request (ID 1 first, ID2 next) from 1 client to 2 servers, it's the first frame that is received. The second is almost every times missed, while on the oscilloscope I can see that the RE/DE management is good btw client and servers and no-one is trying to answer next to the 2nd request, which give a timeout to client for the 2nd request. If we wait long time between the 2 requests, it can work (I had a good result with 143ms).

Another thing I can see is a problem with buffers, or something like that ; if I increase the speed, I have lots of BAD_UNIT_ID received by client, but for sure there is no problem of unit ID, I think it's the same error of decoding or conflits (only with 2 servers).

Thanks 😊

debevv commented 1 year ago

I'm very sorry for the waste of time, I know how it feels to go around in circles when the problem is not on your side...

By the way, I think the culprit was much simpler than I thought. There's no need to handle the timing RTU frames (turns out I was right and nobody does it nowadays), but I found that the server code was not handling "foreign" messages correctly, so by the time the second server received a message, its internal state was messed up by the previous messages.

Can you give a try to this branch https://github.com/debevv/nanoMODBUS/tree/test_rtu_handling and let me know if it solves your issue? Also, the more findings you stumble upon, the better, since the RTU side of this library was really never thoroughly tested.

kopierreko commented 1 year ago

Thanks for this quick answer.

I just tried, it's a little better I think, but it doesn't resolve the problem. I'm sending 1 request to the 2 devices 1 with a delay of 5ms between the 2 sends, and all 1 time per second.

Received by one of the 2 servers : 1 NMBS res -> address_rtu 1.fc 3.b 2.regs 0 1 NMBS req <- address_rtu 3.fc 3.a 49.q 1 1 NMBS res <- address_rtu 3.fc 3.b 2.regs 0 1 NMBS req <- address_rtu 1.fc 3.a 49.q 1

This message is a simple HR of 1 register.

When I try a bigger frame, it's very random. It's better than before because I can't see a priority of the first send, but it's still not working.

What one server receive while I send the write register request to the 2 servers : 1 NMBS res -> address_rtu 1.fc 3.b 2.regs 0 1 NMBS req <- address_rtu 3.fc 16.a 80.q 6.b 12.regs 1 100 120 0 65000 0 1 NMBS req <- address_rtu 3.fc 16.a 80.q 6.b 12.regs 1 100 120 0 65000 0 WaitingStart AutoMode:1 1 NMBS req <- address_rtu 3.fc 16.a 80.q 6.b 65.regs 1 NMBS req <- address_rtu 3.fc 16.a 80.q 6.b 12.regs 1 33 10 0 500 0 1 NMBS req <- address_rtu 3.fc 16.a 80.q 6.b 65.regs 1 NMBS req <- address_rtu 3.fc 3.a 49.q 1 1 NMBS res <- address_rtu 3.fc 3.b 2.regs 0 1 NMBS req <- address_rtu 1.fc 3.a 49.q 1

The write request is a write multiple registers of registers.

What do you think ?

debevv commented 1 year ago

Can you send me the logs of the 3 devices and the initialization code of both server and client?

kopierreko commented 1 year ago

Server :

void init(int id) {

    pinMode(rs485_re, OUTPUT);
    pinMode(rs485_de, OUTPUT);
    digitalWrite(rs485_re, LOW);
    digitalWrite(rs485_de, LOW);

    Serial2.setRxBufferSize(500); //prepareHardwareSerial
    Serial2.begin(115200, SERIAL_8N1, rs485_rx, rs485_tx);

    nmbs_platform_conf platform_conf;
    platform_conf.transport = NMBS_TRANSPORT_RTU;
    platform_conf.read = read_serial;
    platform_conf.write = write_serial;
    platform_conf.arg = NULL;

    nmbs_callbacks callbacks = {0};
    callbacks.read_coils = handle_read_coils;
    callbacks.write_multiple_coils = handle_write_multiple_coils;
    callbacks.read_holding_registers = handler_read_holding_registers;
    callbacks.write_multiple_registers = handle_write_multiple_registers;

    // Create the modbus server
    //nmbs_t nmbs;
    nmbs_error err = nmbs_server_create(&nmbs, id, &platform_conf, &callbacks);
    if (err != NMBS_ERROR_NONE) {
      onError();
    } else {
      Serial.println("Modbus OK");
    }

    nmbs_set_read_timeout(&nmbs, 10);
    nmbs_set_byte_timeout(&nmbs, 100);
}

int32_t read_serial(uint8_t* buf, uint16_t count, int32_t byte_timeout_ms, void* arg) {
  digitalWrite(rs485_re, LOW);
  //Serial.println("read");
  Serial2.setTimeout(byte_timeout_ms);
  return Serial2.readBytes(buf, count);
}

int32_t write_serial(const uint8_t* buf, uint16_t count, int32_t byte_timeout_ms, void* arg) {
  delay(1);
  digitalWrite(rs485_re, HIGH);
  digitalWrite(rs485_de, HIGH);
  //delay(3);
  while (Serial2.available())
    Serial2.read();

  int32_t r = Serial2.write(buf, count);
  //Serial2.flush();
  delay(3);

  digitalWrite(rs485_de, LOW);
  digitalWrite(rs485_re, LOW);
  return r;
}

Client :

void init() {
    pinMode(rs485_re, OUTPUT);
    pinMode(rs485_de, OUTPUT);
    digitalWrite(rs485_re, LOW);
    digitalWrite(rs485_de, LOW);
    Serial2.begin(115200, SERIAL_8N1, rs485_rx, rs485_tx);

    nmbs_platform_conf platform_conf;
    platform_conf.transport = NMBS_TRANSPORT_RTU;
    platform_conf.read = read_serial;
    platform_conf.write = write_serial;

    err = nmbs_client_create(&nmbs, &platform_conf);
    if (err != NMBS_ERROR_NONE)
      onError();

    nmbs_set_read_timeout(&nmbs, 50);
    nmbs_set_byte_timeout(&nmbs, 10);
}

int32_t read_serial(uint8_t* buf, uint16_t count, int32_t byte_timeout_ms, void* arg) {
  digitalWrite(rs485_re, LOW);
  Serial2.setTimeout(byte_timeout_ms);
  int r = Serial2.readBytes(buf, count);
  digitalWrite(rs485_re, HIGH);
  return r;
}

int32_t write_serial(const uint8_t* buf, uint16_t count, int32_t byte_timeout_ms, void* arg) {
  digitalWrite(15, HIGH);
  while (Serial2.available())
    Serial2.read();//*/

  int32_t r = Serial2.write(buf, count);
  delay(3);
  digitalWrite(15, LOW);
  return r;
}

Here is the exact debug of the 3 devices for my write multiple registers (but curiously, without the "regular send" of the read registers, it's working for the 2 devices while sending write register, but with lots of decay ! The client sends a 2nd time if error) :

Client :

2023-05-16 18:51:57 --> 0 NMBS req -> address_rtu 3.fc 16.a 8
2023-05-16 18:51:57 --> 0.q 6.b 12.regs 1 33 10 0 500 0 
2023-05-16 18:51:57 --> /!\44296 modbus error : -3
2023-05-16 18:51:57 --> 
2023-05-16 18:51:57 --> Sending mode to 3failed. ReDo
2023-05-16 18:51:57 --> 
2023-05-16 18:51:57 --> 0 NMBS req -> address_rtu 3.fc 16.a 80.q 6.b 12.regs 1 33 10 0 500 0 
2023-05-16 18:51:57 --> /!\44373 modbus error :
2023-05-16 18:51:58 -->  -3
2023-05-16 18:51:58 --> 
2023-05-16 18:51:58 --> 0 NMBS req -> address_rtu 1.fc 16.a 80.q 6.b 12.regs 1 33 10 0 500 0 
2023-05-16 18:51:58 --> /!\44478 modbus error
2023-05-16 18:51:58 -->  : -3
2023-05-16 18:51:58 --> 
2023-05-16 18:51:58 --> Sending mode to 1failed. ReDo
2023-05-16 18:51:58 --> 0 NMBS req -> address_rtu 1.fc 16.a 80.q 6.b 12.regs 
2023-05-16 18:51:58 --> 1 33 10 0 500 0 
2023-05-16 18:51:58 --> /!\44659 modbus error : -3
2023-05-16 18:51:58 --> 

Server 1 :

2023-05-16 18:51:57 --> 1 NMBS req <- address_rtu 3.fc 16.a 80.q 6.b 1
2023-05-16 18:51:57 --> 2.regs 1 33 10 0 500 0 
2023-05-16 18:51:57 --> 1 NMBS req <- address_rtu 3.fc 16.a 80.q 6.b 12.regs 1 33 10 0 500 
2023-05-16 18:51:57 --> 0 
2023-05-16 18:51:58 --> 1 NMBS req <- address_rtu 3.fc 16.a 80.q 6.b 65.regs 1 NMBS req <- address_rtu 1.
2023-05-16 18:51:58 --> fc 16.a 80.q 6.b 12.regs 1 33 10 0 500 0 
2023-05-16 18:51:58 --> .00m, durationGoal=10s. (=OK)
2023-05-16 18:51:58 --> autoModeDisplay 33 (=OK)
2023-05-16 18:51:58 --> save id 1 (=OK)
2023-05-16 18:51:58 --> 1 NMBS res -> address_rtu 1.fc 16.a 80.q 6
2023-05-16 18:51:58 --> 

Server 2 :

2023-05-16 18:51:57 --> 3 NMBS req <- address_rtu 3.fc 16.a 80.q 6.b 12.regs 
2023-05-16 18:51:57 --> 1 33 10 0 500 0 
2023-05-16 18:51:57 --> Set mode : automode=1 autoModeDisplay=33 distanceGoal=5.00m, durationGoal=10s (=OK)
2023-05-16 18:51:57 --> .
2023-05-16 18:51:57 --> 3 NMBS res -> address_rtu 3.fc 16.a 80.q 6
2023-05-16 18:51:57 --> 3 NMBS req <- address_rtu 1.fc 16.a 80.q 6.b 12.r
2023-05-16 18:51:58 --> egs 1 33 10 0 500 0 
2023-05-16 18:51:58 --> WaitingStart AutoMode:1
2023-05-16 18:51:58 --> 3 NMBS req <- address_rtu 1.fc 16.a 80.q 6.b 12.regs 1 33 10 0 500 0 

I bypassed the regular read to show you only the request which causes the problem but I realize that it "hides" the problem : its working but it's very very long for the second device (~500-1000ms).

If you want I can make a simpler code to test the communication outside of my project. I don't know in which timezone you are but I can try to make it in one hour ^^

debevv commented 1 year ago

Well, from the logs it doesn't seem so bad, the only problem I see it's the client returning a NMBS_ERROR_TIMEOUT. Server 1 is correctly reading and skipping the messages, server 2 is receiving and responding correctly too.

Looks like you are on arduino, did you check out the examples? (these are tested, I promise). Maybe try using the same read_serial() and write_serial() platform funcs EDIT just realized the are basically the same plus the RS485 GPIOs, nevermind

I'm in Italy, but I'm usually working the whole day so no problem

kopierreko commented 1 year ago

Here is a more simple code :

const int rs485_rx {16}; const int rs485_tx {17}; const int rs485_de {15}; const int rs485_re {32};

const int button_short_pin {35}; const int button_normal_pin {25}; const int button_long_pin {26};

nmbs_t nmbs; nmbs_error err;

int32_t read_serial(uint8_t buf, uint16_t count, int32_t byte_timeout_ms, void arg) { digitalWrite(rs485_re, LOW); Serial2.setTimeout(byte_timeout_ms); int r = Serial2.readBytes(buf, count); digitalWrite(rs485_re, HIGH); return r; }

int32_t write_serial(const uint8_t buf, uint16_t count, int32_t byte_timeout_ms, void arg) { digitalWrite(rs485_de, HIGH); int32_t r = Serial2.write(buf, count); Serial2.flush(); digitalWrite(rs485_de, LOW); return r; } void onError() { Serial.print("modbus error : "); Serial.println(err); Serial.println(); }

void setup() { Serial.begin(9600); delay(1000); Serial.println((String)"Modbus Client Example"); delay(1000);

pinMode(rs485_re, OUTPUT); pinMode(rs485_de, OUTPUT); digitalWrite(rs485_re, LOW); digitalWrite(rs485_de, LOW); Serial2.begin(115200, SERIAL_8N1, rs485_rx, rs485_tx);

nmbs_platform_conf platform_conf; platform_conf.transport = NMBS_TRANSPORT_RTU; platform_conf.read = read_serial; platform_conf.write = write_serial;

err = nmbs_client_create(&nmbs, &platform_conf); if (err != NMBS_ERROR_NONE) onError();

nmbs_set_read_timeout(&nmbs, 50); nmbs_set_byte_timeout(&nmbs, 10);

pinMode(button_short_pin, INPUT);//btn A on=low pinMode(button_normal_pin, INPUT);//btn B on=low pinMode(button_long_pin, INPUT);//btn C on=low }

int getSwitch() { if (!digitalRead(button_short_pin)) { return 1; } else if (!digitalRead(button_normal_pin)) { return 2; } else if (!digitalRead(button_long_pin)) { return 3; } else { return 0; } }

//Returns true if no error bool readServer(const int &id, bool &value) { nmbs_set_destination_rtu_address(&nmbs, id); uint16_t answer[1]; uint8_t begin_register {0x31};

err = nmbs_read_holding_registers(&nmbs, begin_register, 1, answer); if (err != NMBS_ERROR_NONE) { onError(); return false; } else { value = answer[0]; return true; } }

bool writeServer(const int &id) { uint16_t data[6]; //Prepare data data[0] = true; data[1] = 34; uint32_t value1 {0x01234567}; data[2] = (uint16_t)(value1 & 0xFFFF); data[3] = (uint16_t)((value1 >> 16) & 0xFFFF); uint32_t value2 {0x89ABCDEF}; data[4] = (uint16_t)(value2 & 0xFFFF); data[5] = (uint16_t)((value2 >> 16) & 0xFFFF);

nmbs_set_destination_rtu_address(&nmbs, id);

err = nmbs_write_multiple_registers(&nmbs, 0x50, 6, data); if (err != NMBS_ERROR_NONE) { onError(); return false; } else { return true; } }

void customDelay(const int &waitingTime) { const auto _begin {millis()}; while (millis() < _begin + waitingTime) {

const auto sw = getSwitch();

if (sw != 0) {
  bool send_1 = writeServer(1);
  Serial.println((String)"Send values to ID 1 : "+send_1);
  bool send_2 = writeServer(3);
  Serial.println((String)"Send values to ID 3 : "+send_2);

  delay(20);
}

err = nmbs_server_poll(&nmbs);
// This will probably never happen, since we don't return < 0 in our platform funcs
if (err == NMBS_ERROR_TRANSPORT) {
  Serial.println((String)millis()+" Modbus Error transport");
}

} }

void loop() {

//Read bool v1, v2; Serial.print("- Read V1 on server ID 1 : "); bool v1_r = readServer(1, v1); if (v1_r) { Serial.println((String)" value received="+v1+"."); } else { Serial.println("failed."); }

customDelay(1);

Serial.print("- Read V1 on server ID 3 : "); bool v2_r = readServer(3, v2); if (v2_r) { Serial.println((String)" value received="+v2+"."); } else { Serial.println("failed."); }

Serial.println("\r\n");

customDelay(1000); }


Servers :

include

include "nanomodbus.h"

int device_id {1};

include

struct EEPROMData { int id; double distanceGoal; unsigned long durationGoal; bool autoMode; uint32_t color; int volume; int autoModeDisplay; bool epicMode; int checkValue; };

void initEEPROM() { EEPROMData data; EEPROM.get(0, data);

// Si les données ne sont pas initialisées en EEPROM, les initialiser avec les valeurs par défaut if (data.checkValue != 3175) { Serial.println("not init"); data.id = 3; data.checkValue = 3175; EEPROM.put(0, data); EEPROM.commit(); } }

void loadEEPROMData() { EEPROMData data; EEPROM.get(0, data); device_id = data.id; Serial.println((String)"id loaded "+device_id); }

void saveEEPROMData() { Serial.println((String)"save id "+device_id); EEPROMData data; data.id = device_id; data.checkValue = 3175;

EEPROM.put(0, data); EEPROM.commit(); }

void saveBaseEEPROMData() { EEPROMData data; data.id = 2; data.distanceGoal = 0; data.durationGoal = 0; data.autoMode = 0; data.color = 0; data.autoModeDisplay = 0; data.volume = 25; data.epicMode = false; data.checkValue = 3175;

EEPROM.put(0, data); EEPROM.commit(); }

define COILS_ADDR_MAX 100

define REGS_ADDR_MAX 32

// New modbus nmbs_t nmbs; nmbs_error err; nmbs_bitfield server_coils = {0}; uint16_t server_registers[REGS_ADDR_MAX] = {0};

const int rs485_rx {16}; const int rs485_tx {17}; const int rs485_de {15}; const int rs485_re {32};

int32_t read_serial(uint8_t buf, uint16_t count, int32_t byte_timeout_ms, void arg) { digitalWrite(rs485_re, LOW); Serial2.setTimeout(byte_timeout_ms); return Serial2.readBytes(buf, count); }

int32_t write_serial(const uint8_t buf, uint16_t count, int32_t byte_timeout_ms, void arg) { digitalWrite(rs485_re, HIGH); digitalWrite(rs485_de, HIGH);

int32_t r = Serial2.write(buf, count); Serial2.flush();

digitalWrite(rs485_de, LOW); digitalWrite(rs485_re, LOW); return r; }

void onError() { Serial.print("modbus error : "); Serial.println(err); }

nmbs_error handle_read_coils(uint16_t address, uint16_t quantity, nmbs_bitfield coils_out, void *arg) { if (address + quantity > COILS_ADDR_MAX + 1) return NMBS_EXCEPTION_ILLEGAL_DATA_ADDRESS;

Serial.println("read coils received but it shoudln't");

return NMBS_ERROR_NONE; }

nmbs_error handle_write_multiple_coils(uint16_t address, uint16_t quantity, const nmbs_bitfield coils, void *arg) { if (address + quantity > COILS_ADDR_MAX + 1) return NMBS_EXCEPTION_ILLEGAL_DATA_ADDRESS;

Serial.println("write multiple coils received but it shoudln't");

return NMBS_ERROR_NONE; }

nmbs_error handler_read_holding_registers(uint16_t address, uint16_t quantity, uint16_t registers_out, void arg) {
const int maxRegister {address + quantity}; Serial.print("Read holding registers addr="); Serial.print(address); Serial.print(" qty="); Serial.print(quantity); Serial.println(" end.\r\n"); return NMBS_ERROR_NONE; }

nmbs_error handle_write_multiple_registers(uint16_t address, uint16_t quantity, const uint16_t registers, void arg) { Serial.print("Write multiple registers "); Serial.print(address); Serial.print(" "); Serial.print(quantity); Serial.print(" "); for (uint16_t i = address; i < (address + quantity); i++) { Serial.print(registers[i], HEX); Serial.print(" "); } Serial.println(" end."); return NMBS_ERROR_NONE; }

void setup() {

EEPROM.begin(100);

initEEPROM(); loadEEPROMData();

Serial.begin(9600); delay(1000); Serial.println((String)"Modbus Server Example : ID="+device_id); delay(1000); pinMode(rs485_re, OUTPUT); pinMode(rs485_de, OUTPUT); digitalWrite(rs485_re, LOW); digitalWrite(rs485_de, LOW);

Serial2.setRxBufferSize(500); Serial2.begin(115200, SERIAL_8N1, rs485_rx, rs485_tx);

nmbs_platform_conf platform_conf; platform_conf.transport = NMBS_TRANSPORT_RTU; platform_conf.read = read_serial; platform_conf.write = write_serial; platform_conf.arg = NULL;

nmbs_callbacks callbacks = {0}; callbacks.read_coils = handle_read_coils; callbacks.write_multiple_coils = handle_write_multiple_coils; callbacks.read_holding_registers = handler_read_holding_registers; callbacks.write_multiple_registers = handle_write_multiple_registers;

nmbs_error err = nmbs_server_create(&nmbs, device_id, &platform_conf, &callbacks); if (err != NMBS_ERROR_NONE) { onError(); } else { Serial.println("Modbus OK"); }

nmbs_set_read_timeout(&nmbs, 10); nmbs_set_byte_timeout(&nmbs, 100); }

void loop() { err = nmbs_server_poll(&nmbs);

if (err == NMBS_ERROR_TRANSPORT) { Serial.println("Modbus Error transport"); } }


I make a regular read_multiple_registers which is quite OK but have some difficulties on boot, and I linked a write_holding_registers on some buttons on my physical interface.

Here is the debug of the regular communication (1000ms btw sendings, 1ms btw the 2 messages) :
Client :

2023-05-16 20:54:37 --> - Read V1 on server ID 1 : modbus error : -3 2023-05-16 20:54:37 --> 2023-05-16 20:54:37 --> 2023-05-16 20:54:37 --> failed. 2023-05-16 20:54:37 --> - Read V1 on server ID 3 : value received=0 2023-05-16 20:54:37 --> . 2023-05-16 20:54:37 --> 2023-05-16 20:54:37 --> 2023-05-16 20:54:38 --> - Read V1 o 2023-05-16 20:54:38 --> n server ID 1 : value received=0. 2023-05-16 20:54:38 --> - Read V1 on 2023-05-16 20:54:38 --> server ID 3 : modbus error : -3 2023-05-16 20:54:38 --> 2023-05-16 20:54:38 --> failed. 2023-05-16 20:54:38 --> 2023-05-16 20:54:38 --> 2023-05-16 20:54:39 --> - Read V1 on server ID 1 : value received=0. 2023-05-16 20:54:39 --> - Rea 2023-05-16 20:54:39 --> d V1 on server ID 3 : modbus error : -3 2023-05-16 20:54:39 --> 2023-05-16 20:54:39 --> failed. 2023-05-16 20:54:39 --> 2023-05-16 20:54:39 --> 2023-05-16 20:54:40 --> - Read V1 on 2023-05-16 20:54:40 --> server ID 1 : value received=0. 2023-05-16 20:54:40 --> - Read V1 on server ID 3 : value rece 2023-05-16 20:54:40 --> ived=0. 2023-05-16 20:54:40 --> 2023-05-16 20:54:40 --> 2023-05-16 20:54:41 --> - Read V1 on 2023-05-16 20:54:41 --> server ID 1 : value received=0. 2023-05-16 20:54:41 --> - Read V1 on server ID 3 : value r 2023-05-16 20:54:42 --> eceived=0. 2023-05-16 20:54:42 --> 2023-05-16 20:54:42 --> 2023-05-16 20:54:42 --> - Read V1 2023-05-16 20:54:43 --> on server ID 1 : value received=0. 2023-05-16 20:54:43 --> - Read V1 on server ID 3 : value 2023-05-16 20:54:43 --> received=0. 2023-05-16 20:54:43 --> 2023-05-16 20:54:43 --> 2023-05-16 20:54:44 --> - Read V1 2023-05-16 20:54:44 --> on server ID 1 : value received=0. 2023-05-16 20:54:44 --> - Read V1 on server ID 3 : valu 2023-05-16 20:54:44 --> e received=0. 2023-05-16 20:54:44 --> 2023-05-16 20:54:44 --> 2023-05-16 20:54:45 --> - Read V1 2023-05-16 20:54:45 --> on server ID 1 : value received=0. 2023-05-16 20:54:45 --> - Read V1 on server ID 3 : va 2023-05-16 20:54:45 --> lue received=0. 2023-05-16 20:54:45 --> 2023-05-16 20:54:45 --> 2023-05-16 20:54:46 --> - Rea 2023-05-16 20:54:46 --> d V1 on server ID 1 : value received=0. 2023-05-16 20:54:46 --> - Read V1 on server ID 3 : val 2023-05-16 20:54:46 --> ue received=0. 2023-05-16 20:54:46 --> 2023-05-16 20:54:46 --> 2023-05-16 20:54:47 --> - Read V1 on server ID 1 : value received=0. 2023-05-16 20:54:47 --> - Read V1 on server ID 3 : 2023-05-16 20:54:47 --> value received=0. 2023-05-16 20:54:47 --> 2023-05-16 20:54:47 -->


Server 1 :

2023-05-16 20:54:39 --> 1 NMBS req <- address_rtu 1.fc 3.a 49.q 1 2023-05-16 20:54:39 --> Read holding registers addr=49 q 2023-05-16 20:54:39 --> ty=1 end. 2023-05-16 20:54:39 --> 2023-05-16 20:54:39 --> 1 NMBS res -> address_rtu 1.fc 3.b 2.regs 0 2023-05-16 20:54:39 --> 1 NMBS req <- address_rtu 3.fc 3.a 49. 2023-05-16 20:54:39 --> q 1 2023-05-16 20:54:39 --> 1 NMBS req <- address_rtu 3.fc 3.a 512.q 193 2023-05-16 20:54:40 --> 1 NMBS req <- address_rtu 1 2023-05-16 20:54:40 --> .fc 3.a 49.q 1 2023-05-16 20:54:40 --> Read holding registers addr=49 qty=1 end. 2023-05-16 20:54:40 --> 2023-05-16 20:54:40 --> 1 NMBS res -> address_rtu 1.fc 3.b 2023-05-16 20:54:40 --> 2.regs 0 2023-05-16 20:54:40 --> 1 NMBS req <- address_rtu 3.fc 3.a 49.q 1 2023-05-16 20:54:40 --> 1 NMBS req <- address_rtu 3.fc 3.a 512.q 2023-05-16 20:54:41 --> 193 2023-05-16 20:54:41 --> 1 NMBS req <- address_rtu 1. 2023-05-16 20:54:41 --> fc 3.a 49.q 1 2023-05-16 20:54:41 --> Read holding registers addr=49 qty=1 end. 2023-05-16 20:54:41 --> 2023-05-16 20:54:41 --> 1 NMBS res -> address_rtu 1.fc 3.b 2023-05-16 20:54:42 --> 2.regs 0 2023-05-16 20:54:42 --> 1 NMBS req <- address_rtu 3.fc 3.a 49.q 1 2023-05-16 20:54:42 --> 1 NMBS req <- address_rtu 3.fc 3.a 512.q 2023-05-16 20:54:42 --> 193 2023-05-16 20:54:42 --> 1 NMBS req <- address_rt 2023-05-16 20:54:43 --> u 1.fc 3.a 49.q 1 2023-05-16 20:54:43 --> Read holding registers addr=49 qty=1 end. 2023-05-16 20:54:43 --> 2023-05-16 20:54:43 --> 1 NMBS res -> address_rtu 1.fc 3.b 2023-05-16 20:54:43 --> 2.regs 0 2023-05-16 20:54:43 --> 1 NMBS req <- address_rtu 3.fc 3.a 49.q 1 2023-05-16 20:54:43 --> 1 NMBS req <- address_rtu 3.fc 3.a 512.q 2023-05-16 20:54:43 --> 193 2023-05-16 20:54:44 --> 1 NMBS req <- address_rtu 2023-05-16 20:54:44 --> 1.fc 3.a 49.q 1 2023-05-16 20:54:44 --> Read holding registers addr=49 qty=1 end. 2023-05-16 20:54:44 --> 2023-05-16 20:54:44 --> 1 NMBS res -> address_rtu 1.fc 2023-05-16 20:54:44 --> 3.b 2.regs 0 2023-05-16 20:54:44 --> 1 NMBS req <- address_rtu 3.fc 3.a 49.q 1 2023-05-16 20:54:44 --> 1 NMBS req <- address_rtu 3.fc 3.a 512.q 1 2023-05-16 20:54:44 --> 93 2023-05-16 20:54:45 --> 1 NMBS req <- address 2023-05-16 20:54:45 --> _rtu 1.fc 3.a 49.q 1 2023-05-16 20:54:45 --> Read holding registers addr=49 qty=1 end. 2023-05-16 20:54:45 --> 2023-05-16 20:54:45 --> 1 NMBS res -> address_rtu 1.fc 2023-05-16 20:54:45 --> 3.b 2.regs 0 2023-05-16 20:54:45 --> 1 NMBS req <- address_rtu 3.fc 3.a 49.q 1 2023-05-16 20:54:45 --> 1 NMBS req <- address_rtu 3.fc 3.a 512 2023-05-16 20:54:45 --> .q 193 2023-05-16 20:54:46 --> 1 NMBS req <- address_r 2023-05-16 20:54:46 --> tu 1.fc 3.a 49.q 1 2023-05-16 20:54:46 --> Read holding registers addr=49 qty=1 end. 2023-05-16 20:54:46 --> 2023-05-16 20:54:46 --> 1 NMBS res -> address_rtu 1.fc 3 2023-05-16 20:54:46 --> .b 2.regs 0 2023-05-16 20:54:46 --> 1 NMBS req <- address_rtu 3.fc 3.a 49.q 1 2023-05-16 20:54:46 --> 1 NMBS req <- address_rtu 3.fc 3.a 2023-05-16 20:54:46 --> 512.q 193 2023-05-16 20:54:47 --> 1 NMBS req <- add 2023-05-16 20:54:47 --> ress_rtu 1.fc 3.a 49.q 1 2023-05-16 20:54:47 --> Read holding registers addr=49 qty=1 end. 2023-05-16 20:54:47 --> 2023-05-16 20:54:47 --> 1 NMBS res -> address_rtu 1 2023-05-16 20:54:47 --> .fc 3.b 2.regs 0 2023-05-16 20:54:47 --> 1 NMBS req <- address_rtu 3.fc 3.a 49.q 1 2023-05-16 20:54:47 --> 1 NMBS req <- address_rtu 3.fc 3.a 512. 2023-05-16 20:54:47 --> q 193 2023-05-16 20:54:48 --> 1 NMBS req <- 2023-05-16 20:54:48 --> address_rtu 1.fc 3.a 49.q 1 2023-05-16 20:54:48 --> Read holding registers addr=49 qty=1 end. 2023-05-16 20:54:48 --> 2023-05-16 20:54:48 --> 1 NMBS res -> address_rtu 1 2023-05-16 20:54:48 --> .fc 3.b 2.regs 0 2023-05-16 20:54:48 --> 1 NMBS req <- address_rtu 3.fc 3.a 49.q 1 2023-05-16 20:54:48 --> 1 NMBS req <- address_rtu 3.fc 3.a 512.q 193


Server 2 : 

2023-05-16 20:54:38 --> 3 NMBS req <- address_rtu 1.fc 3.a 49.q 1 2023-05-16 20:54:38 --> 3 NMBS req <- address_rtu 1.fc 3.a 512.q 184 2023-05-16 20:54:38 --> 2023-05-16 20:54:39 --> 3 NMBS req <- address_rtu 1.fc 3.a 49.q 2023-05-16 20:54:39 --> 1 2023-05-16 20:54:39 --> 3 NMBS res <- address_rtu 1.fc 3.b 2.regs 0 2023-05-16 20:54:39 --> 3 NMBS req <- address_rtu 3.fc 3.a 49.q 1 2023-05-16 20:54:39 --> Read ho 2023-05-16 20:54:39 --> lding registers addr=49 qty=1 end. 2023-05-16 20:54:39 --> 2023-05-16 20:54:39 --> 3 NMBS res -> address_rtu 3.fc 3.b 2.regs 0 2023-05-16 20:54:40 --> 3 NMBS req <- address_rtu 1.fc 3.a 49.q 1 2023-05-16 20:54:40 --> 3 NMBS res <- address_rtu 1.fc 3.b 2.regs 0 2023-05-16 20:54:40 --> 2023-05-16 20:54:40 --> 3 NMBS req <- address_rtu 3.fc 3.a 49.q 1 2023-05-16 20:54:40 --> Read holding registers addr=49 qty=1 end. 2023-05-16 20:54:40 --> 2023-05-16 20:54:40 --> 3 NMBS res 2023-05-16 20:54:40 --> -> address_rtu 3.fc 3.b 2.regs 0 2023-05-16 20:54:41 --> 3 NMBS req <- address_rtu 1.fc 3.a 49.q 1 2023-05-16 20:54:41 --> 3 NMBS res <- address_rtu 1.fc 3.b 2.regs 2023-05-16 20:54:41 --> 0 2023-05-16 20:54:41 --> 3 NMBS req <- address_rtu 3.fc 3.a 49.q 1 2023-05-16 20:54:41 --> Read holding registers addr=49 qty=1 end. 2023-05-16 20:54:41 --> 2023-05-16 20:54:41 --> 3 NMB 2023-05-16 20:54:42 --> S res -> address_rtu 3.fc 3.b 2.regs 0 2023-05-16 20:54:42 --> 3 NMBS req <- address_rtu 1.fc 3.a 49.q 1 2023-05-16 20:54:42 --> 3 NMBS res <- address_rtu 1.fc 3.b 2.regs 0 2023-05-16 20:54:43 --> 2023-05-16 20:54:43 --> 3 NMBS req <- address_rtu 3.fc 3.a 49.q 1 2023-05-16 20:54:43 --> Read holding registers addr=49 qty=1 end. 2023-05-16 20:54:43 --> 2023-05-16 20:54:43 --> 3 N 2023-05-16 20:54:43 --> MBS res -> address_rtu 3.fc 3.b 2.regs 0 2023-05-16 20:54:44 --> 3 NMBS req <- address_rtu 1.fc 3.a 49.q 1 2023-05-16 20:54:44 --> 3 NMBS res <- address_rtu 1.fc 3.b 2.re 2023-05-16 20:54:44 --> gs 0 2023-05-16 20:54:44 --> 3 NMBS req <- address_rtu 3.fc 3.a 49.q 1 2023-05-16 20:54:44 --> Read holding registers addr=49 qty=1 end. 2023-05-16 20:54:44 --> 2023-05-16 20:54:44 --> 3 NMB 2023-05-16 20:54:44 --> S res -> address_rtu 3.fc 3.b 2.regs 0 2023-05-16 20:54:45 --> 3 NMBS req <- address_rtu 1.fc 3.a 49.q 1 2023-05-16 20:54:45 --> 3 NMBS res <- address_rtu 1.fc 3.b 2. 2023-05-16 20:54:45 --> regs 0 2023-05-16 20:54:45 --> 3 NMBS req <- address_rtu 3.fc 3.a 49.q 1 2023-05-16 20:54:45 --> Read holding registers addr=49 qty=1 end. 2023-05-16 20:54:45 --> 2023-05-16 20:54:45 --> 3 NMBS res -> address_rtu 3.fc 3.b 2.regs 0 2023-05-16 20:54:46 --> 3 NMBS req <- address_rtu 1.fc 3.a 49.q 1 2023-05-16 20:54:46 --> 3 NMBS res <- address_rtu 1.fc 3.b 2.r 2023-05-16 20:54:46 --> egs 0 2023-05-16 20:54:46 --> 3 NMBS req <- address_rtu 3.fc 3.a 49.q 1 2023-05-16 20:54:46 --> Read holding registers addr=49 qty=1 end. 2023-05-16 20:54:46 --> 2023-05-16 20:54:46 --> 2023-05-16 20:54:46 --> 3 NMBS res -> address_rtu 3.fc 3.b 2.regs 0 2023-05-16 20:54:47 --> 3 NMBS req <- address_rtu 1.fc 3.a 49.q 1 2023-05-16 20:54:47 --> 3 NMBS res <- address_rtu 1.fc 3. 2023-05-16 20:54:47 --> b 2.regs 0 2023-05-16 20:54:47 --> 3 NMBS req <- address_rtu 3.fc 3.a 49.q 1 2023-05-16 20:54:47 --> Read holding registers addr=49 qty=1 end. 2023-05-16 20:54:47 --> 2023-05-16 20:54:47 --> 2023-05-16 20:54:47 --> 3 NMBS res -> address_rtu 3.fc 3.b 2.regs 0 2023-05-16 20:54:48 --> 3 NMBS req <- address_rtu 1.fc 3.a 49.q 1 2023-05-16 20:54:48 --> 3 NMBS res <- address_rtu 1.fc 3


And now with me pushing buttons (+ regular exchanges) :

Client :

2023-05-16 20:56:26 --> - Read V1 on server ID 1 : value received=0. 2023-05-16 20:56:26 --> - Read V1 on server ID 3 : value received=0. 2023-05-16 20:56:26 --> 2023-05-16 20:56:26 --> 2023-05-16 20:56:27 --> - Read V1 on server ID 1 : value received=0. 2023-05-16 20:56:27 --> - Read V1 on server ID 3 : value received=0. 2023-05-16 20:56:27 --> 2023-05-16 20:56:27 --> 2023-05-16 20:56:28 --> - Read V1 on server ID 1 : value received=0. 2023-05-16 20:56:28 --> - Read V1 on server ID 3 : value received=0. 2023-05-16 20:56:28 --> 2023-05-16 20:56:28 --> 2023-05-16 20:56:29 --> - Read V1 on server ID 1 : value received=0. 2023-05-16 20:56:29 --> - Read V1 on server ID 3 : value received=0. 2023-05-16 20:56:29 --> 2023-05-16 20:56:29 --> 2023-05-16 20:56:30 --> modbus error : -3 2023-05-16 20:56:30 --> 2023-05-16 20:56:30 --> Send values to ID 1 : 0 2023-05-16 20:56:30 --> modbus error : -3 2023-05-16 20:56:30 --> 2023-05-16 20:56:30 --> Send values to ID 3 2023-05-16 20:56:30 --> : 0 2023-05-16 20:56:30 --> - Read V1 2023-05-16 20:56:31 --> on server ID 1 : modbus error : -3 2023-05-16 20:56:31 --> 2023-05-16 20:56:31 --> failed. 2023-05-16 20:56:31 --> - Read V 2023-05-16 20:56:31 --> 1 on server ID 3 : modbus error : -7 2023-05-16 20:56:31 --> 2023-05-16 20:56:31 --> failed. 2023-05-16 20:56:31 --> 2023-05-16 20:56:31 --> 2023-05-16 20:56:31 --> modbus error : -3 2023-05-16 20:56:31 --> 2023-05-16 20:56:31 --> Send values to ID 1 : 0 2023-05-16 20:56:31 --> modbus error : -3 2023-05-16 20:56:31 --> 2023-05-16 20:56:31 --> Send values to ID 3 : 0 2023-05-16 20:56:31 --> modbus error : -3 2023-05-16 20:56:31 --> 2023-05-16 20:56:31 --> Send values to ID 1 : 0 2023-05-16 20:56:31 --> Send values to 2023-05-16 20:56:31 --> ID 3 : 1 2023-05-16 20:56:32 --> - Read V1 on server ID 1 : value re 2023-05-16 20:56:32 --> ceived=0. 2023-05-16 20:56:32 --> modbus error : -3 2023-05-16 20:56:32 --> 2023-05-16 20:56:32 --> Send values to ID 1 : 0 2023-05-16 20:56:32 --> modbus error : -3 2023-05-16 20:56:32 --> 2023-05-16 20:56:32 --> Sen 2023-05-16 20:56:32 --> d values to ID 3 : 0 2023-05-16 20:56:32 --> - Read V1 on server ID 3 : modbus error : -7 2023-05-16 20:56:32 --> 2023-05-16 20:56:32 --> 2023-05-16 20:56:32 --> failed. 2023-05-16 20:56:32 --> 2023-05-16 20:56:32 --> 2023-05-16 20:56:32 --> modbus error : -3 2023-05-16 20:56:32 --> 2023-05-16 20:56:32 --> Send values to ID 1 : 0 2023-05-16 20:56:32 --> modbus 2023-05-16 20:56:33 --> error : -3 2023-05-16 20:56:33 --> 2023-05-16 20:56:33 --> Send values to ID 3 : 0 2023-05-16 20:56:33 --> - Read V1 on server ID 1 : value received=0. 2023-05-16 20:56:33 --> - Read V1 on ser 2023-05-16 20:56:33 --> ver ID 3 : modbus error : -3 2023-05-16 20:56:33 --> 2023-05-16 20:56:33 --> failed. 2023-05-16 20:56:33 --> 2023-05-16 20:56:33 --> 2023-05-16 20:56:33 --> modbus error : -3 2023-05-16 20:56:33 --> 2023-05-16 20:56:33 --> 2023-05-16 20:56:33 --> Send values to ID 1 : 0 2023-05-16 20:56:33 --> modbus error : -2 2023-05-16 20:56:33 --> 2023-05-16 20:56:33 --> Send values to ID 3 : 0 2023-05-16 20:56:34 --> - Read V1 on server ID 1 : modbu 2023-05-16 20:56:34 --> s error : -3 2023-05-16 20:56:34 --> 2023-05-16 20:56:34 --> failed. 2023-05-16 20:56:34 --> - Read V1 on server ID 3 : modbus error : -7 2023-05-16 20:56:34 --> 2023-05-16 20:56:34 --> failed 2023-05-16 20:56:34 --> . 2023-05-16 20:56:34 --> 2023-05-16 20:56:34 --> 2023-05-16 20:56:35 --> modbus error : -3 2023-05-16 20:56:35 --> 2023-05-16 20:56:35 --> Send values to ID 1 : 0 2023-05-16 20:56:35 --> 2023-05-16 20:56:35 --> modbus error : -3 2023-05-16 20:56:35 --> 2023-05-16 20:56:35 --> Send values to ID 3 : 0 2023-05-16 20:56:35 --> modbus error : -7 2023-05-16 20:56:35 --> 2023-05-16 20:56:35 --> 2023-05-16 20:56:35 --> Send values to ID 1 : 0 2023-05-16 20:56:35 --> modbus error : -7 2023-05-16 20:56:35 --> 2023-05-16 20:56:35 --> Send values to ID 3 : 0 2023-05-16 20:56:35 --> modbus error : -3 2023-05-16 20:56:35 --> 2023-05-16 20:56:35 --> Send values to ID 1 : 0 2023-05-16 20:56:35 --> modbus error : -3 2023-05-16 20:56:35 --> 2023-05-16 20:56:35 --> Send val 2023-05-16 20:56:35 --> ues to ID 3 : 0 2023-05-16 20:56:35 --> - Read V1 on server ID 1 : modbus error : -3 2023-05-16 20:56:35 --> 2023-05-16 20:56:35 --> failed. 2023-05-16 20:56:35 --> - R 2023-05-16 20:56:35 --> ead V1 on server ID 3 : modbus error : -3 2023-05-16 20:56:35 --> 2023-05-16 20:56:35 --> failed. 2023-05-16 20:56:35 --> 2023-05-16 20:56:35 --> 2023-05-16 20:56:35 --> modb 2023-05-16 20:56:36 --> us error : -3 2023-05-16 20:56:36 --> 2023-05-16 20:56:36 --> Send values to ID 1 : 0 2023-05-16 20:56:36 --> modbus error : -3 2023-05-16 20:56:36 --> 2023-05-16 20:56:36 --> Send values to ID 3 : 0 2023-05-16 20:56:36 --> modbus error : -3 2023-05-16 20:56:36 --> 2023-05-16 20:56:36 --> Send values to ID 1 : 0 2023-05-16 20:56:36 --> modbus error : -3 2023-05-16 20:56:36 --> 2023-05-16 20:56:36 --> 2023-05-16 20:56:36 --> Send values to ID 3 : 0 2023-05-16 20:56:36 --> - Read V1 on server ID 1 : value r 2023-05-16 20:56:36 --> eceived=0. 2023-05-16 20:56:36 --> - Read V1 on server ID 3 : modbus error : -3 2023-05-16 20:56:36 --> 2023-05-16 20:56:36 --> faile 2023-05-16 20:56:37 --> d. 2023-05-16 20:56:37 --> 2023-05-16 20:56:37 --> 2023-05-16 20:56:38 --> - Read V1 on server ID 1 : value received=0. 2023-05-16 20:56:38 --> - Read V1 on server ID 3 : 2023-05-16 20:56:38 --> value received=0. 2023-05-16 20:56:38 --> 2023-05-16 20:56:38 -->


Server 1:

2023-05-16 20:56:28 --> 1 NMBS req <- address_rtu 1.fc 3.a 49.q 1 2023-05-16 20:56:28 --> Read holding registe 2023-05-16 20:56:28 --> rs addr=49 qty=1 end. 2023-05-16 20:56:28 --> 2023-05-16 20:56:28 --> 1 NMBS res -> address_rtu 1.fc 3.b 2.regs 0 2023-05-16 20:56:28 --> 1 NMBS req <- address_rtu 2023-05-16 20:56:28 --> 3.fc 3.a 49.q 1 2023-05-16 20:56:28 --> 1 NMBS req <- address_rtu 3.fc 3.a 512.q 193 2023-05-16 20:56:29 --> 1 NMBS req <- address_rtu 1.fc 3.a 49.q 1 2023-05-16 20:56:29 --> Read holding regis 2023-05-16 20:56:29 --> ters addr=49 qty=1 end. 2023-05-16 20:56:29 --> 2023-05-16 20:56:29 --> 1 NMBS res -> address_rtu 1.fc 3.b 2.regs 0 2023-05-16 20:56:29 --> 1 NMBS req <- address_r 2023-05-16 20:56:30 --> tu 3.fc 3.a 49.q 1 2023-05-16 20:56:30 --> 1 NMBS req <- address_rtu 3.fc 3.a 512.q 193 2023-05-16 20:56:30 --> 1 NMBS req <- address_rtu 1.fc 16.a 80.q 6.b 12.regs 1 34 17767 2023-05-16 20:56:30 --> 291 52719 35243 2023-05-16 20:56:30 --> Write multiple registers 80 6 FFFF B33F 26A4 800D 2 0 end. 2023-05-16 20:56:30 --> 1 NMBS re 2023-05-16 20:56:30 --> s -> address_rtu 1.fc 16.a 80.q 6 2023-05-16 20:56:30 --> 1 NMBS req <- address_rtu 3.fc 16.a 80.q 6.b 12.regs 1 34 17767 2023-05-16 20:56:30 --> 291 52719 35243 2023-05-16 20:56:30 --> 1 NMBS req <- address_rtu 3 2023-05-16 20:56:31 --> .fc 16.a 80.q 6.b 65.regs 1 NMBS req <- address_rtu 1.fc 3.a 49.q 1 2023-05-16 20:56:31 --> Read holding registers 2023-05-16 20:56:31 --> addr=49 qty=1 end. 2023-05-16 20:56:31 --> 2023-05-16 20:56:31 --> 1 NMBS res -> address_rtu 1.fc 3.b 2.regs 0 2023-05-16 20:56:31 --> 1 NMBS req <- address_rtu 3. 2023-05-16 20:56:31 --> fc 3.a 49.q 1 2023-05-16 20:56:31 --> 1 NMBS req <- address_rtu 3.fc 3.a 512.q 193 2023-05-16 20:56:31 --> 1 NMBS req <- address_rtu 1.fc 16.a 80.q 2023-05-16 20:56:31 --> 6.b 12.regs 1 34 17767 291 52719 35243 2023-05-16 20:56:31 --> Write multiple registers 80 6 FFFF B33F 26A4 800D 2 2023-05-16 20:56:31 --> 0 end. 2023-05-16 20:56:31 --> 1 NMBS res -> address_rtu 1.fc 16.a 80.q 6 2023-05-16 20:56:31 --> 1 NMBS req <- address_rtu 3.fc 16.a 80.q 2023-05-16 20:56:31 --> 6.b 12.regs 1 34 17767 291 52719 35243 2023-05-16 20:56:31 --> 1 NMBS req <- broadcast.fc 80.1 NMBS req <- broadcast.f 2023-05-16 20:56:31 --> c 6.a 3072.value 256 2023-05-16 20:56:31 --> 1 NMBS req <- address_rtu 103.fc 1.a 9165.q 61321 2023-05-16 20:56:32 --> 1 NMBS req <- address_rtu 1.fc 3.a 49.q 1 2023-05-16 20:56:32 --> Read hold 2023-05-16 20:56:32 --> ing registers addr=49 qty=1 end. 2023-05-16 20:56:32 --> 2023-05-16 20:56:32 --> 1 NMBS res -> address_rtu 1.fc 3.b 2.regs 0 2023-05-16 20:56:32 --> 1 NMBS req <- ad 2023-05-16 20:56:32 --> dress_rtu 1.fc 16.a 80.q 6.b 12.regs 1 34 17767 291 52719 35243 2023-05-16 20:56:32 --> Write multiple registers 80 6 2023-05-16 20:56:32 --> FFFF B33F 26A4 800D 2 0 end. 2023-05-16 20:56:32 --> 1 NMBS res -> address_rtu 1.fc 16.a 80.q 6 2023-05-16 20:56:32 --> 1 NMBS req <- address_r 2023-05-16 20:56:32 --> tu 3.fc 16.a 80.q 6.b 12.regs 1 34 17767 291 52719 35243 2023-05-16 20:56:32 --> 1 NMBS req <- broadcast.fc 4 2023-05-16 20:56:32 --> 9.1 NMBS req <- broadcast.fc 1.1 NMBS req <- address_rtu 1.fc 16.a 80.q 6.b 12.regs 1 34 1776 2023-05-16 20:56:33 --> 7 291 52719 35243 2023-05-16 20:56:33 --> Write multiple registers 80 6 FFFF B33F 26A4 800D 2 0 end. 2023-05-16 20:56:33 --> 1 NMBS res -> a 2023-05-16 20:56:33 --> ddress_rtu 1.fc 16.a 80.q 6 2023-05-16 20:56:33 --> 1 NMBS req <- address_rtu 3.fc 16.a 80.q 6.b 12.regs 1 34 17767 2023-05-16 20:56:33 --> 291 52719 35243 2023-05-16 20:56:33 --> 1 NMBS res <- address_rtu 3.fc 16.a 80.q 6 2023-05-16 20:56:33 --> 1 NMBS req <- address_rtu 1.fc 3.a 49.q 1 2023-05-16 20:56:33 --> Read holding registers addr=49 qty=1 end. 2023-05-16 20:56:33 --> 2023-05-16 20:56:33 --> 1 N 2023-05-16 20:56:33 --> MBS res -> address_rtu 1.fc 3.b 2.regs 0 2023-05-16 20:56:33 --> 1 NMBS req <- address_rtu 3.fc 3.a 49.q 1 2023-05-16 20:56:33 --> 1 NMBS req <- address_rt 2023-05-16 20:56:33 --> u 1.fc 16.a 80.q 6.b 12.regs 1 34 17767 291 52719 35243 2023-05-16 20:56:33 --> Write multiple registers 2023-05-16 20:56:33 --> 80 6 FFFF B33F 26A4 800D 2 0 end. 2023-05-16 20:56:33 --> 1 NMBS res -> address_rtu 1.fc 16.a 80.q 6 2023-05-16 20:56:33 --> 1 NMBS r 2023-05-16 20:56:33 --> eq <- address_rtu 3.fc 16.a 80.q 6.b 12.regs 1 34 17767 291 52719 35243 2023-05-16 20:56:34 --> 1 NMBS req <- address_rtu 2.fc 0.1 NMBS req <- broadcast.fc 193.1 NMBS re 2023-05-16 20:56:34 --> q <- address_rtu 1.fc 3.a 49.q 1 2023-05-16 20:56:34 --> Read holding registers addr=49 qty=1 end. 2023-05-16 20:56:34 --> 2023-05-16 20:56:34 --> 1 NMBS res -> add 2023-05-16 20:56:34 --> ress_rtu 1.fc 3.b 2.regs 0 2023-05-16 20:56:34 --> 1 NMBS req <- address_rtu 3.fc 3.a 49.q 1 2023-05-16 20:56:34 --> 1 NMBS req <- address 2023-05-16 20:56:34 --> _rtu 3.fc 3.a 512.q 193 2023-05-16 20:56:35 --> 1 NMBS req <- a 2023-05-16 20:56:35 --> ddress_rtu 1.fc 16.a 80.q 6.b 12.regs 1 34 17767 291 52719 35243 2023-05-16 20:56:35 --> Write multiple registers 80 6 2023-05-16 20:56:35 --> FFFF B33F 26A4 800D 2 0 end. 2023-05-16 20:56:35 --> 1 NMBS res -> addressrtu 1.fc 16.a 80.q 6 2023-05-16 20:56:35 --> 1 NMBS req <- address 2023-05-16 20:56:35 --> rtu 3.fc 16.a 80.q 6.b 12.regs 1 34 17767 291 52719 35243 2023-05-16 20:56:35 --> 1 NMBS req <- broadcast.fc 80.1 2023-05-16 20:56:35 --> NMBS req <- broadcast.fc 6.a 3072.value 256 2023-05-16 20:56:35 --> 1 NMBS req <- address_rtu 103.fc 1.a 9165.q 2023-05-16 20:56:35 --> 61321 2023-05-16 20:56:35 --> 1 NMBS req <- address_rtu 1.fc 16.a 80.q 6.b 12.regs 1 34 17767 291 52719 35243 2023-05-16 20:56:35 --> Write multipl 2023-05-16 20:56:35 --> e registers 80 6 FFFF B33F 26A4 800D 2 0 end. 2023-05-16 20:56:35 --> 1 NMBS res -> address_rtu 1.fc 16.a 80.q 6 2023-05-16 20:56:35 --> 1 NMB 2023-05-16 20:56:35 --> S req <- address_rtu 3.fc 16.a 80.q 6.b 12.regs 1 34 17767 291 52719 35243 2023-05-16 20:56:35 --> 1 NMBS req <- broadcas 2023-05-16 20:56:35 --> t.fc 49.1 NMBS req <- broadcast.fc 1.a 54725.q 784 2023-05-16 20:56:35 --> 1 NMBS req <- broadcast.fc 6.a 16888.value 2023-05-16 20:56:36 --> 771 2023-05-16 20:56:36 --> 1 NMBS req <- broadcast.fc 1.a 54311.q 272 2023-05-16 20:56:36 --> 1 NMBS req <- broadcast.fc 6.a 3072.value 256 2023-05-16 20:56:36 --> 2023-05-16 20:56:36 --> 1 NMBS req <- address_rtu 103.fc 1.a 9165.q 61321 2023-05-16 20:56:36 --> 1 NMBS req <- address_rtu 3.fc 16.a 8 2023-05-16 20:56:36 --> 0.q 6.b 65.regs 1 NMBS req <- address_rtu 1.fc 16.a 80.q 6.b 12.regs 1 34 17767 291 52719 35243 2023-05-16 20:56:36 --> Writ 2023-05-16 20:56:36 --> e multiple registers 80 6 FFFF B33F 26A4 800D 2 0 end. 2023-05-16 20:56:36 --> 1 NMBS res -> address_rtu 1.fc 16.a 8 2023-05-16 20:56:36 --> 0.q 6 2023-05-16 20:56:36 --> 1 NMBS req <- address_rtu 3.fc 16.a 80.q 6.b 12.regs 1 34 17767 291 52719 35243 2023-05-16 20:56:36 --> 1 N 2023-05-16 20:56:36 --> MBS res <- address_rtu 3.fc 16.a 80.q 6 2023-05-16 20:56:36 --> 1 NMBS req <- address_rtu 1.fc 3.a 49.q 1 2023-05-16 20:56:36 --> Read holding 2023-05-16 20:56:36 --> registers addr=49 qty=1 end. 2023-05-16 20:56:36 --> 2023-05-16 20:56:36 --> 1 NMBS res -> address_rtu 1.fc 3.b 2.regs 0 2023-05-16 20:56:36 --> 1 NMBS req <- addr 2023-05-16 20:56:37 --> ess_rtu 3.fc 3.a 49.q 1 2023-05-16 20:56:37 --> 1 NMBS req <- address_rtu 3.fc 3.a 512.q 193 2023-05-16 20:56:37 --> 1 NM 2023-05-16 20:56:38 --> BS req <- address_rtu 1.fc 3.a 49.q 1 2023-05-16 20:56:38 --> Read holding registers addr=49 qty=1 end. 2023-05-16 20:56:38 --> 2023-05-16 20:56:38 --> 1 NMBS res -> 2023-05-16 20:56:38 --> address_rtu 1.fc 3.b 2.regs 0 2023-05-16 20:56:38 --> 1 NMBS req <- address_rtu 3.fc 3.a 49.q 1 2023-05-16 20:56:38 --> 1 NMBS req <- address_rt 2023-05-16 20:56:38 --> u 3.fc 3.a 512.q 193 2023-05-16 20:56:39 --> 1 NMBS re 2023-05-16 20:56:39 --> q <- address_rtu 1.fc 3.a 49.q 1 2023-05-16 20:56:39 --> Read holding registers addr=49 qty=1 end. 2023-05-16 20:56:39 --> 2023-05-16 20:56:39 --> 1 NMBS res -> ad 2023-05-16 20:56:39 --> dress_rtu 1.fc 3.b 2.regs 0 2023-05-16 20:56:39 --> 1 NMBS req <- address_rtu 3.fc 3.a 49.q 1 2023-05-16 20:56:39 --> 1 NMBS req <- address_rtu 3.fc 3.a 512.q 193


Server 2:

2023-05-16 20:56:27 --> 3 NMBS req <- address_rtu 1.f 2023-05-16 20:56:27 --> c 3.a 49.q 1 2023-05-16 20:56:27 --> 3 NMBS res <- address_rtu 1.fc 3.b 2.regs 0 2023-05-16 20:56:27 --> 3 NMBS req <- address_rtu 3.fc 3.a 49.q 2023-05-16 20:56:27 --> 1 2023-05-16 20:56:27 --> Read holding registers addr=49 qty=1 end. 2023-05-16 20:56:27 --> 2023-05-16 20:56:27 --> 3 NMBS res -> address_rtu 3.fc 3.b 2.regs 0 2023-05-16 20:56:27 --> 2023-05-16 20:56:28 --> 3 NMBS req <- address_rtu 1 2023-05-16 20:56:28 --> .fc 3.a 49.q 1 2023-05-16 20:56:28 --> 3 NMBS res <- address_rtu 1.fc 3.b 2.regs 0 2023-05-16 20:56:28 --> 3 NMBS req <- address_rtu 3.fc 3.a 2023-05-16 20:56:28 --> 49.q 1 2023-05-16 20:56:28 --> Read holding registers addr=49 qty=1 end. 2023-05-16 20:56:28 --> 2023-05-16 20:56:28 --> 3 NMBS res -> address_rtu 3.fc 3.b 2.regs 0 2023-05-16 20:56:29 --> 3 NMBS req <- address_rtu 1.fc 2023-05-16 20:56:29 --> 3.a 49.q 1 2023-05-16 20:56:29 --> 3 NMBS res <- address_rtu 1.fc 3.b 2.regs 0 2023-05-16 20:56:29 --> 3 NMBS req <- address_rtu 3.fc 3 2023-05-16 20:56:29 --> .a 49.q 1 2023-05-16 20:56:29 --> Read holding registers addr=49 qty=1 end. 2023-05-16 20:56:29 --> 2023-05-16 20:56:29 --> 3 NMBS res -> address_rtu 3.fc 3.b 2.reg 2023-05-16 20:56:30 --> s 0 2023-05-16 20:56:30 --> 3 NMBS req <- address_r 2023-05-16 20:56:30 --> tu 1.fc 16.a 80.q 6.b 12.regs 1 34 17767 291 52719 35243 2023-05-16 20:56:30 --> 3 NMBS req <- address_rtu 3.fc 16.a 80 2023-05-16 20:56:30 --> .q 6.b 12.regs 1 34 17767 291 52719 35243 2023-05-16 20:56:30 --> Write multiple registers 80 6 FFFF B33F 26A4 800D 2023-05-16 20:56:30 --> 2 0 end. 2023-05-16 20:56:30 --> 3 NMBS res -> address_rtu 3.fc 16.a 80.q 6 2023-05-16 20:56:30 --> 3 NMBS req <- address_rtu 1.fc 16.a 80.q 6.b 64.regs 3 NMBS req <- address_rtu 1.fc 3. 2023-05-16 20:56:31 --> a 49.q 1 2023-05-16 20:56:31 --> 3 NMBS req <- address_rtu 3.fc 3.a 49.q 1 2023-05-16 20:56:31 --> Read holding registers addr=49 qty=1 end 2023-05-16 20:56:31 --> . 2023-05-16 20:56:31 --> 2023-05-16 20:56:31 --> 3 NMBS res -> address_rtu 3.fc 3.b 2.regs 0 2023-05-16 20:56:31 --> 3 NMBS req <- address_rtu 1.fc 3.a 512.q 184 2023-05-16 20:56:31 --> 2023-05-16 20:56:31 --> 3 NMBS req <- address_rtu 1.fc 16.a 80.q 6.b 12.regs 1 34 17767 291 52719 35243 2023-05-16 20:56:31 --> 3 NMBS req <- a 2023-05-16 20:56:31 --> ddress_rtu 3.fc 16.a 80.q 6.b 12.regs 1 34 17767 291 52719 35243 2023-05-16 20:56:31 --> Write multiple registers 8 2023-05-16 20:56:31 --> 0 6 FFFF B33F 26A4 800D 2 0 end. 2023-05-16 20:56:31 --> 3 NMBS res -> address_rtu 3.fc 16.a 80.q 6 2023-05-16 20:56:32 --> 3 NMBS req <- a 2023-05-16 20:56:32 --> ddress_rtu 1.fc 16.a 80.q 6.b 64.regs 3 NMBS req <- address_rtu 1.fc 3.a 49.q 1 2023-05-16 20:56:32 --> 3 NMBS res <- addr 2023-05-16 20:56:32 --> ess_rtu 1.fc 3.b 2.regs 0 2023-05-16 20:56:32 --> 3 NMBS req <- address_rtu 1.fc 16.a 80.q 6.b 12.regs 1 34 17767 2 2023-05-16 20:56:32 --> 91 52719 35243 2023-05-16 20:56:32 --> 3 NMBS req <- broadcast.fc 80.3 NMBS req <- broadcast.fc 6.a 3072.value 256 2023-05-16 20:56:32 --> 3 2023-05-16 20:56:32 --> NMBS req <- address_rtu 103.fc 1.a 9165.q 61321 2023-05-16 20:56:32 --> 3 NMBS req <- address_rtu 1.fc 16.a 80.q 6.b 12.regs 1 34 17767 291 52719 35243 2023-05-16 20:56:32 --> 3 NMBS req <- address_rtu 3.fc 16.a 80.q 6.b 12.regs 1 34 17767 291 52719 35243 2023-05-16 20:56:32 --> Write multiple 2023-05-16 20:56:33 --> registers 80 6 FFFF B33F 26A4 800D 2 0 end. 2023-05-16 20:56:33 --> 3 NMBS res -> address_rtu 3.fc 16.a 80.q 6 2023-05-16 20:56:33 --> 3 NMBS req <- address_rtu 1.fc 16.a 80.q 6.b 64.regs 2023-05-16 20:56:33 --> 3 NMBS req <- address_rtu 1.fc 3.a 49.q 1 2023-05-16 20:56:33 --> 3 NMBS res <- address_rtu 1.fc 3.b 2.regs 0 2023-05-16 20:56:33 --> 3 NM 2023-05-16 20:56:33 --> BS req <- address_rtu 3.fc 3.a 49.q 1 2023-05-16 20:56:33 --> Read holding registers addr=49 qty=1 end. 2023-05-16 20:56:33 --> 2023-05-16 20:56:33 --> 3 NMBS res 2023-05-16 20:56:33 --> -> address_rtu 3.fc 3.b 2.regs 0 2023-05-16 20:56:33 --> 3 NMBS req <- address_rtu 1.fc 16.a 80.q 6.b 12.regs 1 34 17767 291 2023-05-16 20:56:33 --> 52719 35243 2023-05-16 20:56:33 --> 3 NMBS req <- broadcast.fc 80.3 NMBS req <- broadcast.fc 6.a 3072.value 256 2023-05-16 20:56:33 --> 2023-05-16 20:56:33 --> 3 NMBS req <- address_rtu 103.fc 1.a 9165.q 61321 2023-05-16 20:56:34 --> 3 NMBS req <- address_rtu 1. 2023-05-16 20:56:34 --> fc 3.a 49.q 1 2023-05-16 20:56:34 --> 3 NMBS req <- address_rtu 3.fc 2023-05-16 20:56:34 --> 3.a 49.q 1 2023-05-16 20:56:34 --> Read holding registers addr=49 qty=1 end. 2023-05-16 20:56:34 --> 2023-05-16 20:56:34 --> 3 NMBS res -> address_rtu 3.fc 3.b 2 2023-05-16 20:56:34 --> .regs 0 2023-05-16 20:56:34 --> 3 NMBS req <- address_rtu 1.fc 3.a 512.q 184 2023-05-16 20:56:35 --> 3 NMBS req <- address_rtu 1.fc 16.a 80.q 6.b 12.regs 1 34 17767 291 52 2023-05-16 20:56:35 --> 719 35243 2023-05-16 20:56:35 --> 3 NMBS req <- address_rtu 3.fc 16.a 80.q 6.b 12.regs 1 34 17767 291 52719 35243 2023-05-16 20:56:35 --> Write multiple registers 80 6 FFFF B33F 26A4 800D 2 0 end. 2023-05-16 20:56:35 --> 3 NMBS res -> address_rtu 3.fc 16. 2023-05-16 20:56:35 --> a 80.q 6 2023-05-16 20:56:35 --> 3 NMBS req <- 2023-05-16 20:56:35 --> address_rtu 1.fc 16.a 80.q 6.b 64.regs 3 NMBS req <- address_rtu 1.fc 16.a 80.q 6.b 12.reg 2023-05-16 20:56:35 --> s 1 34 17767 291 52719 35243 2023-05-16 20:56:35 --> 3 NMBS req <- address_rtu 3.fc 16.a 80.q 6.b 12.regs 1 34 17767 2 2023-05-16 20:56:35 --> 91 52719 35243 2023-05-16 20:56:35 --> Write multiple registers 80 6 FFFF B33F 26A4 800D 2 0 end. 2023-05-16 20:56:35 --> 3 NMBS res -> address 2023-05-16 20:56:35 --> _rtu 3.fc 16.a 80.q 6 2023-05-16 20:56:35 --> 3 NMBS req <- address_rtu 1. 2023-05-16 20:56:35 --> fc 16.a 80.q 6.b 64.regs 3 NMBS req <- address_rtu 1.fc 16.a 80.q 6.b 12.regs 1 34 17767 291 52 2023-05-16 20:56:36 --> 719 35243 2023-05-16 20:56:36 --> 3 NMBS req <- address_rtu 3.fc 16.a 80.q 6.b 12.regs 1 34 17767 291 52719 35243 2023-05-16 20:56:36 --> Write 2023-05-16 20:56:36 --> multiple registers 80 6 FFFF B33F 26A4 800D 2 0 end. 2023-05-16 20:56:36 --> 3 NMBS res -> address_rtu 3.fc 16.a 80. 2023-05-16 20:56:36 --> q 6 2023-05-16 20:56:36 --> 3 NMBS req <- address_rtu 1.fc 16.a 80.q 6.b 12.regs 1 34 17767 291 52719 35243 2023-05-16 20:56:36 --> 3 NMBS 2023-05-16 20:56:36 --> req <- address_rtu 3.fc 16.a 80.q 6.b 12.regs 1 34 17767 291 52719 35243 2023-05-16 20:56:36 --> Write multiple registers 2023-05-16 20:56:36 --> 80 6 FFFF B33F 26A4 800D 2 0 end. 2023-05-16 20:56:36 --> 3 NMBS res -> address_rtu 3.fc 16.a 80.q 6 2023-05-16 20:56:36 --> 3 NMBS req 2023-05-16 20:56:36 --> <- address_rtu 1.fc 16.a 80.q 6.b 64.regs 3 NMBS req <- address_rtu 1.fc 3.a 49.q 1 2023-05-16 20:56:36 --> 3 NMBS res 2023-05-16 20:56:36 --> <- address_rtu 1.fc 3.b 2.regs 0 2023-05-16 20:56:36 --> 3 NMBS req <- address_rtu 3.fc 3.a 49.q 1 2023-05-16 20:56:36 --> Read holding registers 2023-05-16 20:56:37 --> addr=49 qty=1 end. 2023-05-16 20:56:37 --> 2023-05-16 20:56:37 --> 3 NMBS res -> address_rtu 3.fc 3.b 2.regs 0 2023-05-16 20:56:37 --> 3 NMBS req <- address_rtu 1.fc 3.a 49.q 1 2023-05-16 20:56:37 --> 3 NMBS res <- address 2023-05-16 20:56:38 --> _rtu 1.fc 3.b 2.regs 0 2023-05-16 20:56:38 --> 3 NMBS req <- address_rtu 3.fc 3.a 49.q 1 2023-05-16 20:56:38 --> Read holding registers addr= 2023-05-16 20:56:38 --> 49 qty=1 end. 2023-05-16 20:56:38 --> 2023-05-16 20:56:38 --> 3 NMBS res -> address_rtu 3.fc 3.b 2.regs 0 2023-05-16 20:56:39 --> 3 NMBS req <- address_rtu 1.fc 3.a 49.q 1 2023-05-16 20:56:39 --> 3 NMBS res <- address



the devices seems to receive the requests normally, that it's a very big difference btw the reason I'm making this issue, but I can't understand why because in my project I don't use Serial2 for other thing that using your library, so I should find the same buffer values while reading id even if I'm not as responsive as this code because it's doing nothing else reading the serial port ^^
kopierreko commented 1 year ago

To confirm the things, I replace your library in this test program by you "master" version, and I have the same troubles than the reason of my issue. So I think you fixed the main problem with your last modification, but for a reason I ignore for the moment, I still have the problem by using you last commit (which works in my current example) in my project.

I will try to find if can't have a conflict in my project which can avoid your fix working, or if you have another idea of flaw in your code... 😊

But for this beginning of answer, thanks a lot for your fix. I will search tomorrow morning if I can find something interesting.

EDIT : I replaced my delays between sendings to different IDs by my customDelay :

void customDelay(const int &waitingTime) {
  const auto _begin {millis()};
  while (millis() < _begin + waitingTime) {
    err = nmbs_server_poll(&nmbs);
    // This will probably never happen, since we don't return < 0 in our platform funcs
    if (err == NMBS_ERROR_TRANSPORT) {
      Serial.println((String)millis()+" Modbus Error transport");
    }
  }
}

So in the most cases of my issues AND with your last modifications AND with re-send in more than 30% of the cases, but it's "OK". I still have troubles when I want to "poll" the modbus to have the maximum getValues rates but it's better. Maybe it suggests that the read_timeout is too small ?

nmbs_set_read_timeout(&nmbs, 50);
nmbs_set_byte_timeout(&nmbs, 10);

It's important to have in mind that my ESP32s have other things to do than making a simple polling on UART, so they can't answer as quick as my example, so it's normal, I think, that I can't have the same accuracy. But when I ask to the client to make requests ASAP to the 2 servers, it still have no answer and error -5

debevv commented 1 year ago

I think this situation is similar to this issue of libmodbus https://github.com/stephane/libmodbus/issues/18. So start by setting the timeouts of the client to a value higher than the one of the servers, like how is described in this commit of the documentation https://github.com/stephane/libmodbus/commit/a11805cbfda23da36aed84bca3c5edc1413d664c

Also I noticed that your are calling nmbs_server_poll() on a client instance, why is that?

kopierreko commented 1 year ago

Hi !

I found the problem, it was more subtle than it seemed. In my project, because I was trying lots of different options, I saw this morning that I didn't reset my write method with Serial.flush(). I fixed the digitalWrite(DE_PIN, *) with a delay to be sure, and it's working with all my frames except one, and I deduced that it was function of the size of the frame, and I was right : the delay is too small for this frame.

After re-using the Serial.flush(), all was good.

_Also I noticed that your are calling nmbs_serverpoll() on a client instance, why is that?

My bad, I accuse a little fatigue but this function has nothing to do there. However, removing it did not affect my result.

To conclude, your modification fixed the entire problem ; I just had to make the short code test to realize that it's working like this and I adjusted the different timeouts in my side to assure that's OK !

I will test with the final cable length and with 5 servers this afternoon but I think your side is OK 😊 If you want me to do some tests, you can say me.

Thanks a lot for you time and your quickness ! 👍 We'll test on a RP2040 ASAP too.

debevv commented 1 year ago

That's great :tada: so I guess I'll wait a couple of days and if no other problems arise I'll close the issue.
Regarding the tests, like I wrote I'm interested in the RTU protocol inside a multi-server environment. So the more servers you can use, the better

debevv commented 1 year ago

Do you have any additional feedback?

debevv commented 1 year ago

Fixed in 0d6a5274f3b7f2ed0764a848212a793950e4d59c