|
|

楼主 |
发表于 2026-4-16 17:25:36
|
显示全部楼层
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)就写入到文本当中。所以这种情况应该怎么解决。
|
|