广州大彩串口屏论坛_大彩开发者交流论坛

 找回密码
 立即注册
搜索
热搜: 活动 交友 discuz
查看: 200|回复: 3

modbus

[复制链接]

9

主题

21

帖子

97

积分

注册会员

Rank: 2

积分
97
发表于 2026-4-16 10:32:05 | 显示全部楼层 |阅读模式
有什么办法可以提高modbus的读取速度,我现在的modbus轮询延时是10毫秒,然后我开启一个定时器是50毫秒且无限循环,去读取modbus地址的值(共5个地址,且不是连续的),并且设置到文本当中。但是如果我快速的修改地址的值,虽然也能显示,但是有时候会卡顿一下,比如说我修改地址的值1-->2-->3-->4,时间很短,但是在屏幕上面可能就会1-->3-->4这样在2的时候卡顿一下且不显示。
回复

使用道具 举报

164

主题

210

帖子

1万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
11036
发表于 2026-4-16 16:18:32 | 显示全部楼层
需要看脚本逻辑是怎么处理的
销售与技术支持:(020)82186683-601
回复

使用道具 举报

9

主题

21

帖子

97

积分

注册会员

Rank: 2

积分
97
 楼主| 发表于 2026-4-16 17:25:36 | 显示全部楼层
卡米拉 发表于 2026-4-16 16:18
需要看脚本逻辑是怎么处理的

local cjson =require "cjson"

local dataflash = 0x1E61  --7777
local jsonstr_addr= 0x22B8 --8888

local guangban1
local write_data_byte = {}   --字节数组写入flash

--若数值为小数,则写入转换
local function write_transition(num)
    return num * 10
end

--若数值为小数,则读取转换
local function read_transition(val)
    return val / 10
end

function on_init()                            --界面初始化回调函
    local guangban = mb_read_reg_03(1, 267, 1)

    ---------------上电后读取数据---------------
    local read_data = read_flash(dataflash, 4)
    local chengxu = read_data[0]
    local dianya  = read_data[1]
    local maikuan = read_transition(read_data[2])
    local pinlv   = read_data[3]
    set_text(0, 15, chengxu)
    set_text(0, 16, dianya)
    set_text(0, 17, maikuan)
    set_text(0, 18, pinlv)
    set_text(0, 19, guangban)
    set_text(0, 67, chengxu)
    set_text(0, 25, dianya)
    set_text(0, 40, maikuan)
    set_text(0, 54, pinlv)
    set_text(0, 64, guangban)
    maikuan = maikuan * 10
    mb_write_reg_06(1,255,chengxu)
    mb_write_reg_06(1,430,dianya)
    mb_write_reg_06(1,304,maikuan)
    mb_write_reg_06(1,302,pinlv)
end

--按程序号保存数据到JSON键值对
local function write_data_to_chengxu(program_no, data_list)
    --读取现有JSON数据(无数据则初始化空表)
    local existing_json = read_flash_string(jsonstr_addr)
    --无论existing_json是否为空,都初始化为空表
    local data_table = {}
    if existing_json ~= "" then
        local status, res = pcall(cjson.decode, existing_json)  --保护性读取JSON数据
        if status then
            data_table = res
        else
            data_table = {}
        end
    end
        if type(data_table) ~= "table" then
        data_table = {}
    end
    --以程序号为键,写入新数据(程序号转为字符串避免数字键问题)
    local program_key = tostring(program_no)
    data_table[program_key] = data_list
    --编码为JSON并写入Flash
    local new_json = cjson.encode(data_table)
    write_flash_string(jsonstr_addr, new_json)
end

--按程序号读取JSON中的数据
local function read_data_to_chengxu(program_no)
    local program_key = tostring(program_no)
    --读取并解码JSON数据
    local existing_json = read_flash_string(jsonstr_addr)
    if existing_json == nil or existing_json == "" then
        return nil
    end

    local status, data_table = pcall(cjson.decode, existing_json)
    if not status or type(data_table) ~= "table" then
        return nil
    end

    return data_table[program_key]
end

--保存按键
local function on_save_button_click()
    local current_chengxu = tonumber(get_text(0,15))
        local data_to_save =
    {
                get_text(0,16),
                get_text(0,17),
                get_text(0,18),
        get_text(0,25),
        get_text(0,40),
        get_text(0,54)
        }
    -- 写入程序号
    write_data_to_chengxu(current_chengxu, data_to_save)

    write_data_byte[0] = current_chengxu
    write_data_byte[1] = data_to_save[1]
    write_data_byte[2] = write_transition(data_to_save[2])
    write_data_byte[3] = data_to_save[3]
    write_flash(dataflash, write_data_byte)
end

-- 切换程序:读取[当前语言]的数据
local function on_program_switch(program_no)
    local saved_data = read_data_to_chengxu(program_no)
    if saved_data then
        set_text(0,15, program_no)
        set_text(0,16, saved_data[1])
        set_text(0,17, saved_data[2])
        set_text(0,18, saved_data[3])
        set_text(0,67, program_no)
        set_text(0,25, saved_data[4])
        set_text(0,40, saved_data[5])
        set_text(0,54, saved_data[6])
    else
        -- 无数据则加载默认值
        set_text(0,15, program_no)
        set_text(0,16, 1)
        set_text(0,17, 0.1)
        set_text(0,18, 1)

        set_text(0,67, program_no)
        set_text(0,25, 1)
        set_text(0,40, 1)
        set_text(0,54, 1)
    end
end

function on_timer(timer_id)
    if timer_id == 0 then
        set_visiable(10,1,1)
        stop_timer(0)
        change_screen(0)
    elseif timer_id == 1 then    --plc写入到屏幕
        local chengxu = mb_read_reg_03(1, 255, 1)
        local dianya  = mb_read_reg_03(1, 430, 1)
        local maikuan = mb_read_reg_03(1, 304, 1)
        local pinlv   = mb_read_reg_03(1, 302, 1)
        set_value(0, 15, chengxu[0])
        set_value(0, 16, dianya[0])
        set_text(0, 17, maikuan[0] / 10)
        set_value(0, 18, pinlv[0])

        set_value(0, 67, chengxu[0])
        set_value(0, 25, dianya[0])
        set_text(0, 40, maikuan[0] / 10)
        set_value(0, 54, pinlv[0])
        guangban1 = mb_read_reg_03(1, 267, 1)
        if guangban1[0] > 60000 then
            set_text(0,64,(guangban1[0]-65536)/10)
            set_text(0,19,(guangban1[0]-65536)/10)
        else
            set_text(0,64,guangban1[0]/10)
            set_text(0,19,guangban1[0]/10)
        end
    elseif timer_id == 2 then
        stop_timer(2)
        set_enable(0,2,1)
        set_enable(0,1,1)
        set_enable(0,6,1)
        set_enable(0,4,1)
        set_enable(0,8,1)
        set_enable(0,7,1)
        set_enable(0,11,1)
        set_enable(0,9,1)
        set_enable(0,13,1)
        set_enable(0,12,1)
    end
end

function on_systick()

end

--用户通过触摸改控件后,执行回调函数
--点击按钮控件,修改文控件、修改滑动条都会触发此事件
function on_control_notify(screen,control,value)
    guangban1 = mb_read_reg_03(1, 267, 1)
    if screen == 0 then
        local chengxu = tonumber(get_text(0,15)) or 1
        local dianya = tonumber(get_text(0,16)) or 1
        local maikuan = tonumber(get_text(0,17)) or 0.3
        local pinlv = tonumber(get_text(0,18)) or 1
        local max_dianya_maikuan = tonumber(get_text(0,50))
        local max_maikuan_pinlv = tonumber(get_text(0,51))
        local max_value = tonumber(get_text(0,52))

        -------增减参数数值
        if control == 2 then        --程序号加
            if value == 1 or value == 2 then  --单击或长按
                local chengxu = chengxu + 1
                if chengxu > 20 then
                    chengxu = 20
                end
                mb_write_reg_06(1,255,chengxu)
                on_program_switch(chengxu)
                on_save_button_click()
                set_enable(0,2,0)
                start_timer(2, 300, 1, 1)
            end

                elseif control == 1  then        --程序号减
                        if value == 1 or value == 2 then  --单击或长按
                local chengxu = chengxu - 1
                if chengxu < 1 then
                    chengxu = 1
                end
                mb_write_reg_06(1,255,chengxu)
                on_program_switch(chengxu)
                on_save_button_click()
                set_enable(0,1,0)
                start_timer(2, 300, 1, 1)
            end

        elseif control == 6 then        --电压加
            if value == 1 or value == 2 then
                --获取当前电压、脉宽、频率以及三个相乘最大值,并且电压+1
                local dianya = dianya + 1
                --获取电压*脉宽的最大值,并且得到电压的限制值1
                local dianya_limit1 = max_dianya_maikuan // (maikuan*10)
                --当前电压*脉宽*频率是否大于最大值,如果大于,电压的限制值2=最大值/(脉宽*频率),如果电压大于限制值2,则电压=限制值2
                local current_value = dianya * maikuan * 10 * pinlv
                if current_value > max_value then
                    maikuan_pinlv = maikuan * 10 * pinlv
                    local dianya_limit2 = max_value // maikuan_pinlv
                    if dianya > dianya_limit2 then
                        dianya = dianya_limit2
                    end
                end
                if dianya > dianya_limit1 then
                    dianya = dianya_limit1
                elseif dianya > 100 then
                    dianya = 100
                end
                --写入文本控件当中,并且保存到flash以及寄存器当中
                mb_write_reg_06(1,430,dianya)
                set_text(0,16,dianya)
                set_text(0,25,dianya)
                on_save_button_click()
                set_enable(0,6,0)
                start_timer(2, 100, 1, 1)
            end

                elseif control == 4 then        --电压减
            if value == 1 or value == 2 then
                local dianya = dianya - 1
                local dianya_limit1 = max_dianya_maikuan // (maikuan*10)
                local current_value = dianya * maikuan * 10 * pinlv
                if current_value > max_value then
                    maikuan_pinlv = maikuan * 10 * pinlv
                    local dianya_limit2 = max_value // maikuan_pinlv
                    if dianya > dianya_limit2 then
                        dianya = dianya_limit2
                    end
                end
                if dianya > dianya_limit1 then
                    dianya = dianya_limit1
                elseif dianya < 1 then
                    dianya = 1
                end
                --写入文本控件当中,并且保存到flash以及寄存器当中
                mb_write_reg_06(1,430,dianya)
                set_text(0,16,dianya)
                set_text(0,25,dianya)
                on_save_button_click()
                set_enable(0,4,0)
                start_timer(2, 100, 1, 1)
            end

                elseif control == 8 then        --脉宽加
            if value == 1 or value == 2 then
                local maikuan = maikuan + 0.1
                maikuan = maikuan * 10
                local maikuan_limit1 = max_dianya_maikuan // dianya
                local maikuan_limit2 = max_maikuan_pinlv // pinlv
                local current_value = dianya * maikuan * pinlv
                if current_value > max_value then
                    dianya_pinlv = dianya * pinlv
                    local maikuan_limit3 = max_value // dianya_pinlv
                    if maikuan > maikuan_limit3 then
                        maikuan = maikuan_limit3
                    end
                end
                if maikuan > maikuan_limit1 then
                    maikuan = maikuan_limit1
                elseif maikuan > maikuan_limit2 then
                    maikuan = maikuan_limit2
                elseif maikuan > 250 then
                    maikuan = 250
                end
                mb_write_reg_06(1,304,maikuan)
                set_text(0,17,maikuan/10)
                set_text(0,40,maikuan/10)
                on_save_button_click()
                set_enable(0,8,0)
                start_timer(2, 100, 1, 1)
            end

                elseif control == 7 then        --脉宽减
            if value == 1 or value == 2 then
                local maikuan = maikuan - 0.1
                maikuan = maikuan * 10
                local maikuan_limit1 = max_maikuan_pinlv // pinlv
                local maikuan_limit2 = max_dianya_maikuan // dianya
                local current_value = dianya * maikuan * pinlv
                if current_value > max_value then
                    dianya_pinlv = dianya * pinlv
                    local maikuan_limit3 = max_value // dianya_pinlv
                    if maikuan > maikuan_limit3 then
                        maikuan = maikuan_limit3
                    end
                end
                if maikuan > maikuan_limit1 then
                    maikuan = maikuan_limit1
                elseif maikuan > maikuan_limit2 then
                    maikuan = maikuan_limit2
                elseif maikuan < 3 then
                    maikuan = 3
                end
                mb_write_reg_06(1,304,maikuan)
                set_text(0,17,maikuan/10)
                set_text(0,40,maikuan/10)
                on_save_button_click()
                set_enable(0,7,0)
                start_timer(2, 100, 1, 1)
            end

        elseif control == 11 then        --频率加
            if value == 1 or value == 2 then
                local pinlv = pinlv + 1
                local pinlv_limit1 = max_maikuan_pinlv // (maikuan*10)
                local current_value = dianya * maikuan * 10 * pinlv
                if current_value > max_value then
                    local dianya_maikuan = dianya * maikuan * 10
                    local pinlv_limit2 = max_value // dianya_maikuan
                    if pinlv > pinlv_limit2 then
                        pinlv = pinlv_limit2
                    end
                end
                if pinlv > pinlv_limit1 then
                    pinlv = pinlv_limit1
                elseif pinlv > 30 then
                    pinlv = 30
                end
                mb_write_reg_06(1,302,pinlv)
                set_text(0,18,pinlv)
                set_text(0,54,pinlv)
                on_save_button_click()
                set_enable(0,11,0)
                start_timer(2, 100, 1, 1)
            end

                elseif control == 9 then        --频率减
            if value == 1 or value == 2 then
                local pinlv = pinlv - 1
                local pinlv_limit1 = max_maikuan_pinlv // (maikuan*10)
                local current_value = dianya * maikuan * 10 * pinlv
                if current_value > max_value then
                    local dianya_maikuan = dianya * maikuan * 10
                    local pinlv_limit2 = max_value // dianya_maikuan
                    if pinlv > pinlv_limit2 then
                        pinlv = pinlv_limit2
                    end
                end
                if pinlv > pinlv_limit1 then
                    pinlv = pinlv_limit1
                elseif pinlv < 1 then
                    pinlv = 1
                end
                mb_write_reg_06(1,302,pinlv)
                set_text(0,18,pinlv)
                set_text(0,54,pinlv)
                on_save_button_click()
                set_enable(0,8,0)
                start_timer(2, 100, 1, 1)
            end
        elseif control == 13 then
            if value == 1 or value == 2 then
                if guangban1[0] > 60000 then
                    set_text(0,64,(guangban1[0]-65536)/10)
                    set_text(0,19,(guangban1[0]-65536)/10)
                else
                    set_text(0,64,guangban1[0]/10)
                    set_text(0,19,guangban1[0]/10)
                end
                set_enable(0,13,0)
                start_timer(2, 100, 1, 1)
            end
        elseif control == 12 then
            if value == 1 or value == 2 then
                if guangban1[0] > 60000 then
                    set_text(0,64,(guangban1[0]-65536)/10)
                    set_text(0,19,(guangban1[0]-65536)/10)
                else
                    set_text(0,64,guangban1[0]/10)
                    set_text(0,19,guangban1[0]/10)
                end
            end
            set_enable(0,12,0)
                start_timer(2, 100, 1, 1)
        end
    end
end
代码逻辑是这样的,点击控件的加减按键,然后写入到modbus中,我通过定时器来不断的获取该地址的值,并且写入到文本当中,但是在点击加减的时候(例如2加到3),屏幕上的文本可能是这样变化的,一开始是2,然后变为3,然后再变为2,最后再变为3,我的理解是第一次变为3是获取到我的json的数值是3,然后还没有写入到modbus地址中,但是定时器却获取了数值(该数值是旧的是2)写入到文本当中,然后定时器又一次获取了数值(这次就是新的数值了是3)就写入到文本当中。所以这种情况应该怎么解决。

回复

使用道具 举报

0

主题

988

帖子

2924

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
2924
发表于 2026-4-17 09:58:33 | 显示全部楼层
MB函数本身轮询显示就会很慢,没有控件直接关联变量 或者 get_variant 或 set_variant函数调用快。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|Archiver|手机版|小黑屋|广州大彩串口屏论坛_大彩开发者交流论坛

GMT+8, 2026-5-12 20:57 , Processed in 0.033783 second(s), 17 queries .

Powered by Discuz! X3.4

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表