大彩串口屏-龙8客户端下载






lua modbus应用






用户使用modbus协议时,可以通过lua交互实现复杂的逻辑,提供丰富的modbus接口函数,如下所示:

序号

描述/api

功能码

应用范围

1

获取变量值:get_variant(name)

-

fx2n/xgus/modbus

2

设置变量值:set_variant(name)

-

fx2n/xgus/modbus

3

读线圈变量:mb_read_coil_01 (slave,addr,quantity)

0x01

modbus

4

读离散变量:mb_read_input_02(slave,addr,quantity)

0x02

modbus

5

读保存寄存器:mb_read_reg_03(slave,addr,quantity)

0x03

modbus

6

读输入寄存器:mb_read_input_reg_04(slave,addr,quantity)

0x04

modbus

7

写单个线圈:mb_write_coil_05    (slave,addr,status)

0x05

modbus

8

写单个保存寄存器:mb_write_reg_06 (slave,addr,reg)

0x06

modbus

9

写多个线圈:mb_write_coil_15 (slave,addr,quantity,coils)

0x0f

modbus

10

写多个保存寄存器:mb_write_reg_16 (slave,addr,regs)

0x10

modbus

更多组态配置modbus、变量的创建请参考modbus教程,本章节不在阐述。本章节屏幕作为modbus 主站,创建线圈、离散输入、保存寄存器、输入寄存器各2个变量,具体属性可查看工程源文件,如下所示:

图片


本章节主要描述以下内容:

1. 变量名读写值

2. 线圈读写

3. 读离散变量

4. 保存寄存器读写

5. 读输入寄存器 

适用范围:m系列、w系列、x系列、f系列(固件版本 >= v4.2.401.0) 例程下载链接:《lua-modbusapi应用》(http://www.gz-dc.com/uploads/file/20210628/modbus - luaapi.zip   复制链接打开下载)

特别说明:本例程的演示,由虚拟屏和modbus slave联调,第三方工具modbus slave、虚拟串口具体的使用、获取等,本章节不在阐述,在我司龙8客户端下载官网下载或自行网上下载。



一、变量名读写值


get_variant(name)/set_variant(name)函数适用于在【工具】→【协议与变量...】里面创建的变量,不局限与modbus,同时适用于三菱fx2n、xgus等协议,用法一样,参考本章节即可。

1. 函数说明

读变量:get_variant(name)

  • name:字符串,变量名,应用变量时候一定要和【工具】→【协议与变量...】里面创建的变量一 致

eg:local data = get_variant(“设置温度”)

写变量:set_variant(name,value)

  • name:字符串,变量名,应用变量时候一定要和【工具】→【协议与变量...】里面创建的变量一 致
  • value:数值
eg:set_variant(“设置温度”,25)


2. 画面配置

变量名读写是通过get_variant(name) /set_variant(name)函数来实现,画面配置如下所示:

图片


线圈的读写:

  • 按钮控件id1:作为读取“电源/开机”的触发按钮,并将值显示在文本控件id2中;
  • 文本控件id2:显示get_variant(“电源/开机”)获取后的值;
  • 按钮控件id3:作为写“电源/开机”的触发按钮,将获取文本控件id4的值在写入;
  • 文本控件id4:键值输入“电源/开机”的目标值。

保存寄存器的读写:

  • 按钮控件id5:作为读取“目标温度”的触发按钮,并将值显示在文本控件id6中;
  • 文本控件id6:显示get_variant(“设置温度”)获取后的值;
  • 按钮控件id7:作为写“设置温度”的触发按钮,将获取文本控件id8的值在写入;
  • 文本控件id8:键值输入“设置温度”的目标值。


3. lua脚本

按钮控件id1按下时,将“电源/开机”显示在文本控件id1中,同理其他按钮/文本对应控件联动触发、显示,lua脚本如下所示:

--用户通过触摸修改控件后,执行此回调函数。
--点击按钮控件,修改文本控件、修改滑动条都会触发此事件。
function on_control_notify(screen,control,value)
    if screen == sc_variant
    then
        if control == 1 and value == 0
        then
            local power = get_variant('电源/开机')
            set_value(sc_variant, 2, power)
        elseif control == 3 and value == 0
        then
            local power = get_value(sc_variant, 4)
            set_variant('电源/开机', power)
        elseif control == 5 and value == 0
        then
            local dsttempe = get_variant('设置温度')
            set_value(sc_variant, 6, dsttempe)
        elseif control == 7 and value == 0
        then
            local dsttempe = get_value(sc_variant, 8)
            set_variant('设置温度', dsttempe)
        end
    ......
    end
end


4. 运行预览

根据画面配置和lua脚本,运行结果如下所示

图片





二、线圈(0x01,0x05,0x0f)


线圈的读写还可以通过mb函数来实现

1. 函数说明

读取线圈:

mb_read_coil_01 (slave,addr,quantity)

  • salve从机站号 
  • addr线圈起始地址 
  • quantity读取的个数

读取成功:返回字节数组,8个线圈为一个字节;读取失败,返回nil

如:从0开始,读取32个线圈,local coilstb = mb_read_coil_01 (1, 0, 32) 

假设读取成功,返回的字节内容依次为 coilstb[0]=0x12,coilstb[1]=0x24,coilstb[1]=0x0c,coilstb[1]=0x08线圈和字节数组的每一位的对应关 系,如下所示:

写单个线圈:mb_write_coil_05(slave,addr,state)

  • salve从机站号 
  • addr线圈地址 
  • state线圈状态,01

写成功,返回ture写失败,返回false


写多个线圈:mb_write_coil_15 (slave,addr,quantity,coils)

  • salve从机站号 
  • addr线圈地址 
  • quantity读取的个数
  • coils字节数组,设置的值,关系可参考上表

成功,返回ture写失败,返回false 


2. 画面配置 

通过mb函数来实现,画面配置如下所示


读线圈:

  • 按钮控件id1:作为读取"线圈"的触发按钮,并将值显示在文本控件id2、id4中 
  • 文本控件id2:显示mb_read_coil_01(, , , )获取变量"电源"的值(coil1~coil16) 
  • 按钮控件id4:显示mb_read_coil_01(, , , )获取变量"模式"的值(coil17~coil32)

设置单个线圈"电源/开机":

  • 按钮控件id5:设置线圈"电源/开机"  =  1的触发按钮

设置多个线圈  "电源/开机"、"指示灯开关":

  • 按钮控件id7:设置线圈"电源/开机" = 1、"指示灯开关" = 1的触发按钮


3. lua脚本

按钮控件id1按下时,将?电源?、?模式?显示在文本控件id2、文本控件id4中,同理其他按钮/文本对应控 件联动触发、显示,lua脚本如下所示:


--设置位函数
--data:源数据
--bitmask:第几位位置
--state:数值,0或1
function set_bits(data, bitmask, state)
    bitmask  = (1 << bitmask) & 0xff
    if state == 0
    then
        data = data & (~bitmask)
    elseif state == 1
    then
        data = data | bitmask
    end
    print(data)
    return data
end
--用户通过触摸修改控件后,执行此回调函数。
--点击按钮控件,修改文本控件、修改滑动条都会触发此事件。
function on_control_notify(screen,control,value)
    ......
    elseif screen == sc_coils
    then
        if control == 1 and value == 1
        then
            local power, mode = 0, 0
            --modbus coils: 请求从站号1,从地址0开始的32个线圈
            local coilstb = mb_read_coil_01(1, 0, 32)
            if coilstb ~= nil
            then
                power = (coilstb[1] << 8) | coilstb[0]
                mode  = (coilstb[3] << 8) | coilstb[2]
                print('power = '..power)
                print('mode = '..mode)
                set_text(sc_coils, 2, power)
                set_text(sc_coils, 4, mode)
            end
        elseif control == 5
        then
            mb_write_coil_05(1, 0, value)
        elseif control == 7 and value == 0
        then
            local power = 0
            local mode  = 0
            --modbus read coils: 读从站号1,从地址0开始的32个线圈
            local coilstb = mb_read_coil_01(1, 0, 32)
            if coilstb ~= nil
            then
                coilstb[0] = set_bits(coilstb[0], 0, 1)  --设置“开机-电源”= 1
                coilstb[2] = set_bits(coilstb[2], 6, 1)  --设置“状态-打开指示灯” = 1
                --modbus write coils: 
                mb_write_coil_15 (1, 0, 32, coilstb)
            end
        end
        ......
    end
end



4. 运行预览

根据画面配置和lua脚本,运行结果如下所示:





三、离散输入(0x02)


1.函数说明

读取离散输入:mb_read_input_02(slave,addr,quantity)

  • salve:从机站号 
  • addr:离散输入寄存器的起始地址 quantity:读取的个数

读取成功:字节数组,8个离散输入为一个字节;读取失败,返回nil

如:从0开始,读取32个离散输入,local discretetb = mb_read_input_02 (1, 0, 32)

离散变量和字节数组的每一位的对应关系可参考线圈说明


2. 画面配置

通过mb函数来实现【离散输入】寄存器的读取,画面配置如下所示:


读离散输入寄存器:

  • 按钮控件id1:作为读取离散输入寄存器“状态”、“告警”的触发按钮,并将值显示在文本控件id2、id4中
  • 文本控件id2:显示mb_read_input_02(, , , )获取变量“状态”的值(discrete1~discrete16) 
  • 文本控件id4:显示mb_read_input_02(, , , )获取变量"告警"的值(discrete17~discrete32)


3. lua脚本

按钮控件id1按下时,将"状态"、"告警"显示在文本控件id2、文本控件id4中,lua脚本如下所示:


--用户通过触摸修改控件后,执行此回调函数。
--点击按钮控件,修改文本控件、修改滑动条都会触发此事件。
function on_control_notify(screen,control,value)
    ......
    elseif screen == sc_discrete
    then
        if control == 1 and value == 1
        then
            local status, alert  = 0, 0
            --modbus coils: 请求从站号1,从地址0开始的32个线圈
            local discretetb = mb_read_input_02(1, 0, 32)
            if discretetb ~= nil
            then
                status = (discretetb[1] << 8) | discretetb[0]
                alert  = (discretetb[3] << 8) | discretetb[2]
                print('status  = '..status)
                print('alert = '..alert)
                set_text(sc_discrete, 2, status)
                set_text(sc_discrete, 4, alert)
            end
        end
    ......
end



4. 运行预览

根据画面配置和lua脚本,运行结果如下所示:





四、保存寄存器(0x03,0x06,0x10)


1. 函数说明

读取保持寄存器:mb_read_reg_03(slave,addr,quantity)
  • salve:从机站
  • addr:保存寄存器的起始地
  • quantity:读取的个数

读取成功,返回字数组;读取失败,返回nil


写单个保存寄存器:mb_write_reg_06 (slave,addr,reg)
  • salve:从机站号
  • addr:保存寄存器地址
  • reg:寄存器

写成功,返回ture;写失败,返回false;


写多个保存寄存器:mb_write_reg_16 (slave,addr,regs)
  • salve:从机站
  • addr:写的起始地址
  • regs:数组,word字数组

写成功,返回ture;写失败,返回false;


2. 画面配置

通过mb函数来实现【保持寄存器】的读写,画面配置如下所示:

读保存寄存器:

  • 按钮控件id1:作为读取“设置温度”、“设置湿度”的触发按钮,并将值显示在文本控件id2、id4中
  • 文本控件id2:显示mb_read_reg_03(,,,)获取变量“设置温度”的值
  • 文本控件id4:显示mb_read_reg_03(,,,)获取变量“设置湿度”的值

设置单个保存寄存器 “设置温度”:

  • 按钮控件id5:设置保存寄存器“设置温度” = 25 的触发按钮

设置多个线圈 “设置温度”、“设置湿度”:

  • 按钮控件id7:设置保存寄存器“设置温度” = 28、“设置湿度” = 60 的触发按钮


3. lua脚本

按钮控件id1按下时,将“设置温度”、“设置湿度”显示在文本控件id2、文本控件id4中,同理其他按钮/文本对应控件联动触发、显示,lua脚本如下所示:


--用户通过触摸修改控件后,执行此回调函数。
--点击按钮控件,修改文本控件、修改滑动条都会触发此事件。
function on_control_notify(screen,control,value)
    ......
    elseif screen == sc_holding
    then
        if control == 1 and value == 1
        then
            local holdtb = mb_read_reg_03(1, 0, 2)
            if holdtb ~= nil
            then
                set_text(sc_holding, 2, holdtb[0])
                set_text(sc_holding, 4, holdtb[1])
            end
        elseif control == 5 and value == 0
        then
            mb_write_reg_06(1, 0, 25)
        elseif control == 7 and value == 0
        then
            local holdtb = {}
            holdtb[0] = 28
            holdtb[1] = 60
            mb_write_reg_16(1, 0, holdtb)
        end
    ......
    end
end



4. 运行效果

根据画面配置和lua脚本,运行结果如下所示





五、输入寄存器(0x04)


1. 函数说明

读输入寄存器:mb_read_input_reg_04(slave,addr,quantity)

  • salve:从机站
  • addr:输入寄存器的起始地址
  • quantity:读取的个数

读取成功,返回字数组;读取失败,返回nil


2. 画面配置

通过mb函数来实现【输入寄存器】的读取,画面配置如下所示:


读输入寄存器:

  • 按钮控件id1:作为读取输入寄存器“回风变量”、“回风湿度”的触发按钮,并将值显示在文本控件id2、id4中
  • 文本控件id2:显示mb_read_input_reg_04(,,,)获取变量“回风温度”的值
  • 文本控件id4:显示mb_read_input_reg_04(,,,)获取变量“回风湿度”的值


3. lua脚本

按钮控件id1按下时,将“回风温度”、“回风湿度”显示在文本控件id2、文本控件id4中,lua脚本如下所示:


--用户通过触摸修改控件后,执行此回调函数。
--点击按钮控件,修改文本控件、修改滑动条都会触发此事件。
function on_control_notify(screen,control,value)
    ......
    elseif screen == sc_input
    then
        if control == 1 and value == 1
        then
            local inputtb =  mb_read_input_reg_04(1, 0, 2)
           if inputtb ~= nil
            then
                set_text(sc_input, 2, inputtb[0])
                set_text(sc_input, 4, inputtb[1])
            end
        end
    ......
end




4. 运行预览

根据画面配置和lua脚本,运行结果如下所示





六、更多技术资料


更多技术资料链接: