**

QT使用libmodbus库与施耐德PLC通信

**
1.环境配置
2.modbus简介
3.libmodbus简介
4.施耐德PLC地址映射
5.程序源码

1.环境配置
我当前使用的环境为WIN10 + MSVC2013 X64 + QT 5.9.9 +QT Creator 4.11.0
2.modbus简介
modbus作为一种通信协议,支持RS232,RS485以及以太网等设备。请求建立连接的称为主站master,
作出响应的称为从站slave,主站可以单独与一个从站进行通讯,也可以以广播的方式进行通信。
modbus的数据传输支持两种方式:一种是ASCLL方式,一种是RTU方式。
两种方式的主要区别是;前者以ascll码的方式进行传输,调试起来更加直观,但是传输效率低,因为一个ascll码的二进制是8位,相反,后者以16位数据传输,效率要高得多。以传输数据0xA8为例,ascll传输需要将‘A’和’8’分开传输,也即0x41和0x38,而rtu直接传输0xA8即可。
从站地址从0-247,0是广播地址所有从机都可以识别,所以实际上从机的寻址范围是1-247,主从通信时从站地址设为1即可
modbus的功能码

modbus通信数据格式,只介绍用到的几个:


关于CRC(Modbus)校验,这里贴一个链接,做调试用
CRC在线校验
3.libmodbus简介

关于libmodbus的使用网上很多,我也看了许多,有两个写的还是很全的
libmodbus的编译
libmodbus的使用

4.施耐德PLC地址映射

其他PLC的地址映射见这里
5.程序源码
在.pro文件中链接WS2_32.LIB库,以及头文件路径

LIBS  += -L$$PWD/lib/ -lWS2_32
INCLUDEPATH += $$PWD/libmodbus

这是整个工程文件

libmodbus文件夹中有

在.h文件中声明modbus对象

modbus_t *mb;

.c文件构造函数中添加

    mb = modbus_new_rtu("COM5", 38400, 'N', 8, 1);modbus_set_slave(mb, 1); //设置modbus从机地址modbus_set_response_timeout(mb, 0, 1000000);/* 超时时间1s */

析构函数中添加

MainWindow::~MainWindow()
{modbus_close(mb);modbus_free(mb);delete ui;
}

设备连接

    if(modbus_connect(mb) < 0){ui->textEdit->append(QString::fromLocal8Bit("连接失败"));}else {ui->textEdit->append(QString::fromLocal8Bit("连接成功"));}

0x01码 (读QX输出线圈)

void MainWindow::on_pushButton_01_clicked()
{qDebug() << "0x01";uint8_t dest[8] = {0};if(modbus_read_bits(mb, 0, 8, dest) != 8 )/* 读输出端 */{qDebug() << "Read Coils Error";}else{qDebug() << "Read Coils Success";}
}

0x02码 (读取IX离散输入)

void MainWindow::on_pushButton_02_clicked()
{qDebug() << "0x02";uint8_t dest_2[8] = {0};modbus_read_input_bits(mb, 0, 8, dest_2); /* 读输入端 */qDebug() << dest_2[0] << ":" << dest_2[1] << ":" << dest_2[2] << ":" << dest_2[3];qDebug() << dest_2[4] << ":" << dest_2[5] << ":" << dest_2[6] << ":" << dest_2[7];
}

0x03码(读取MW寄存器)

void MainWindow::on_pushButton_03_clicked()
{qDebug() << "0x03";uint16_t reg[5];int rc = modbus_read_registers(mb, 0, 5, reg);for(int i = 0; i < rc; i++) {QString str = QString::fromLocal8Bit("寄存器reg[%1]的值为:%2").arg(i+300).arg(decTobin(QString::number(reg[i])));  /* 读多个保持寄存器 */ui->textEdit->append(str);}}

0x10码 (写MW寄存器)

void MainWindow::on_pushButton_10_clicked()
{/* MW0 40001 *//* MW359  40360*/qDebug() << "0x10";uint16_t tab_regs[5] = {206,0,1,0,0};if(modbus_write_registers(mb, 360, 5, tab_regs) == (-1)) {qDebug() << "write error";}
}

以下是我修改后的使用0X01,0X02,0X03,0X10的例子供大家参考

void MainWindow::on_btnConfirm_clicked()
{byte keyValue = 1 << 5;qDebug() << keyValue;byte mode = ui->comboBoxMode->currentIndex(); /* 0 1 2 3 */qDebug() << mode;int plateNum = ui->lineEditNum->text().toUInt();qDebug() << plateNum;byte cmode = 0;switch (mode) {case 0: cmode = 1 << 0; break;case 1: cmode = 1 << 1; break;case 2: cmode = 1 << 2; break;case 3: cmode = 1 << 3; break;default:cmode = 0;      break;}qDebug() << cmode;uint16_t tab_reg[5] = {plateNum, 0, cmode, keyValue, 0};/* 数组实际为如 101,0,1,32,0 */byte rc = modbus_write_registers(mb, 360, 5, tab_reg); /* 判断写入的数据长度是不是5个,点对点通信时从站是有返回值的 */if(rc == sizeof (tab_reg)/sizeof (tab_reg[0])){qDebug() << "write success";}
}
void MainWindow::on_btnViewPlate_clicked() /* 查看扩展板输入输出状态 */
{uint16_t reg[2];int rc = modbus_read_registers(mb, 0, 2, reg);for(byte i = 0; i < rc; i++){ui->textEdit->append(QString::fromLocal8Bit("扩展板0%1").arg(i+1));ui->textEdit->append("----------------------------");for(byte j = 0; j < 16; j++){QString str = QString("%1 : %2").arg(j+1).arg( (reg[rc] >> j) & 0x0001);/* 获取位状态 */ui->textEdit->append(str);}}}void MainWindow::on_btnViewPlc_clicked()  /* 查看PLC输入输出点状态 */
{uint8_t dest[8] = {0};byte rc = modbus_read_input_bits(mb, 0, 8, dest); /* 读输入端 */for(byte i = 0; i < rc; i++){QString in = QString("IX0.%1 = %2").arg(i).arg(dest[i]);ui->textEdit->append(in);}memset(dest, '\0', sizeof (dest));ui->textEdit->append("---------------------------");rc = modbus_read_bits(mb, 0, 8, dest);for(byte i = 0; i < rc; i++){QString in = QString("QX0.%1 = %2").arg(i).arg(dest[i]);ui->textEdit->append(in);}memset(dest, '\0', sizeof (dest));
}



输入车位号206,点击确认,打开modscan32查看一下PLC内部值是否改变

可以看到已经写入成功

最后,说一下我调试的过程,首先先写好一个测试用的DEMO,我把常用的几个功能码都使用了用按钮触发,就是上面贴的代码,有几个我没贴,然后使用软件VSPD虚拟两个串口出来,再用软件Modbus Slave来模拟从站,就可以对代码进行调试了。如果有硬件,可以使用两个USB转485并联与PLC相连,打开串口调试软件比如我用的XCOM2.0,和你自己写的软件分别连接一个COM口,这样你发送给PLC的数据就可以显示在串口调试软件上了,这里要注意的是,点对点测试的时候,串口调试软件会收到两条数据,一条是你发送给PLC的数据,一条是PLC返回的数据,一开始我以为是我发送的数据格式有误。好了,今天就写到这里,关于工程文件已经上传CSDN了,积分窘迫的同学可以评论或者私信我,分享快乐。

QT使用libmodbus库与施耐德PLC通信相关推荐

  1. Labview通过NIopc与施耐德plc通信

    一.配置opc* 1.安装labview并且安装NIDSC工具包后从工具栏或者开始菜单打开opc工具. 2.单击CLIck to add a channel.进行配置 3.Channel name:名 ...

  2. Qt 使用Visa库与数字仪器仪表TCP/IP通信(SCPI指令自动化测试)

    标准数字仪器仪表可通过 GPIB, RS232, USB, LAN接口等与上位机数据通信和控制.如示波器.数字万用表.频率计.台式电源等.通过SCPI协议(字符串形式)与设备通信,串口,USB等接口可 ...

  3. 基于QT开发的使用OPC_UA与西门子1200,1500系列PLC通信的工业监控Demo

    目录 一,总体介绍 二,需要的软件 三,需要的硬件 四,QT程序代码 五,西门子PLC代码 一,总体介绍 先看一下图1-1的QT运行界面图,界面中服务器地址就是OPC_UA服务器地址,整个项目作用,就 ...

  4. mx三菱plc安装报错_Qt使用 MX Component 插件与三菱PLC通信

    作者:billy 版权声明:著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处 MX Component 简介 MX Component 是三菱PLC官方上位机通讯中间件,通过使用该工 ...

  5. modbus/施耐德PLC协议网关

    物通博联modbus/施耐德PLC协议网关即wtblnet iot Gateway,是一款支持单网口/两网口/五网口,支持4G/3G/WIFI/PPPOE/WAN有线网络,内嵌工业控制协议,支持远程自 ...

  6. ubuntu下libmodbus库的使用

    工作项目中,机器人要完成一个电源管理的功能,自带可充电触点接触充电的电池,具体参数不表,代码要完成通过无线网络与西门子的PLC通信,从而控制充电房的开门与关门,以及控制充电处的继电器的开启与关闭,协议 ...

  7. plc原理及应用_施耐德PLC应用技术

    电工学习网:www.diangon.com 关注电工学习网官方微信公众号"电工电气学习",收获更多经验知识. 本书系统介绍施耐德plc的工作原理和应用技术.主要包括施耐德plc概述 ...

  8. 信捷plc485通信上位机_基于Snap7实现与西门子PLC通信

    如果你对西门子PLC通信或者上位机开发稍微有一点研究的话,应该对Snap7有所耳闻. Snap7是一个基于以太网与西门子S7系列PLC通信的开源库,在世界领域应用很广.但也许是因为资料比较少,而且很多 ...

  9. MODBUS通讯:libmodbus库使用方法

    MODBUS通讯:libmodbus库使用方法 libmodbus是一个快速.跨平台的Modbus库,目前支持Linux, Mac OS X, FreeBSD, QNX和Windows系统.libmo ...

最新文章

  1. webconfig加密
  2. python获取docx文档的内容(文本)
  3. 2015-2016 ACM-ICPC Northeastern European Regional Contest (NEERC 15)
  4. 【Linux】一步一步学Linux——builtin命令(215)
  5. astc贴图格式是什么意思_c4d配合AEe3d导入c4d模型贴图及插件安装所有流程
  6. LoadRunner Interview Questions
  7. html css a标签的应用
  8. 西安市2008驾照理论考试题
  9. 缺失值填充4——使用线性模型(岭回归、Lasso回归、ElasticNet回归)填充序列缺失值
  10. 【CDH】 kafkaServer-gc.log日志太多
  11. 200 行代码,一行行教你自制微信机器人
  12. 【运维安全】-HTTP协议
  13. os.path.join;os.makedirs()
  14. 吴恩达深度学习笔记 第二章作业1
  15. 手动安装.app到模拟器simulator, iOS XCode 11
  16. 基于RS485通信的Modbus通信协议
  17. 服务器拆装服务协议,在windows server 2012下安装SMB协议
  18. 非常全面详细的Sklearn介绍
  19. ES可视化工具--Dejavu--下载、安装、使用
  20. javascript渐变色算法

热门文章

  1. OSPF基础实验配置
  2. JavaScript 注释
  3. 解决jquery版本过低引发的XSS跨站安全漏洞
  4. 【ArcGIS】ArcGIS Editor for OpenStreetMap 各版本稳定下载链接
  5. 用Python生成一个上三角矩阵
  6. IntelliJ IDEA好用的插件:笔记
  7. 知乎-如何进入BAT2
  8. 人人网技术部门完成上市后的重组
  9. MAC 自定义通知提醒 (定时提醒喝水)
  10. 【Linux】软件安装(三分钟教会你如何在linux下安装软件)