Сторона Windows, libmodbus + Qt PC test

Сторона Windows, libmodbus + Qt PC test

Эта статья основана на реализации связи по протоколу Modbus в VS, и в Qt были внесены некоторые простые модификации для реализации связи по протоколу Modbus в Qt. (Это можно рассматривать как кривую спасения страны)

Ясное мышление

Долгое время я был немного запутан в связи между Modbus-Master (ведущая сторона) и Modbus-Slave (ведомая сторона) относительно того, какой конец назначен регистру.
основная причина:

  • 1. Это потому, что я не совсем понимаю концепцию коммуникации: и хост, и подчиненная сторона могут передавать данные, и обе могут присваивать значения регистрам;
  • 2. Ссылаясь на информацию в Интернете, большинство соединений между Master и Slave устанавливаются на стороне Qt, а назначение выполняется с помощью инструмента Modbus Slave, что вызывает недопонимание.

Примечания к исследованию встроенного STM32 (8) -libmodbus + Qt host computer test
Функция, показанная в тексте, заключается в присвоении значений регистрам в инструменте Modbus Slave.После успешного подключения вы можете увидеть передачу значения в командном окне.
Но в моей реальной ситуации Qt, как хост-компьютер, должен передавать значения на конец Slave для достижения эффекта отправки инструкций. Поэтому мне нужно внести некоторые изменения в код, чтобы он работал на меня.

Идея проверки

Перед написанием кода необходимо проверить идею, чтобы увидеть, насколько она разумна, сначала воспользуйтесь вспомогательными инструментами Modbus.

Тест вспомогательного инструмента Modbus

Воспользуйтесь вспомогательными инструментами для установления соединений Modbus Poll и Modbus Slave, а затем используйте Modbus Poll для передачи данных в Modbus Slave, а затем используйте Modbus Slave для передачи данных в Modbus Poll.
1. Передайте значения 0–9 из опроса Modbus в ведомое устройство Modbus, как показано на рисунке 1 ниже.
фигура 1

Tx означает отправку, Rx означает получение.
Modbus Poll сначала отправляет 03 00 00 00 0A C5 CD
Modbus Slave получает эту строку кодов,
Modbus Slave отправляет
03 14 00 00 00 01 00 02 00 03 00 04 00 05 00 06 00 07 00 08 00 09 CD 51
Modbus Получено в опросе

Я немного запутался в этом процессе, почему?
В этом вспомогательном программном обеспечении есть ошибка. Оно напрямую отправляет значение Modbus Slave во время процесса назначения опроса Modbus. Этот тест не объяснил проблему.
2. Передайте значение 10-1 от ведомого конца Modbus к концу опроса Modbus, как показано на Рисунке 2 ниже.
фигура 2

Точно так же Tx означает отправку, а Rx означает получение.
Modbus Poll сначала отправляет 03 00 00 00 0A C5 CD
Modbus Slave получает 03 00 00 00 0A C5 CD
Modbus Slave отправляет
03 14 00 0A 00 09 00 08 00 07 00 06 00 05 00 04 00 03 00 02 00 01 Получен
конец опроса AD B5 Modbus

Главный компьютер Qt как Modbus-Master

Qt компьютера верхнего уровня используется как Modbus-Master (сторона хоста), а на стороне хоста регистр назначается с использованием метода случайной выборки.
Сначала вставьте код:
1.mywidget.h

#ifndef MYWIDGET_H
#define MYWIDGET_H

#include <QWidget>
#include <libmodbus/modbus.h>

#define ADDRESS_START 0
#define ADDRESS_END 9
#define LOOP  1

QT_BEGIN_NAMESPACE
namespace Ui {
    
     class myWidget; }
QT_END_NAMESPACE

class myWidget : public QWidget
{
    
    
    Q_OBJECT

public:
    myWidget(QWidget *parent = nullptr);
    ~myWidget();

private slots:
    void on_pushButton_clicked();

private:
    Ui::myWidget *ui;
    modbus_t *ctx;
    uint16_t *tab_reg;
    uint16_t *send_tab_reg;
    int nb;
    int addr;
    modbus_mapping_t *mb_mapping;
    int nb_fail;
    int nb_loop;
};
#endif // MYWIDGET_H

2.mywidget.cpp

#include "mywidget.h"
#include "ui_mywidget.h"

#include "libmodbus/modbus.h"
#include "QThread"
#include <QtDebug>
#include <errno.h>
#include <stdlib.h>
#include <malloc.h>


myWidget::myWidget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::myWidget)
{
    
    
    ui->setupUi(this);
}

myWidget::~myWidget()
{
    
    
    delete ui;
}


void myWidget::on_pushButton_clicked()
{
    
    
    int rc;
    int i;

    ctx = modbus_new_rtu("COM3", 115200, 'N', 8, 1);
    modbus_set_slave(ctx,1);

    modbus_set_debug(ctx,TRUE);

    if (modbus_connect(ctx)==-1)
        {
    
    
            fprintf(stderr, "Connection failed: %s\n",modbus_strerror(errno));
            modbus_free(ctx);
        }


        /*
        uint32_t old_response_to_sec;//秒
        uint32_t old_response_to_usec;//微秒,1秒=1,000,000微秒

        modbus_get_response_timeout(ctx, &old_response_to_sec, &old_response_to_usec);//获取当前设置的超时

        modbus_set_response_timeout(ctx,0,50000);//设定超时,默认50ms(50,000us)
        qDebug()<<"get timeout sec:"<<old_response_to_sec;
        qDebug()<<"get timeout usec:"<<old_response_to_usec;



        printf("\n----------------\n");*/
        nb=ADDRESS_END-ADDRESS_START;

        tab_reg=(uint16_t *)malloc(nb * sizeof(uint16_t));
        memset(tab_reg,0,nb * sizeof(uint16_t));

        /*写入保持寄存器数值*/
        nb_loop=nb_fail=0;
        while(nb_loop++<LOOP)
        {
    
    
            for(addr=ADDRESS_START;addr<ADDRESS_END;addr++)
            {
    
    
                int i;
                for(i=0;i<nb;i++)
                {
    
    
                    tab_reg[i]=(uint16_t)(65535*rand()/(RAND_MAX+1.0));
                }
                nb=ADDRESS_END-addr;

                rc=modbus_write_register(ctx,addr,tab_reg[0]);
                if(rc !=1)
                {
    
    
                    printf("ERROR modbus_write_register(%d)\n",rc);
                    nb_fail++;
                }
                else
                {
    
    
                    rc = modbus_read_registers(ctx,addr,1, tab_reg); //03#读取保持寄存器的值,(对象,起始地址,读取数量,存储读取到的值)
                    if (rc != 1)
                    {
    
    
                        fprintf(stderr,"%s\n", modbus_strerror(errno));
                        qDebug()<<"rc错误"<<modbus_strerror(errno);
                        nb_fail++;
                    }
                    else
                    {
    
    
                        qDebug()<<"链接成功";
                        for (i=0; i<10; i++)
                        {
    
    
                            printf("reg[%d] = %d(0x%x)\n", i, tab_reg[i], tab_reg[i]);
                            qDebug()<<"rc收到:"<<tab_reg[i];
                        }
                     }

                 }

               }
        }
        modbus_close(ctx);  //关闭modbus连接
        modbus_free(ctx);   //释放modbus资源,使用完libmodbus需要释放掉
}




Эффект после выполнения показан на рисунке ниже:
изображение 3
вы можете видеть, что значение, присвоенное регистру, было передано в Modbus Slave, что указывает на то, что этот код действителен на стороне Modbus Master.
Кроме того, при проведении этого теста я надеюсь использовать ссылки на мои последние две статьи, включая редактирование библиотеки libmodbus и моделирование связи Modbus.
Ссылка 1: Меры предосторожности при использовании libmodbus в Qt 5 в Windows
Ссылка 2: Моделирование связи в режиме Modbus RTU на основе библиотеки libmodbus в Visual Studio
Ссылка 3: Обучающие заметки по встроенному STM32 (8) -libmodbus + Qt PC test

рекомендация

отblog.csdn.net/qq_43552324/article/details/108714390