Adam-6350 DI/DO Testing using libmodbus

I tested my ADAM-6350 module with QModMaster, and all read/write operations worked correctly. However, using a C program with libmodbus, writing to a coil with modbus_write_bit works, but modbus_read_bits always returns 0, regardless of the value written. Could this issue be related to incorrect coil/register addresses, initialization requirements, or differences in how QModMaster handles Modbus TCP compared to libmodbus? What steps can I take to verify the correct Modbus configuration or address mappings for the ADAM-6350 when using a custom program? Are there any specific settings I need to adjust in libmodbus?
#include <modbus.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>

#define SERVER_IP "192.168.1.250"
#define SERVER_PORT 502
const uint16_t COIL_ADDRESS = 0x0033; // Address for a single coil

int main() {
int rc;
modbus_t *ctx;
uint8_t coil_value;

// Create Modbus context
ctx = modbus_new_tcp(SERVER_IP, SERVER_PORT);
if (ctx == NULL) {
fprintf(stderr, "Unable to create Modbus context: %s\n", modbus_strerror(errno));
return -1;
}

// Connect to Modbus server
if (modbus_connect(ctx) == -1) {
fprintf(stderr, "Unable to connect to Modbus server: %s\n", modbus_strerror(errno));
modbus_free(ctx);
return -1;
}

printf("Connected to Modbus server %s:%d\n", SERVER_IP, SERVER_PORT);

// Write to a single coil
printf("Writing to coil at address 0x%04X...\n", COIL_ADDRESS);
rc = modbus_write_bit(ctx, COIL_ADDRESS, 1); // Turn the coil ON
if (rc == -1) {
fprintf(stderr, "Error writing to coil: %s\n", modbus_strerror(errno));
modbus_close(ctx);
modbus_free(ctx);
return -1;
}
printf("Successfully wrote to coil at address 0x%04X.\n", COIL_ADDRESS);

// Read the single coil
printf("Reading coil at address 0x%04X...\n", COIL_ADDRESS);
rc = modbus_read_bits(ctx, COIL_ADDRESS, 1, &coil_value);
if (rc == -1) {
fprintf(stderr, "Error reading coil: %s\n", modbus_strerror(errno));
modbus_close(ctx);
modbus_free(ctx);
return -1;
}
printf("Read coil value at address 0x%04X: %d\n", COIL_ADDRESS, coil_value);

// Close the connection
modbus_close(ctx);
modbus_free(ctx);

return 0;
}
 
Hi,
actually the 0x in 0x0033 address means COIL type, not hexadecimal number.
You need to change the code:
const uint16_t COIL_ADDRESS = 32; // Address for a single coil
The "on-the-wire" address that's actually encoded into the packet is 0-based, so I subtract 1.
It should work.
 
Top