From b4e84879c55c004876b319b5b576e92890254c76 Mon Sep 17 00:00:00 2001 From: andrew_marles Date: Sat, 21 Feb 2026 22:12:03 -0800 Subject: [PATCH] I think I may have found some small issues when working with single coils and the packed bytes that they use. This seems to work against a nanoModbus server in my basic testing. --- modbus.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/modbus.c b/modbus.c index b1e9e3b..49de418 100644 --- a/modbus.c +++ b/modbus.c @@ -221,6 +221,12 @@ FLASHMEM static void rx_packet (modbus_message_t *msg) case ModBus_Diagnostics: response.num_values = 0; // TBA break; + case ModBus_ReadCoils: + case ModBus_ReadDiscreteInputs: + response.num_values = min(msg->adu[2], 3); // byte count, not /2 + for(idx = 0; idx < response.num_values; idx++) + response.values[idx] = msg->adu[3 + idx]; // single bytes, not u16 + break; default:; response.num_values = cmds[response.function].single_register || cmds[response.function].is_write ? 2 : msg->adu[2] / 2; @@ -295,7 +301,11 @@ FLASHMEM status_code_t modbus_message (uint8_t server, modbus_function_t functio } else { // read cmd.adu[4] = (uint8_t)(registers >> 8); cmd.adu[5] = (uint8_t)(registers & 0xFF); - cmd.rx_length = 5 + (registers << 1); + + if(function == ModBus_ReadCoils || function == ModBus_ReadDiscreteInputs) + cmd.rx_length = 5 + ((registers + 7) / 8); // bit-packed, ceil(n/8) bytes + else + cmd.rx_length = 5 + (registers << 1); // 2 bytes per register } }