libmodbus передача пакета по RTU rs-485

214
12 июня 2018, 09:20

Кто работал с библиотекой libmodbus подскажите пожалуйста. Хочу в устройство принимающая данный по протоколу MODBUS отправить сам пакет.

Приведу кусок кода со структурой самого пакета:

struct input_t
{
union
{
    uint16_t raw[9];
    struct {
        uint16_t mode;
        float position;
        float time;
        float ampl;
        float velocity;
    } __attribute__((packed));
};
static constexpr int addr = 1;
static constexpr int count = sizeof(raw) / 2;
};

В основной части приложения мне достаточно просто отправить этот пакет по COM PORT по RTU:

modbus_t* ctx;
input_t ifield;
output_t ofield;
std::cout << "Sizeof input : " << sizeof(input_t) << std::endl;
std::cout << "Sizeof output: " << sizeof(output_t) << std::endl;
//ctx = modbus_new_tcp("192.168.0.3", 502);
ctx = modbus_new_rtu("COM4", 115200, 'N', 8, 1);
if( ctx == NULL ) {
    std::cout << "Unable to create the libmodbus context";
    return -1;
}
modbus_set_slave(ctx, 1);
modbus_set_debug(ctx, FALSE);
std::cout << "Connect: " << modbus_connect(ctx) << std::endl;
uint16_t tab_reg[64];
if (ctx ==NULL)
    printf("%s\n","check null not ok" );
int a = modbus_read_registers(ctx, input_t::addr, input_t::count, ofield.raw);
std::cout << a << std::endl;
std::cout << *ofield.raw << std::endl;
ifield.mode = 3;
ifield.position = -9;
ifield.time = 6;
int b = modbus_write_registers(ctx, output_t::addr, output_t::count, ofield.raw);
std::cout << a << std::endl;
modbus_close(ctx);
modbus_free(ctx);
return 0;

В данной программе подключение к данному порту и и к ведомому происходит корректно. Ошибки возникают на функциях отправки пакета и считывания регистров.С чем это может быть связанно?

Answer 1

Решение данной проблемы может быть не очевидно и решена она была методом тыка во все функции. Надеюсь что кому то когда то это поможет. Решение следующее , нужно было всего лишь установить время timeout. Хотя в документации к использованию данной библиотеки - libmodbus, сказано что данные переменные устанавливаются по дефолту. Ниже приведу код работающей программы про протоколу RTU, для операционной системы windows, для nix-подобных систем нужно будет только поменять порт с COMX на /dev/ttyUSBX.

Структура пакета:

struct massage
{
union
{
    uint16_t raw[9];
    struct {
        uint16_t mode;
        float position;
        float time;
        float ampl;
        float velocity;
    } __attribute__((packed));
};
 static constexpr int addr = 256 ;
 static constexpr int count = sizeof(raw) / 2;
};

Основная функция для приема и передачи данный по RTU:

ctx = modbus_new_rtu("COM4", 19200, 'N', 8, 1);
if (NULL == ctx)
{
                printf("Unable to create libmodbus context\n");
                res = 1;
}
else
{
    printf("created libmodbus context\n");
    modbus_set_debug(ctx, TRUE);
    modbus_set_error_recovery(ctx,MODBUS_ERROR_RECOVERY_PROTOCOL);
    rc = modbus_set_slave(ctx, 1);
    modbus_get_response_timeout(ctx, &tv_sec, &tv_usec); 
    tv_sec = 60;
    tv_usec = 0;
    modbus_set_response_timeout(ctx, tv_sec,tv_usec); 
    modbus_get_response_timeout(ctx, &tv_sec, &tv_usec); 

    rc = modbus_connect(ctx);
    printf("modbus_connect: %d \n",rc);
    if (rc == -1) {
        printf("Connection failed: %s\n", modbus_strerror(errno));
        res = 1;
    }
    rc = modbus_read_registers(ctx, massage::addr, massage::count, out.raw);
    rc = modbus_write_registers(ctx, massage::addr, massage::count, out.raw);

    modbus_close(ctx);
    modbus_free(ctx);
}
READ ALSO
Параметры функций

Параметры функций

Я хочу хочу понять какие параметры нужны в c++ в функции push_heap()Если можете объясните всё простым языком

154
Возврат из функции и её вызов в С++

Возврат из функции и её вызов в С++

Имею 2 функции (различий меж ними нет, практически) Правильно ли я выполняю из них возврат? И как правильно их нужно вызывать в main (между массивами,...

182
Ассемблер. Ассемблерные вставки. Строки

Ассемблер. Ассемблерные вставки. Строки

Как копировать одну строку в другуюНапример, строка text1[6]="fsdfaf" копируется в text2[6]={0}

187
Как сделать отображение чата на Qt

Как сделать отображение чата на Qt

Есть база данных в которой хранятся все сообщения, сервер их подгружает, но возникла проблема в визуализации этих же сообщенийТо есть нужен...

165