Modbus TCP&modbus rtu协议库 上位机开发/修复04功能码

axuanup 2024-2-5 2890

Code AardioLine:218复制
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.
  • 33.
  • 34.
  • 35.
  • 36.
  • 37.
  • 38.
  • 39.
  • 40.
  • 41.
  • 42.
  • 43.
  • 44.
  • 45.
  • 46.
  • 47.
  • 48.
  • 49.
  • 50.
  • 51.
  • 52.
  • 53.
  • 54.
  • 55.
  • 56.
  • 57.
  • 58.
  • 59.
  • 60.
  • 61.
  • 62.
  • 63.
  • 64.
  • 65.
  • 66.
  • 67.
  • 68.
  • 69.
  • 70.
  • 71.
  • 72.
  • 73.
  • 74.
  • 75.
  • 76.
  • 77.
  • 78.
  • 79.
  • 80.
  • 81.
  • 82.
  • 83.
  • 84.
  • 85.
  • 86.
  • 87.
  • 88.
  • 89.
  • 90.
  • 91.
  • 92.
  • 93.
  • 94.
  • 95.
  • 96.
  • 97.
  • 98.
  • 99.
  • 100.
  • 101.
  • 102.
  • 103.
  • 104.
  • 105.
  • 106.
  • 107.
  • 108.
  • 109.
  • 110.
  • 111.
  • 112.
  • 113.
  • 114.
  • 115.
  • 116.
  • 117.
  • 118.
  • 119.
  • 120.
  • 121.
  • 122.
  • 123.
  • 124.
  • 125.
  • 126.
  • 127.
  • 128.
  • 129.
  • 130.
  • 131.
  • 132.
  • 133.
  • 134.
  • 135.
  • 136.
  • 137.
  • 138.
  • 139.
  • 140.
  • 141.
  • 142.
  • 143.
  • 144.
  • 145.
  • 146.
  • 147.
  • 148.
  • 149.
  • 150.
  • 151.
  • 152.
  • 153.
  • 154.
  • 155.
  • 156.
  • 157.
  • 158.
  • 159.
  • 160.
  • 161.
  • 162.
  • 163.
  • 164.
  • 165.
  • 166.
  • 167.
  • 168.
  • 169.
  • 170.
  • 171.
  • 172.
  • 173.
  • 174.
  • 175.
  • 176.
  • 177.
  • 178.
  • 179.
  • 180.
  • 181.
  • 182.
  • 183.
  • 184.
  • 185.
  • 186.
  • 187.
  • 188.
  • 189.
  • 190.
  • 191.
  • 192.
  • 193.
  • 194.
  • 195.
  • 196.
  • 197.
  • 198.
  • 199.
  • 200.
  • 201.
  • 202.
  • 203.
  • 204.
  • 205.
  • 206.
  • 207.
  • 208.
  • 209.
  • 210.
  • 211.
  • 212.
  • 213.
  • 214.
  • 215.
  • 216.
  • 217.
  • 218.
    • import win.ui;
    • import sys.comPort;
    • import modbus.modbustcp;
    • import wsock.tcp.client;
    • /*DSG{{*/
    • mainForm = win.form(text="zmodbus";right=663;bottom=623)
    • mainForm.add(
    • button={cls="button";text="01功能码";left=8;top=568;right=96;bottom=600;db=1;dl=1;z=68};
    • button2={cls="button";text="02功能码";left=128;top=568;right=216;bottom=600;db=1;dl=1;z=69};
    • button3={cls="button";text="03功能码";left=248;top=568;right=336;bottom=600;db=1;dl=1;z=70};
    • button4={cls="button";text="04功能码";left=360;top=568;right=448;bottom=600;db=1;dl=1;z=71};
    • ["button_COM_断开"]={cls="button";text="断开连接";left=456;top=208;right=544;bottom=240;dr=1;dt=1;z=67};
    • ["button_COM_连接"]={cls="button";text="连接从机";left=352;top=208;right=440;bottom=240;dr=1;dt=1;z=66};
    • ["button_TCP_断开"]={cls="button";text="断开连接";left=152;top=208;right=240;bottom=240;dl=1;dt=1;z=65};
    • ["button_TCP_连接"]={cls="button";text="连接从机";left=48;top=208;right=136;bottom=240;dl=1;dt=1;z=64};
    • ["button_写单个寄存器"]={cls="button";text="写单个寄存器";left=384;top=488;right=472;bottom=520;db=1;dr=1;z=52};
    • ["button_写单个线圈"]={cls="button";text="写单个线圈";left=64;top=488;right=152;bottom=520;db=1;dl=1;z=34};
    • ["button_写多个寄存器"]={cls="button";text="写多个寄存器";left=544;top=488;right=632;bottom=520;db=1;dr=1;z=59};
    • ["button_写多个线圈"]={cls="button";text="写多个线圈";left=224;top=488;right=312;bottom=520;db=1;dl=1;z=41};
    • ["button_读单个寄存器"]={cls="button";text="读单个寄存器";left=384;top=448;right=472;bottom=480;db=1;dr=1;z=51};
    • ["button_读单个线圈"]={cls="button";text="读单个线圈";left=64;top=448;right=152;bottom=480;db=1;dl=1;z=33};
    • ["button_读多个寄存器"]={cls="button";text="读多个寄存器";left=544;top=448;right=632;bottom=480;db=1;dr=1;z=58};
    • ["button_读多个线圈"]={cls="button";text="读多个线圈";left=224;top=448;right=312;bottom=480;db=1;dl=1;z=40};
    • ["combobox_串口号"]={cls="combobox";left=352;top=96;right=432;bottom=120;dr=1;dt=1;edge=1;items={};mode="dropdown";z=18};
    • ["combobox_停止位"]={cls="combobox";left=352;top=168;right=432;bottom=192;dr=1;dt=1;edge=1;items={};mode="dropdown";z=27};
    • ["combobox_数据位"]={cls="combobox";left=352;top=136;right=432;bottom=160;dr=1;dt=1;edge=1;items={};mode="dropdown";z=26};
    • ["combobox_校验位"]={cls="combobox";left=488;top=136;right=568;bottom=160;dr=1;dt=1;edge=1;items={};mode="dropdown";z=23};
    • ["combobox_波特率"]={cls="combobox";left=488;top=96;right=568;bottom=120;dr=1;dt=1;edge=1;items={};mode="dropdown";z=19};
    • edit_COM_id={cls="edit";text="1";left=352;top=64;right=432;bottom=88;dr=1;dt=1;edge=1;num=1;z=14};
    • edit_COM_timer={cls="edit";text="200";left=488;top=168;right=568;bottom=192;dr=1;dt=1;edge=1;num=1;z=25};
    • edit_TCP_id={cls="edit";text="1";left=72;top=56;right=216;bottom=80;dl=1;dt=1;edge=1;num=1;z=6};
    • edit_TCP_ip={cls="edit";text="192.168.1.143";left=72;top=96;right=216;bottom=120;dl=1;dt=1;edge=1;z=7};
    • edit_TCP_port={cls="edit";text="502";left=72;top=136;right=216;bottom=160;dl=1;dt=1;edge=1;num=1;z=8};
    • edit_TCP_timer={cls="edit";text="200";left=72;top=168;right=216;bottom=192;dl=1;dt=1;edge=1;num=1;z=9};
    • ["edit_单个线圈值"]={cls="edit";text="0";left=88;top=344;right=152;bottom=368;db=1;dl=1;edge=1;num=1;z=32};
    • ["edit_单个线圈地址"]={cls="edit";text="0";left=88;top=312;right=152;bottom=336;db=1;dl=1;edge=1;num=1;z=31};
    • ["edit_单寄存器值"]={cls="edit";text="0";left=408;top=344;right=472;bottom=368;db=1;dr=1;edge=1;num=1;z=50};
    • ["edit_单寄存器地址"]={cls="edit";text="0";left=408;top=312;right=472;bottom=336;db=1;dr=1;edge=1;num=1;z=49};
    • ["edit_多寄存器地址"]={cls="edit";text="0";left=576;top=312;right=632;bottom=336;db=1;dr=1;edge=1;num=1;z=56};
    • ["edit_多寄存器地址个数"]={cls="edit";text="2";left=576;top=344;right=632;bottom=368;db=1;dr=1;edge=1;num=1;z=57};
    • ["edit_多寄存器地址值1"]={cls="edit";text="0";left=576;top=376;right=632;bottom=400;db=1;dr=1;edge=1;num=1;z=62};
    • ["edit_多寄存器地址值2"]={cls="edit";text="0";left=576;top=408;right=632;bottom=432;db=1;dr=1;edge=1;num=1;z=63};
    • ["edit_多线圈值1"]={cls="edit";text="0";left=248;top=376;right=312;bottom=400;db=1;dl=1;edge=1;num=1;z=44};
    • ["edit_多线圈值2"]={cls="edit";text="0";left=248;top=408;right=312;bottom=432;db=1;dl=1;edge=1;num=1;z=45};
    • ["edit_多线圈地址"]={cls="edit";text="0";left=248;top=312;right=312;bottom=336;db=1;dl=1;edge=1;num=1;z=38};
    • ["edit_多线圈数量"]={cls="edit";text="2";left=248;top=344;right=312;bottom=368;db=1;dl=1;edge=1;num=1;z=39};
    • groupbox={cls="groupbox";text="以太网主机";left=8;top=16;right=256;bottom=248;dl=1;dt=1;edge=1;z=1};
    • groupbox2={cls="groupbox";text="串口主机";left=272;top=16;right=640;bottom=248;dl=1;dr=1;dt=1;edge=1;z=10};
    • groupbox3={cls="groupbox";text="单个线圈操作";left=8;top=272;right=160;bottom=528;db=1;dl=1;edge=1;z=28};
    • groupbox5={cls="groupbox";text="多个线圈操作";left=168;top=272;right=320;bottom=528;db=1;dl=1;edge=1;z=35};
    • groupbox6={cls="groupbox";text="单个寄存器操作";left=328;top=272;right=480;bottom=528;db=1;dr=1;edge=1;z=46};
    • groupbox7={cls="groupbox";text="多个寄存器操作";left=488;top=272;right=640;bottom=528;db=1;dr=1;edge=1;z=53};
    • radiobutton_ASCII={cls="radiobutton";text="ASCII";left=576;top=64;right=632;bottom=88;dr=1;dt=1;z=16};
    • radiobutton_RTU={cls="radiobutton";text="RTU";left=512;top=64;right=568;bottom=88;dr=1;dt=1;z=15};
    • static={cls="static";text="ID";left=32;top=56;right=56;bottom=80;center=1;dl=1;dt=1;transparent=1;z=2};
    • static10={cls="static";text="工作方式";left=440;top=64;right=496;bottom=88;center=1;dr=1;dt=1;transparent=1;z=20};
    • static11={cls="static";text="波特率";left=440;top=96;right=480;bottom=120;center=1;dr=1;dt=1;transparent=1;z=21};
    • static12={cls="static";text="校验位";left=440;top=136;right=480;bottom=160;center=1;dr=1;dt=1;transparent=1;z=22};
    • static13={cls="static";text="超时";left=440;top=168;right=480;bottom=192;center=1;dr=1;dt=1;transparent=1;z=24};
    • static14={cls="static";text="线圈地址";left=16;top=312;right=72;bottom=336;center=1;db=1;dl=1;transparent=1;z=29};
    • static15={cls="static";text="线圈值";left=16;top=344;right=64;bottom=368;center=1;db=1;dl=1;transparent=1;z=30};
    • static18={cls="static";text="线圈地址";left=176;top=312;right=232;bottom=336;center=1;db=1;dl=1;transparent=1;z=36};
    • static19={cls="static";text="线圈个数";left=176;top=344;right=232;bottom=368;center=1;db=1;dl=1;transparent=1;z=37};
    • static2={cls="static";text="IP";left=32;top=96;right=56;bottom=120;center=1;dl=1;dt=1;transparent=1;z=3};
    • static20={cls="static";text="线圈(1)值";left=176;top=376;right=232;bottom=400;center=1;db=1;dl=1;transparent=1;z=42};
    • static21={cls="static";text="线圈(2)值";left=176;top=408;right=232;bottom=432;center=1;db=1;dl=1;transparent=1;z=43};
    • static22={cls="static";text="寄存器地址";left=336;top=312;right=400;bottom=336;center=1;db=1;dr=1;transparent=1;z=47};
    • static23={cls="static";text="寄存器值";left=336;top=344;right=400;bottom=368;center=1;db=1;dr=1;transparent=1;z=48};
    • static26={cls="static";text="寄存器地址";left=496;top=312;right=568;bottom=336;center=1;db=1;dr=1;transparent=1;z=54};
    • static27={cls="static";text="寄存器个数";left=496;top=344;right=568;bottom=368;center=1;db=1;dr=1;transparent=1;z=55};
    • static28={cls="static";text="寄存器(1)值";left=496;top=376;right=568;bottom=400;center=1;db=1;dr=1;transparent=1;z=60};
    • static29={cls="static";text="寄存器(2)值";left=496;top=408;right=568;bottom=432;center=1;db=1;dr=1;transparent=1;z=61};
    • static3={cls="static";text="端口号";left=32;top=136;right=56;bottom=160;center=1;dl=1;dt=1;transparent=1;z=4};
    • static4={cls="static";text="超时";left=32;top=168;right=64;bottom=192;center=1;dl=1;dt=1;transparent=1;z=5};
    • static5={cls="static";text="ID";left=296;top=64;right=320;bottom=88;center=1;dl=1;dt=1;transparent=1;z=11};
    • static7={cls="static";text="数据位";left=296;top=136;right=336;bottom=160;center=1;dl=1;dr=1;dt=1;transparent=1;z=12};
    • static8={cls="static";text="停止位";left=296;top=168;right=336;bottom=192;center=1;dl=1;dr=1;dt=1;transparent=1;z=13};
    • static9={cls="static";text="串口号";left=296;top=96;right=336;bottom=120;center=1;dl=1;dr=1;dt=1;transparent=1;z=17}
    • )
    • /*}}*/
    • mainForm.combobox_串口号.items = sys.comPort.list()
    • mainForm.combobox_串口号.selIndex = 1;
    • mainForm.edit_TCP_ip.text = "127.0.0.1"
    • var handle;
    • var m = modbus.modbustcp();
    • mainForm.button_TCP_连接.oncommand = function(id, event) {
    • var ip = mainForm.edit_TCP_ip.text;
    • var port = mainForm.edit_TCP_port.text;
    • var timeout = mainForm.edit_TCP_timer.text;
    • var v = wsock.tcp.client.test(ip);
    • if (type(v) == "string") {
    • if handle
    • return;
    • handle = m.tcpConnect(ip, port, timeout);
    • if (handle) {
    • win.msgbox("连接成功")
    • }
    • else {
    • win.msgbox("连接失败")
    • }
    • }
    • else {
    • win.msgbox("连接失败")
    • }
    • }
    • mainForm.button_TCP_断开.oncommand = function(id, event) {
    • if (handle) {
    • m.closeConnect();
    • handle = null;
    • win.msgbox("断开成功")
    • }
    • }
    • mainForm.button_读单个线圈.oncommand = function(id, event) {
    • var id = mainForm.edit_TCP_id.text
    • var addr = mainForm.edit_单个线圈地址.text;
    • var v = m.readCoils(id, addr, 1)
    • mainForm.edit_单个线圈值.text = v[1];
    • }
    • mainForm.button_写单个线圈.oncommand = function(id, event) {
    • var id = mainForm.edit_TCP_id.text
    • var addr = mainForm.edit_单个线圈地址.text;
    • var v = mainForm.edit_单个线圈值.text;
    • m.writeSingle(id, addr, v)
    • }
    • mainForm.button_读多个线圈.oncommand = function(id, event) {
    • var addr = mainForm.edit_多线圈地址.text;
    • var num = mainForm.edit_多线圈数量.text;
    • var id = mainForm.edit_TCP_id.text
    • var v = m.readCoils(id, addr, num)
    • console.dump(v)
    • mainForm.edit_多线圈值1.text = v[1];
    • mainForm.edit_多线圈值2.text = v[2];
    • }
    • mainForm.button_写多个线圈.oncommand = function(id, event) {
    • var id = mainForm.edit_TCP_id.text
    • var addr = mainForm.edit_多线圈地址.text;
    • var v1 = mainForm.edit_多线圈值1.text;
    • var v2 = mainForm.edit_多线圈值2.text;
    • m.writeMultipleCoils(id, addr, 2, {
    • v1;v2
    • })
    • }
    • mainForm.button_读单个寄存器.oncommand = function(id, event) {
    • var addr = mainForm.edit_单寄存器地址.text;
    • var regValue = mainForm.edit_单寄存器值.text;
    • var id = mainForm.edit_TCP_id.text
    • var v = m.readHoldingRegisters(id, addr, 1)
    • mainForm.edit_单寄存器值.text = tonumber(v[1], 16);
    • }
    • mainForm.button_写单个寄存器.oncommand = function(id, event) {
    • var addr = mainForm.edit_单寄存器地址.text;
    • var regValue = mainForm.edit_单寄存器值.text;
    • var id = mainForm.edit_TCP_id.text
    • m.writeSingleRegister(id, addr, tonumber(regValue))
    • }
    • mainForm.button_读多个寄存器.oncommand = function(id, event) {
    • var addr = mainForm.edit_多寄存器地址.text;
    • var regValue = mainForm.edit_多寄存器地址个数.text;
    • var id = mainForm.edit_TCP_id.text
    • var v = m.readHoldingRegisters(id, addr, regValue)
    • console.dump(v)
    • mainForm.edit_多寄存器地址值1.text = tonumber(v[1], 16)
    • mainForm.edit_多寄存器地址值2.text = tonumber(v[2], 16)
    • }
    • mainForm.button_写多个寄存器.oncommand = function(id, event) {
    • var v1 = tonumber(mainForm.edit_多寄存器地址值1.text);
    • var v2 = tonumber(mainForm.edit_多寄存器地址值2.text);
    • var id = mainForm.edit_TCP_id.text
    • m.writeMultipleRegisters(id, 0, 2, {
    • v1;v2
    • })
    • }
    • mainForm.button.oncommand = function(id,event){
    • //01功能码读
    • console.dump(m.readCoils(1,0,10));
    • }
    • mainForm.button2.oncommand = function(id,event){
    • //02功能码读
    • console.dump(m.readDiscreteInputs(1,0,10))
    • }
    • mainForm.button3.oncommand = function(id,event){
    • //03功能码读
    • console.dump(m.readHoldingRegisters(1,0,10))
    • }
    • mainForm.button4.oncommand = function(id,event){
    • //04功能码读
    • console.dump(m.readInputRegisters(1,0,10))
    • }
    • mainForm.show();
    • return win.loopMessage();

    1、修复04功能码获取不到数据问题

    感谢@13500720415 朋友的反馈

    上传的附件:
    最新回复 (34)
    • 13500720415 2024-2-5
      0 2

    • 13500720415 2024-2-5
      0 3
      很遗憾,本次修改仍未成功,按04按钮,出现的问题和以前的一模一样
    • 13500720415 2024-2-5
      0 4
      另外,第95行:var v = wsock.tcp.client.test(ip); 点击连接按钮,出现“连接2失败”,第109行;我填上(ip,port,timeout)后,就链接成功了。
    • axuanup 2024-2-5
      0 5
      可以的
    • axuanup 2024-2-5
      0 6

    • axuanup 2024-2-5
      0 7
      自己研究吧
    • 小光芒 2024-2-5
      0 8
      顶一个
    • 13500720415 2024-2-6
      0 9

      是不是我的环境出现了问题?请帮忙指导一下

      错误行号:#77  为     self.ZMB_ReadInputReg(this.handle, id, addr, count, buff, 0)   

      错误参数:@5 为  buff  

      整个程序均为在论坛上复制的,数据是从现场实际得到的

      除04功能码以外,其他按钮全部正常。


    • 13500720415 2024-2-7
      0 10
      你用的证明04功能码好用的软件,不是你提供的这个案例,
    • axuanup 2024-2-7
      0 11
      你提供你的案例工程,以及读的寄存器。
    • axuanup 2024-2-7
      0 12
      你把库替换掉呀
    • axuanup 2024-2-7
      0 13
      或者是你自己用仿真软件测试
    • 13500720415 2024-2-7
      0 14
      咱俩搞误会了,我这儿有一个远程遥测的实际现场,用组态软件一直在正常运转好多年了,出于好奇心,我这个编程的老白照葫芦画瓢,用python的modbus_tk.modbustcp编程来采集modbus数据,居然很成功,去年末在做桌面界面时 发现了aardio ,这个软件对我们初学者简直太友好了,当看到你这个工程案例特别高兴,就将你的这个案例套在上位机上用了一下,于是就发现了我提出来的问题,因为是初学,还没有能力把库换掉,我曾试过用aardio + python 结合起来,但是不太会用,目前我正在学习这方面的知识,希望能得到你的帮助。
    • 13500720415 2024-2-7
      0 15
      此楼层已删除
    • 13500720415 2024-2-7
      0 16
      python 目前主流使用操作modbus协议的库有三个: pymodbus 使用twisted实现的modbus完整协议(支持异步通讯); MinimalModbus 只支持modbusrtu ;modbus_tk 完整modbus协议栈的实现,支持modbus tcp/rtu{1.提供slave模拟器,即模拟modbus server:502), web-based hmi master支持}。 aardio 的 modbus 库,我只见到你引用的这个库 import modbus.modbustcp; 而 import wsock.tcp.client; 我认为是客户端的库,我没有再见到aardio里的另外的modbus的库可替换。
    • 13500720415 2024-2-8
      0 17

      终于发现了一点端倪,

      从下面的语句中,可以看到 #77 和 #64 是完全相同的,只是寄存器的名称不同,程序报告,问题出在 #77 的 @5 参数上。

      而在后面中 @5 又出现了不同的参数

      我不知道如何去处理,估计问题出在这里,请帮忙解决为盼



    • 13500720415 2024-2-13
      0 18

      周立功的modbus 协议关于#03,#04的 @5 参数是这样写的:

      参见《 ZModbusSdk 配置函数库使用手册    V 1.07  》

      视乎与 aardio 的 modbus 协议中,@5参数 略有不同

      self.ZMB_ReadHoldReg(this.handle, id, addr, count, buff, 0)

      self.ZMB_ReadInputReg(this.handle, id, addr, count, buff, 0)


      ZMB_ReadHoldReg = dll.api( /*03功能码读保持寄存器*/ "ZMB_ReadHoldReg", "int( INT hand, BYTE serID, int nStart, int nCount, string &bRet, WORD TranID)");

      ZMB_ReadInputReg = dll.api( /*04功能码读输入寄存器*/ "ZMB_ReadInputReg", "int( INT hand, BYTE serID, int nStart, int nCount, WORD & Ret, WORD TranID)");


      long ZMB_ReadHoldReg ( HANDLE hand, BYTE serID, int nStart, int nCount, WORD * bRet/*arr of reg*/, WORD TranID);

      long ZMB_ReadInputReg ( HANDLE hand, BYTE serID, int nStart, int nCount, WORD * Ret/*arr of reg*/, WORD TranID);

          总的来说,对于#03指令,可以正常运行。

      而对于#04号指令,aardio 的 modbus 协议,@5参数在上下文有不同,而且与周立功的modbus y也有区别。

      供参考。


    • 13500720415 2024-2-26
      0 19

      再啰嗦几句,我用aardio标准库的modbustcp协议库,和用aardio通过python的第三方库modbus_tk,进行采集现场数据对比,感觉速度上前者要比后者快很多,只可惜我们的标准库#04指令有问题,无法运行,以下是我的测试程序:

      import win.ui;

      /*DSG{{*/

      var winform = win.form(text="aardio form";right=759;bottom=469)

      winform.add(

      button={cls="button";text="调用 python 执行 modbus 数据采集";left=24;top=64;right=376;bottom=144;border=1;color=14120960;db=1;dr=1;font=LOGFONT(h=-14);note="每次点击都会重绘一次";z=2};

      button2={cls="button";text="aardio 执行 modbus 数据采集";left=392;top=64;right=744;bottom=144;border=1;color=14120960;db=1;dr=1;font=LOGFONT(h=-14);z=3};

      edit={cls="edit";left=24;top=176;right=376;bottom=432;edge=1;hscroll=1;multiline=1;vscroll=1;z=1};

      edit3={cls="edit";left=392;top=176;right=744;bottom=432;edge=1;hscroll=1;multiline=1;vscroll=1;z=4}

      )

      /*}}*/


      //以下是借用python的modbus_tk库

      import py3;   //aardio调用python

      import process.python;

      //import process.python.pip;

      var pyCode = /**

      import time

      import datetime

      import modbus_tk.modbus_tcp as mt

      import modbus_tk.defines as md

      ip = "10.168.4.75"

      port = 502 

      master = mt.TcpMaster(ip, 502)

      master.set_timeout(50.0)

      tn=datetime.datetime.now()    # 返回当前的datetime日期类型

      aa = master.execute(1,md.READ_HOLDING_REGISTERS,100,8)

      bb = master.execute(1,md.READ_INPUT_REGISTERS,0,3)

      aa1 = list(aa)

      for j, item  in  enumerate(aa1):

          aa1[j] = round(aa1[j]/100,2)    # 工程数据,小数点后2位

      bb1 = list(bb)

      for k, item in enumerate(bb1):

          bb1[k] = round(bb[k]/10000,2)   #数字改变,小数点2位 

      print("时间:",tn)

      print("输入寄存器",bb1)

      print("保持寄存器",aa1)

      print("---------------------")

      **/

      py3.exec(pyCode);

      winform.button.oncommand = function(id,event) { 

         var reslist = process.python.exec(pyCode);  // 执行Python脚本

          reslist.logResponse(winform.edit);     //第二种:python程序的执行方法!!

          }



      //以下是用aardio 自带的modbus库完成同一功能的


      import modbus.modbustcp;  //取寄存器的值

      var m = modbus.modbustcp();

      var ip = "10.168.3.75";

      var port = 502;

      var timeout = 50;

      var handle = m.tcpConnect(ip, port, timeout);


      winform.button2.oncommand = function(id,event){

      var v = m.readHoldingRegisters(1, 100, 8);      //用modbus读取寄存器的值

      //var w = m.readInputRegisters(1, 0, 3);     //w = 预期得到 number,实际获取为 buffer,错误!!

      var currDT = tostring(time(time.now(),"%Y-%m-%d %H:%M:%S"));  //当前日期

          winform.edit3.print(currDT);

          winform.edit3.print("输入寄存器无法运行");

          winform.edit3.print("保持寄存器=");

        for(i=1;8;1){

              winform.edit3.print(tonumber(v[i],16)/100);

               }

          //winform.edit3.print(v);

          winform.edit3.print("--------------"); 

         }


      winform.show();

      win.loopMessage();


      /**

      aardio语言简单明了,运行速度还很快。

      如果把自身的modbus库解决好,

      完全不必通过python的第三方库费力的去处理。

      **/

      这是监测站的两个虚拟局域网的地址,正常运行时,用的是组态软件进行的。

      另外,如何将数据竖排改成横排,改成左边的方式,请提示。

      拜个晚年,祝阖家团圆,工作愉快。

    • 光庆 2024-2-27
      0 20

      这种东西吧,就是因为大家没有硬件环境,不方便帮你测试,所以解决起来相对麻烦点。上次帮一个朋友搞串口库,人家直接把板子给我寄过来,我很快就搞定了。如果没有板子,就真不好测试了,就算搞一个库出来,运行结果对不对自己都不知道。

    • 13500720415 2024-2-27
      0 21
      谢谢回复。 我的主导思想就是:咱们的modbus协议库关于#04指令有点问题,稍许改动,就可以使我们的modbus协议正常运行,应该与硬件无关。我的建议,仅供参考。
    • 光庆 2024-2-28
      0 22
      13500720415 谢谢回复。 我的主导思想就是:咱们的modbus协议库关于#04指令有点问题,稍许改动,就可以使我们的modbus协议正常运行,应该与硬件无关。我的建议,仅供参考。

      不好意思啊,误会了,现在看明白了,你这是已经修复后的。

    • 13500720415 2024-2-28
      0 23
      是的,我只想请求把aardio的mogbus协议中的小错误改正一下,但我又不会改,我现在还没有修复这个错误的能力。实在抱歉。
    • 光庆 2024-2-29
      0 24
      13500720415 是的,我只想请求把aardio的mogbus协议中的小错误改正一下,但我又不会改,我现在还没有修复这个错误的能力。实在抱歉。

      还是因为没法测试,只能根据api定义,给你改一下,你自己测试一下:

      1、dll 声明先将var 去掉

      Code AardioLine:1复制
    • 1.
      • var dll = ..raw.loadDll(path)

      改为

      Code AardioLine:1复制
    • 1.
      • dll = ..raw.loadDll(path)

      2、readInputRegisters 函数定义改为:

      Code AardioLine:10复制
    • 1.
    • 2.
    • 3.
    • 4.
    • 5.
    • 6.
    • 7.
    • 8.
    • 9.
    • 10.
      • readInputRegisters = function(id, addr, count) {
      • if (this.handle) {
      • var buff = {
      • word w[] = {length = count}
      • }
      • dll.ZMB_ReadInputReg(this.handle, id, addr, count, buff, 0)
      • //返回一个表
      • return buff.w;
      • }
      • }


    • 光庆 2024-2-29
      0 25

      或这样:

      1、ZMB_ReadInputReg 定义改为:

      Code AardioLine:1复制
    • 1.
      • ZMB_ReadInputReg = dll.api( /*04功能码读输入寄存器*/ "ZMB_ReadInputReg", "int( INT hand, BYTE serID, int nStart, int nCount,struct &bRet, WORD TranID)");

      2、readInputRegisters 定义改为:

      Code AardioLine:10复制
    • 1.
    • 2.
    • 3.
    • 4.
    • 5.
    • 6.
    • 7.
    • 8.
    • 9.
    • 10.
      • readInputRegisters = function(id, addr, count) {
      • if (this.handle) {
      • var buff = {
      • word w[] = {length = count};
      • }
      • ZMB_ReadInputReg(this.handle, id, addr, count, buff, 0);
      • //返回一个表
      • return buff.w;
      • }
      • }


    • 13500720415 2024-3-5
      0 26

      刚从外地返回来,没能及时回复你的回帖,非常抱歉。

      根据你的提示,我又重新看了周立功的有关modbustcp库中对#03和#04指令的定义,结合我们aardio 对modbustcp库的#03和#0的对比,发现周立功的#03和#04指令中的@5参数全是WORD,而 aardio 的modbustcp中#03指令引用的是string,可用!而#04指令引用的是WORD,出现错误,于是我把aardio的modbustcp协议中的#04指令中的@5参数由WORD改成了string,结果成功了,

      125  

      ZMB_ReadHoldReg = dll.api( /*03功能码读保持寄存器*/ "ZMB_ReadHoldReg", "int( INT hand, BYTE serID, int nStart, int nCount, string &bRet, WORD TranID)");

      126

      ZMB_ReadInputReg = dll.api( /*04功能码读输入寄存器*/ "ZMB_ReadInputReg", "int( INT hand, BYTE serID, int nStart, int nCount, WORD    string& Ret, WORD TranID)");

      不知对否,供参考

      //以下是用aardio 自带的modbus库完成同一功能的

      import modbus.modbustcp;  //协议修改的内容见上

      var m = modbus.modbustcp();

      winform.button2.oncommand = function(id,event){

      var ip = "10.168.3.75";

      var port = 502;

      var timeout = 50;


      var handle = m.tcpConnect(ip, 502, 50);

      var v = m.readHoldingRegisters(1, 100, 8);      //用modbus读取寄存器的值

      var w = m.readInputRegisters(1, 0, 3);     //读取输入寄存器的值,现在可用了

      var currDT = tostring(time(time.now(),"%Y-%m-%d %H:%M:%S"));  //当前日期

          winform.edit3.print(currDT);

          winform.edit3.print("输入寄存器=");

          for i=1;3;1 {

                winform.edit3.print(math.round(tonumber(w[i],16)/10000,2));  //保持小数点后两位。

                }

          winform.edit3.print("--------------");

          winform.edit3.print("保持寄存器=");

        for i=1;8;1 {

                winform.edit3.print(tonumber(v[i],16)/100);

                }

          //winform.edit3.print(v);

          winform.edit3.print("--------------"); 

         }


      winform.show();

      win.loopMessage();


      能否帮我把竖排的数值改为横排的,我找了很长时间也没找到。麻烦你了。





    • 13500720415 2024-3-5
      0 27
      这是两个现场的数值,数据不一样
    • 13500720415 2024-3-7
      0 28
      谢谢光庆的指导,,我采用的是您第二个方案,立马成功,修改了aardio标准库中modbus协议里的一个bug,现在运行正常。
    • mndsoft 2024-7-10
      0 29
      请问楼主,ZMB_WriteCmdBuf 和 ZMB_ReadRecBuf这个功能函数没有封装进去,这2个是不是可以自定义功能码收发的?比如有些设备貌似扩展了功能码,方便的话能否加近期库,谢谢
    • axuanup 2024-7-16
      0 30
      没留意这个函数
    • mndsoft 2024-7-17
      0 31

      楼主帮忙看下 ZMB_WriteCmdBuf 这个函数,我照你的改了下提示错误。

      调用:m.WriteCmdBuf({1;48;240;0;0;10},6)


      Code AardioLine:9复制
    • 1.
    • 2.
    • 3.
    • 4.
    • 5.
    • 6.
    • 7.
    • 8.
    • 9.
      • //自定义写命令串 hand,BYTE *pBuf,int iLen,int nAddCheck,WORD TranID;
      • //TranID 在 TCP 的 MODBUS 协议里需要用到任务 ID 号,如果为 0 使用系统自生成的,串口MODBUS 此参数无效。
      • WriteCmdBuf = function(data,num ) {
      • if (this.handle) {
      • var n = bytetoew(data, self.wordtobyte)
      • n = self.ertoyi(n, #n, 2)
      • self.ZMB_WriteCmdBuf(this.handle,self.tobuffer(n),n, 0)
      • }
      • }


    • mndsoft 2024-7-17
      0 32

      在学习楼主这个库函数,我让 claude-3.5-sonnet 解释下 这个函数

      Code AardioLine:7复制
    • 1.
    • 2.
    • 3.
    • 4.
    • 5.
    • 6.
    • 7.
      • //word类型转byte类型
      • wordtobyte = function(w) {
      • var t = {}
      • t[1] = w & 0x00FF;
      • t[2] = (w >> 8) & 0x00FF;
      • return t;
      • }

      claude-3.5-sonnet 解释如下,楼主觉得 claude-3.5-sonnet解释的对吗?

    • mndsoft 2024-7-17
      0 33

      又让解释了 claude-3.5-sonnet  这个函数,感觉解释的还是挺不错。

      Code AardioLine:8复制
    • 1.
    • 2.
    • 3.
    • 4.
    • 5.
    • 6.
    • 7.
    • 8.
      • //16功能码,写多个寄存器
      • writeMultipleRegisters = function(id, addr, num, data) {
      • if (this.handle) {
      • var n = bytetoew(data, self.wordtobyte)
      • n = self.ertoyi(n, #n, 2)
      • self.ZMB_WriteRegMulitiple(this.handle, id, addr, num, self.tobuffer(n), 0)
      • }
      • }

    • axuanup 2024-7-17
      0 34
      我现在都用easymodbus
    • axuanup 2024-7-17
      0 35
      或者是自己封装协议库,我用到的基本上都是非标协议
    返回