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.

This commit is contained in:
andrew_marles
2026-02-21 22:12:03 -08:00
parent e0896a9db0
commit b4e84879c5

View File

@@ -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
}
}