如何通过Modbus TCP读取WAGO 753-483模拟输入模块的数据?
Let's break down the issues with your current setup and fix them step by step:
1. Fix the Read_AI Request Frame
Your current Read_AI array has a critical mistake in the register count field (last two bytes set to 0,0), which tells the controller to read 0 registers—so you're getting no valid data back. Here's the corrected array:
byte Read_AI[12] = {0, 0, 0, 0, 0, 6, 1, 4, 0, 29, 0, 1};
Let's break down each part of the Modbus TCP frame to clarify why this works:
- Bytes 0-1: Transaction ID (can stay fixed or increment per request to match responses, either works for single-request workflows)
- Bytes 2-3: Protocol ID (fixed
0,0for Modbus TCP) - Bytes 4-5: Length of the following PDU (6 bytes total: Unit ID + Function Code + Start Address + Register Count)
- Byte 6: Unit ID (WAGO controller's station address,
1is correct here as per your setup) - Byte 7: Function Code (
4= Read Input Registers—this is the right choice for AI modules; FC2 is for discrete switches, FC3 is for writable holding registers, neither applies here) - Bytes 8-9: Start register address (
0,29= decimal 29, which matches your documentation) - Bytes 10-11: Register count (
0,1= read 1 register, since your voltage data lives in a single 16-bit input register)
2. Process the Response Data
After sending the corrected Read_AI frame, you'll get a response from the WAGO controller. Here's how to parse it to get your voltage value:
Response Frame Structure
A successful response will follow this format:
- Bytes 0-3: Match your request's Transaction/Protocol IDs
- Bytes 4-5: Length of the following data (should be
0,5for this request) - Byte 6: Unit ID (matches your request)
- Byte 7: Function Code (
4= no error; if it's0x84, an exception occurred—check byte 8 for the error code) - Byte 8: Number of data bytes (
2for 1 register) - Bytes 9-10: The 16-bit register value (stored big-endian: high byte first)
Parse the Voltage Value
Per your documentation, the data uses an 11-bit resolution (the two bytes correspond to the high/low parts of this 11-bit value). Assuming the 11 bits are the lower 11 bits of the 16-bit register (common for WAGO modules), here's how to calculate the actual voltage:
// Assume you've received the response into a byte array called 'response' if (response[7] == 0x04) { // Check for successful read (FC4) if (response[8] == 2) { // Confirm we got 2 bytes of register data byte high_byte = response[9]; byte low_byte = response[10]; uint16_t raw_value = (high_byte << 8) | low_byte; // Extract the 11-bit effective value (mask with 0x7FF = 11 binary 1s) uint16_t effective_value = raw_value & 0x7FF; // Convert to voltage (0-10V range, 11-bit max value = 2047) double voltage = (effective_value / 2047.0) * 10.0; // Detect your target state (0V vs ~10V) if (voltage < 0.5) { // Adjust threshold to match your needs write("Voltage is near 0V"); } else if (voltage > 9.5) { write("Voltage is near 10V"); } } } else { // Handle error cases write("Modbus read error - Exception code: " + String(response[8])); }
3. Quick Validation Checks
- Confirm your WAGO controller's Unit ID is indeed
1(check the controller's web config if you're unsure) - Double-check the register address: some docs use 1-based numbering, but Modbus uses 0-based—your request uses decimal 29 which matches the doc's "input register 29", so this is correct
- Ensure your TCP socket connection stays stable (you mentioned writes work, so this is likely not an issue)
内容的提问来源于stack exchange,提问作者Markus

