The"modbus_read_bits"function fails to read the state of the coil. Am I using this function wrong?

59 Views Asked by At

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:

enter image description here

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.

enter image description here

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!

0

There are 0 best solutions below