Кто работал с библиотекой 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;
В данной программе подключение к данному порту и и к ведомому происходит корректно. Ошибки возникают на функциях отправки пакета и считывания регистров.С чем это может быть связанно?
Решение данной проблемы может быть не очевидно и решена она была методом тыка во все функции. Надеюсь что кому то когда то это поможет. Решение следующее , нужно было всего лишь установить время 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);
}
Айфон мало держит заряд, разбираемся с проблемой вместе с AppLab
Перевод документов на английский язык: Важность и ключевые аспекты
Я хочу хочу понять какие параметры нужны в c++ в функции push_heap()Если можете объясните всё простым языком
Имею 2 функции (различий меж ними нет, практически) Правильно ли я выполняю из них возврат? И как правильно их нужно вызывать в main (между массивами,...
Как копировать одну строку в другуюНапример, строка text1[6]="fsdfaf" копируется в text2[6]={0}
Есть база данных в которой хранятся все сообщения, сервер их подгружает, но возникла проблема в визуализации этих же сообщенийТо есть нужен...