I built and used libmodbus with VS2022 on Win10. According to the coil address provided by the equipment instruction manual, I successfully opened and closed the 12 coils. When I try to read the state of the coil, the "modbus_read_bits" return value is always less than 0, so the read operation is unsuccessful. I have checked the coil address carefully, and there is no problem. I can control the coil on and off, which means the coil address is correct. My code is as follows:
#include <conio.h>
#include <iostream>
#include "libmodbus/modbus.h"
#pragma comment(lib,"modbus.lib")
const char IP_addr[] = "192.168.1.232";
const short port_number = 10000;
modbus_t* MyModbus;
uint8_t read_buffer[1024];
uint8_t write_buffer[1024];
uint16_t read_buffer_16[1024];
uint16_t write_buffer_16[1024];
int main()
{
//Create a connection and initialize MyModbus
MyModbus = modbus_new_tcp(IP_addr, port_number);
// Set the slave phone number
modbus_set_slave(MyModbus, 1);
modbus_set_response_timeout(MyModbus, 0, 1000 * 1000);//0s+1000*1000us=1000ms
//connecte device
int myerror = modbus_connect(MyModbus);
if (myerror < 0)
{
modbus_free(MyModbus);
std::cout << "IP_addr=" << IP_addr << "\t Connection failed! \n Press any key to exit!" << std::endl;
_getch();
return 0;
}
else
std::cout << "IP_addr=" << IP_addr << "\t successfu lconnection" << std::endl;
//Initializes the write buffer with all values set to 0xFF
memset(write_buffer, 0xFF, sizeof(uint8_t) * 12);
write_buffer[4] = 0x00;//close it
write_buffer[6] = 0x00;
write_buffer[8] = 0x00;
modbus_write_bits(MyModbus, 0x00, 12, write_buffer);
std::cout << "Coil 4,6,8 closed, the rest of the coil open \n";
char key = getchar();
//Querying coil status
memset(read_buffer, 0x00, sizeof(uint8_t) * 12);
myerror = modbus_read_bits(MyModbus, 0x00, 12, read_buffer);//here
if (myerror > 0)
for (int i = 0; i < 12; i++)
std::cout << std::hex << (int)read_buffer[i] << ", ";
else
std::cout << "Coil status query failed!" << std::endl;
key = getchar();
modbus_close(MyModbus);
modbus_free(MyModbus);
std::cout << "\n Disconnect the device!\n";
return 0;
}
Output:
Fortunately, the software provided by the equipment manufacturer can see the state of the coil, so I can run the program and know whether the coil is open or not. The DO button shows red, indicating that the coil is open; Black indicates that the coil is closed.
I tried to read the value of the device hold register, but failed. The device manufacturer provided instructions for the device instructions, but only the modbus instructions under the serial port connection mode were told. The reference contribution under TCP connection is not very large. And the equipment manufacturer can not be contacted.
Finally, I just want to know, is there a problem with me using this function? Are there any other special cases for reading the state of the coil? Thanks!