您尚未登录。

#1 Re: 计算机图形/GUI/RTOS/FileSystem/OpenGL/DirectX/SDL2 » AWTK 开源智能串口屏方案发布 » 2024-03-28 15:57:28

这个方案挺好的啊,有人玩不,我建了个交流群,企鹅:335477091

#2 Re: 全志 SOC » f1c100s awtk lua 串口屏之串口调试助手应用分享 » 2024-03-01 14:55:17

DDER 说:

整套方案有点类似大彩的串口屏。思路不错,
大彩有专用的上位机和模拟器。可以设计界面并编译lua脚本 生成固件。

也把运行lua脚本的模拟器加上了,可进行硬件无关的绝大多数控件的模拟了(可查看lua文件的报错输出)

将main.lua文件放置到bin/demos/目录下,运行awtkRun.exe即可进行硬件无关的界面逻辑的模拟了

awtkRun.png

local img_index = 0

local line_series_tm_id = 0

local bar_series_tm_id = 0

local gauge_tm_id = 0

local liquid_flow_tm_id = 0

local flow_tank_img_index = 4

local left_pointer_angle = -129

local right_pointer_angle = -129

local datetime = {0}

local timer_id = 0

local trh_tm_id = 0

local temp_tm_id = 0

local period_send_tm = 0

local password = "0124678"

s_preload_res = {
  {type = AssetType.IMAGE, name = "bg"},
  {type = AssetType.IMAGE, name = "bar_chart"},
  {type = AssetType.IMAGE, name = "button"},
  {type = AssetType.IMAGE, name = "chart_view"},
  {type = AssetType.IMAGE, name = "checkbox"},
  {type = AssetType.IMAGE, name = "clock_bg"},
  {type = AssetType.IMAGE, name = "clock_hour"},
  {type = AssetType.IMAGE, name = "clock_minute"},
  {type = AssetType.IMAGE, name = "clock_second"},
  {type = AssetType.IMAGE, name = "color_picker"},
  {type = AssetType.IMAGE, name = "coolingCoilFalse"},
  {type = AssetType.IMAGE, name = "fanRightFalse"},
  {type = AssetType.IMAGE, name = "damperV5"},
  {type = AssetType.IMAGE, name = "damperH5"},
  {type = AssetType.IMAGE, name = "filterV1"},
  {type = AssetType.IMAGE, name = "heatingCoilv2wRFalse"},
  {type = AssetType.IMAGE, name = "coolingCoilv2wRFalse"},
  {type = AssetType.IMAGE, name = "data_log"},
  {type = AssetType.IMAGE, name = "ductD"},
  {type = AssetType.IMAGE, name = "gesture_lock"},
  {type = AssetType.IMAGE, name = "grid"},
  {type = AssetType.IMAGE, name = "guage_bg_1"},
  {type = AssetType.IMAGE, name = "guage_bg_2"},
  {type = AssetType.IMAGE, name = "img_animation"},
  {type = AssetType.IMAGE, name = "log"},
  {type = AssetType.IMAGE, name = "meter"},
  {type = AssetType.IMAGE, name = "num_lab"},
  {type = AssetType.IMAGE, name = "progress_circle"},
  {type = AssetType.IMAGE, name = "qr_code"},
  {type = AssetType.IMAGE, name = "radio_button"},
  {type = AssetType.IMAGE, name = "slider_circle"},
  {type = AssetType.IMAGE, name = "text_select"},
  {type = AssetType.IMAGE, name = "time_clock"},
  {type = AssetType.IMAGE, name = "uiex_clock_bg"},
  {type = AssetType.IMAGE, name = "uiex_load1_bg"},
  {type = AssetType.IMAGE, name = "uiex_load2_bg"},
  {type = AssetType.IMAGE, name = "uiex_load1_loading"},
  {type = AssetType.IMAGE, name = "uiex_load2_loading"},
  {type = AssetType.IMAGE, name = "Tank_Fuel0"},
  {type = AssetType.IMAGE, name = "Tank_Fuel1"},
  {type = AssetType.IMAGE, name = "Tank_Fuel2"},
  {type = AssetType.IMAGE, name = "Tank_Fuel3"},
  {type = AssetType.IMAGE, name = "Tank_Fuel4"},
  {type = AssetType.IMAGE, name = "Tank_Water0"},
  {type = AssetType.IMAGE, name = "Tank_Water1"},
  {type = AssetType.IMAGE, name = "Tank_Water2"},
  {type = AssetType.IMAGE, name = "Tank_Water3"},
  {type = AssetType.IMAGE, name = "Tank_Water4"},
  {type = AssetType.IMAGE, name = "calendar"}
}

local TIME_PER_DIV = 2000        -- 每个DIV的持续时间
local SAMPLE_COUNT_PER_DIV = 10  -- 每个DIV的采样点数


--***************************************************UI界面更新及切换**************************************************************

function str_contains(str, substr) 
  local s, e = string.find(str, substr);

  return s ~= nil;
end

function qr_view_init(iter) 
  local widget_name = iter.name;
  if(str_contains(widget_name, 'btn_update_qr'))
  then
    iter:on(EventType.CLICK, function(evt)
      local qr_data = win_qr_view:lookup('edit_qr_data', TRUE):get_text()
      if qr_data ~= nil then
          win_qr_view:lookup('qr', TRUE):set_value(to_str(qr_data))
      end
    end)
  elseif(str_contains(widget_name, 'close'))
  then
    iter:on(EventType.CLICK, function(evt)
      win_qr_view:close()
      win_qr_view = nil
      return Ret.OK
    end)
  end
  return Ret.OK
end

function win_line_series_parall_init(iter) 
  local widget_name = iter.name;
  if(str_contains(widget_name, 'close'))
  then
    iter:on(EventType.CLICK, function(evt)
      win_line_series_parall:close()
      win_line_series_parall = nil
      return Ret.OK
    end)
  end
  return Ret.OK
end

function chart_view_init(iter) 
  local widget_name = iter.name;
  if(str_contains(widget_name, 'close'))
  then
    iter:on(EventType.CLICK, function(evt)
      win_chart_view:close()
      win_chart_view = nil
      return Ret.OK
    end)
  end
  return Ret.OK
end

function win_btn_init(iter) 
  local widget_name = iter.name;
  if(str_contains(widget_name, 'btn_lvl0'))
  then
    iter:on(EventType.CLICK, function(evt)
      win_btn:lookup('image_lvl', TRUE):set_prop_str("image", "Tank_Fuel0")
    end)
  elseif(str_contains(widget_name, 'btn_lvl1'))
  then
    iter:on(EventType.CLICK, function(evt)
      win_btn:lookup('image_lvl', TRUE):set_prop_str("image", "Tank_Fuel1")
    end)   
  elseif(str_contains(widget_name, 'btn_lvl2'))
  then
    iter:on(EventType.CLICK, function(evt)
      win_btn:lookup('image_lvl', TRUE):set_prop_str("image", "Tank_Fuel2")
    end)   
  elseif(str_contains(widget_name, 'btn_lvl3'))
  then
    iter:on(EventType.CLICK, function(evt)
      win_btn:lookup('image_lvl', TRUE):set_prop_str("image", "Tank_Fuel3")
    end)   
  elseif(str_contains(widget_name, 'btn_lvl4'))
  then
    iter:on(EventType.CLICK, function(evt)
      win_btn:lookup('image_lvl', TRUE):set_prop_str("image", "Tank_Fuel4")
    end)   
  elseif(str_contains(widget_name, 'close'))
  then
    iter:on(EventType.CLICK, function(evt)
      win_btn:close()
      win_btn = nil
      return Ret.OK
    end)
  end

  return Ret.OK
end

function timer_hvac(info)
  local t1 
  t1 = math.random(10,100)
  win_check_btn:lookup('number_label_t1', TRUE):set_value(t1);
  t1 = math.random(10,100)
  win_check_btn:lookup('number_label_t2', TRUE):set_value(t1);
  t1 = math.random(10,100)
  win_check_btn:lookup('number_label_t3', TRUE):set_value(t1);
  t1 = math.random(10,100)
  win_check_btn:lookup('number_label_t4', TRUE):set_value(t1);

  img_index = img_index + 1
  local str_name_v = "damperV"..img_index
  win_check_btn:lookup('gif_damper_v', TRUE):set_prop_str("image", str_name_v)
  local str_name_h = "damperH"..img_index
  win_check_btn:lookup('gif_damper_h', TRUE):set_prop_str("image", str_name_h)

  if img_index == 5 then
    img_index = 1
  end
  
  return Ret.REPEAT
end

function win_check_btn_init(iter)
  local widget_name = iter.name;
  if(str_contains(widget_name, 'btn_check_btn'))
  then
    iter:on(EventType.CLICK, function(evt)
      fan_check_btn = iter:get_value()
      if fan_check_btn == 1 then
        win_check_btn:lookup('gif_fan_r', TRUE):set_prop_str("image", "fanRightTrue")
        if timer_id == 0 then
          timer_id = Timer.add(timer_hvac, 2000)
        end
      else
        win_check_btn:lookup('gif_fan_r', TRUE):set_prop_str("image", "fanRightFalse")
        Timer.remove(timer_id)
        timer_id = 0
      end
    end)
  elseif(str_contains(widget_name, 'slider_set'))
  then
    local set_point = iter:get_value()
    iter:get_window().lab_t_set:set_text(string.format("%d", set_point))
    
    iter:on(EventType.VALUE_CHANGING, function(evt)
      local set_point = iter:get_value()
      iter:get_window().lab_t_set:set_text(string.format("%d", set_point))
    end) 
  elseif(str_contains(widget_name, 'close'))
  then
    iter:on(EventType.CLICK, function(evt)
      win_check_btn:close()
      win_check_btn = nil
      return Ret.OK
    end)
  end
  return Ret.OK
end

function on_gauge_set_angle(info)
  left_pointer_angle = left_pointer_angle + 1
  right_pointer_angle = right_pointer_angle + 1

  --win_gauge:lookup('guage_l', TRUE):lookup('left_pointer', TRUE):set_angle(left_pointer_angle)
  --win_gauge:lookup('guage_r', TRUE):lookup('right_pointer', TRUE):set_angle(right_pointer_angle)

  local guage_pointer_l = win_gauge:lookup('guage_l', TRUE):lookup('left_pointer', TRUE)
  GaugePointer.cast(guage_pointer_l):set_angle(left_pointer_angle)

  --local guage_pointer_r = win_gauge:lookup('guage_r', TRUE):lookup('right_pointer', TRUE)
  --GaugePointer.cast(guage_pointer_r):set_angle(right_pointer_angle)


  if left_pointer_angle >= 128 then
    left_pointer_angle = -129
  end

  if right_pointer_angle >= 128 then
    right_pointer_angle = -129
  end

  return Ret.REPEAT
end

function win_gauge_init(iter)
  local widget_name = iter.name;
  if(str_contains(widget_name, 'btn_start'))
  then
    iter:on(EventType.CLICK, function(evt)
      if gauge_tm_id == 0 then
        gauge_tm_id = Timer.add(on_gauge_set_angle, 100)
      end
    end)
  elseif(str_contains(widget_name, 'btn_stop'))
  then
    iter:on(EventType.CLICK, function(evt)
      Timer.remove(gauge_tm_id)
      gauge_tm_id = 0
    end)   
  elseif(str_contains(widget_name, 'btn_close'))
  then
    iter:on(EventType.CLICK, function(evt)
      Timer.remove(gauge_tm_id)
      gauge_tm_id = 0
      win_gauge:close()
      win_gauge = nil
      return Ret.OK
    end)  
  end
  return Ret.OK
end

function win_gesture_lock_init(iter)
  local widget_name = iter.name;
  if(str_contains(widget_name, 'close'))
  then
    iter:on(EventType.CLICK, function(evt)
      win_gesture_lock:close()
      win_gesture_lock = nil
      return Ret.OK
    end)  
  elseif(str_contains(widget_name, 'gesture_lock_set'))
  then
    iter:on(EventType.VALUE_CHANGED, function(evt)
      local value = ValueChangeEvent.cast(evt).new_value
      local pass_input = Value.cast(value):str()

      print("password input ", pass_input)

      if password == pass_input then
        win_popup = Window.open('win_popup')
        win_popup.lab_pass_info:set_text("密码正确!")
        win_popup.btn_ret:on(EventType.CLICK, function(evt)
          win_popup:close()
          win_popup = nil
          return Ret.OK
        end)  
      else
        win_popup = Window.open('win_popup')
        win_popup.lab_pass_info:set_text("密码错误!")
        win_popup.btn_ret:on(EventType.CLICK, function(evt)
          win_popup:close()
          win_popup = nil
          return Ret.OK
        end)  
      end
      
      return Ret.REMOVE
    end)
  end
  return Ret.OK
end

function win_pro_circle_init(iter)
  local widget_name = iter.name;
  if(str_contains(widget_name, 'close'))
  then
    iter:on(EventType.CLICK, function(evt)
      iter:get_window():close()
      win_pro_circle = nil
      return Ret.OK
    end)  
  end
  return Ret.OK
end

function win_text_select_init(iter)
  local widget_name = iter.name
  if(str_contains(widget_name, 'close'))
  then
    iter:on(EventType.CLICK, function(evt)
      datetime:destroy()
      iter:get_window():close()
      win_text_select = nil
      return Ret.OK
    end)  
  elseif(str_contains(widget_name, 'text_selector_year'))
  then
    iter:set_selected_index(24)
  elseif(str_contains(widget_name, 'text_selector_mon'))
  then
    iter:set_selected_index(1)
  elseif(str_contains(widget_name, 'text_selector_day'))
  then
    iter:set_selected_index(17)
  elseif(str_contains(widget_name, 'text_selector_hour'))
  then
    iter:set_selected_index(12)
  elseif(str_contains(widget_name, 'text_selector_min'))
  then
    iter:set_selected_index(46)
  elseif(str_contains(widget_name, 'text_selector_sec'))
  then
    iter:set_selected_index(30)
  elseif(str_contains(widget_name, 'btn_time_set'))
  then
    iter:on(EventType.CLICK, function(evt)
      local year = iter:get_window():lookup('text_selector_year'):get_value_int()
      local month = iter:get_window():lookup('text_selector_mon'):get_value_int()
      local day = iter:get_window():lookup('text_selector_day'):get_value_int()
      local hour = iter:get_window():lookup('text_selector_hour'):get_value_int()
      local minute = iter:get_window():lookup('text_selector_min'):get_value_int()
      local second = iter:get_window():lookup('text_selector_sec'):get_value_int()

      datetime:set_year(year)
      datetime:set_month(month)
      datetime:set_day(day)
      datetime:set_hour(hour)
      datetime:set_minute(minute)
      datetime:set_second(second)
      datetime:set()
      
      return Ret.OK
    end) 
  end
  return Ret.OK
end

function win_slider_circle_init(iter)
  local widget_name = iter.name;
  if(str_contains(widget_name, 'close'))
  then
    iter:on(EventType.CLICK, function(evt)
      iter:get_window():close()
      win_slider_circle = nil
      return Ret.OK
    end)  
  elseif(str_contains(widget_name, 'slider_circle_l'))
  then
    iter:on(EventType.VALUE_CHANGING, function(evt)
      local vlab = iter:get_value()
      local v_txt = string.format("%d", vlab)
      iter:get_window():lookup('slider_circle_l', TRUE):lookup('value_l', TRUE):set_text(v_txt)
      return Ret.OK
    end) 
  elseif(str_contains(widget_name, 'slider_circle_r'))
  then
    iter:on(EventType.VALUE_CHANGING, function(evt)
      local vlab = iter:get_value()
      local v_txt = string.format("%d", vlab)
      iter:get_window():lookup('slider_circle_r', TRUE):lookup('value_r', TRUE):set_text(v_txt)
      return Ret.OK
    end) 
  end
  return Ret.OK
end

function win_radio_btn_init(iter)
  local widget_name = iter.name;
  if(str_contains(widget_name, 'close'))
  then
    iter:on(EventType.CLICK, function(evt)
      iter:get_window():close()
      win_radio_btn = nil
      return Ret.OK
    end)  
  end
  return Ret.OK
end


function win_temp_chart_view_init(iter) 
  local widget_name = iter.name;
  if(str_contains(widget_name, 'close'))
  then
    iter:on(EventType.CLICK, function(evt)
      win_temp_chart_view:close()
      win_temp_chart_view = nil
      return Ret.OK
    end)
  end
  return Ret.OK
end

function win_trh_chart_view_init(iter) 
  local widget_name = iter.name;
  if(str_contains(widget_name, 'close'))
  then
    iter:on(EventType.CLICK, function(evt)
      win_trh_chart_view:close()
      win_trh_chart_view = nil
      return Ret.OK
    end)
  end
  return Ret.OK
end

function win_trh_view_init(iter)
  local widget_name = iter.name;
  if(str_contains(widget_name, 'close'))
  then
    iter:on(EventType.CLICK, function(evt)
      iter:get_window():close()
      win_trh_view = nil
      return Ret.OK
    end)  
  end
  return Ret.OK
end

function win_sscom_init(iter)
  local widget_name = iter.name;
  if(str_contains(widget_name, 'close'))
  then
    iter:on(EventType.CLICK, function(evt)
      win_sscom:close()
      win_sscom = nil
      return Ret.OK
    end)
  end
  return Ret.OK
end

function win_liquid_flow_init(iter)
  local widget_name = iter.name;
  if(str_contains(widget_name, 'close'))
  then
    iter:on(EventType.CLICK, function(evt)
      Timer.remove(liquid_flow_tm_id)
      liquid_flow_tm_id = 0
      flow_tank_img_index = 4
      iter:get_window():close()
      win_liquid_flow = nil
      return Ret.OK
    end)  
  elseif(str_contains(widget_name, 'btn_flow_stop'))
  then
    iter:on(EventType.CLICK, function(evt)
      iter:get_window():lookup('gif_pump', TRUE):set_prop_str("image", "generatorFalse")
      iter:get_window():lookup('gif_boiler', TRUE):set_prop_str("image", "Boiler_Generic_Left_Off")
      iter:get_window():lookup('flow1', TRUE):set_running(false)
      iter:get_window():lookup('flow2', TRUE):set_running(false)
      iter:get_window():lookup('flow3', TRUE):set_running(false)
      iter:get_window():lookup('flow4', TRUE):set_running(false)
      Timer.remove(liquid_flow_tm_id)
      liquid_flow_tm_id = 0
    end)
  elseif(str_contains(widget_name, 'btn_flow_start'))
  then
    iter:on(EventType.CLICK, function(evt)
      iter:get_window():lookup('gif_pump', TRUE):set_prop_str("image", "generatorTrue")
      iter:get_window():lookup('gif_boiler', TRUE):set_prop_str("image", "Boiler_Generic_Left_On")
      iter:get_window():lookup('flow1', TRUE):set_running(true)
      iter:get_window():lookup('flow2', TRUE):set_running(true)
      iter:get_window():lookup('flow3', TRUE):set_running(true)
      iter:get_window():lookup('flow4', TRUE):set_running(true)
      if liquid_flow_tm_id == 0 then 
          liquid_flow_tm_id = Timer.add(function(info) 
          local tank_name_v = "Tank_Fuel"..flow_tank_img_index
          iter:get_window():lookup('img_tank', TRUE):set_prop_str("image", tank_name_v)
          flow_tank_img_index = flow_tank_img_index - 1
          if flow_tank_img_index == 0 then
            flow_tank_img_index = 4
          end

          return Ret.REPEAT
        end, 2000)
      end
    end)  
  elseif(str_contains(widget_name, 'flow1') or str_contains(widget_name, 'flow2') or str_contains(widget_name, 'flow3') or str_contains(widget_name, 'flow4'))
  then
    iter:set_running(false)
    iter:set_forward(true)
    iter:set_update_delta(20)
    iter:set_update_interval(200)
  elseif(str_contains(widget_name, 'img_tank'))
  then
    iter:set_prop_str("image", "Tank_Fuel4")
  elseif(str_contains(widget_name, 'gif_pump'))
  then
    iter:set_prop_str("image", "generatorFalse")
  elseif(str_contains(widget_name, 'gif_boiler'))
  then
    iter:set_prop_str("image", "Boiler_Generic_Left_Off")
  end
  return Ret.OK
end

function home_page_init(iter) 
  local widget_name = iter.name;
  if(str_contains(widget_name, 'btn_qr'))
  then
    iter:on(EventType.CLICK, function(evt)
      win_qr_view = Window.open('win_qr_view')
      if win_qr_view ~= nil then
        win_qr_view:foreach(qr_view_init);
      end
    end)   
  elseif(str_contains(widget_name, 'btn_number_lab'))
  then
    iter:on(EventType.CLICK, function(evt)
      win_number_lab = Window.open('win_number_lab')
      if win_number_lab ~= nil then
        win_number_lab:lookup('close', TRUE):on(EventType.CLICK, function(evt)
          win_number_lab:close()
          win_number_lab = nil
          return Ret.OK
        end)   
      end
    end)   
  elseif(str_contains(widget_name, 'btn_select'))
  then
    iter:on(EventType.CLICK, function(evt)
      win_text_select = Window.open('win_text_select')
      if win_text_select ~= nil then
        datetime = DateTime.create()
        win_text_select:foreach(win_text_select_init)
      end
    end)   
  elseif(str_contains(widget_name, 'btn_trh_view'))
  then
    iter:on(EventType.CLICK, function(evt)
      win_trh_view = Window.open('win_trh_view')
      if win_trh_view ~= nil then
        win_trh_view:foreach(win_trh_view_init)
      end
    end)
  elseif(str_contains(widget_name, 'btn_image_anim'))
  then
    iter:on(EventType.CLICK, function(evt)
      win_image_anim = Window.open('win_image_anim')
      if win_image_anim ~= nil then
        win_image_anim:lookup('close', TRUE):on(EventType.CLICK, function(evt)
          win_image_anim:close()
          win_image_anim = nil
          return Ret.OK
        end) 
      end
    end)   
  elseif(str_contains(widget_name, 'btn_grid'))
  then
    iter:on(EventType.CLICK, function(evt)
      win_grid = Window.open('win_grid')
      if win_grid ~= nil then
        win_grid:lookup('close', TRUE):on(EventType.CLICK, function(evt)
          win_grid:close()
          win_grid = nil
          return Ret.OK
        end)
      end
    end)   
  elseif(str_contains(widget_name, 'btn_time_clock'))
  then
    iter:on(EventType.CLICK, function(evt)
      win_time_clock = Window.open('win_time_clock')
      if win_time_clock ~= nil then
        win_time_clock:lookup('close', TRUE):on(EventType.CLICK, function(evt)
          win_time_clock:close()
          win_time_clock = nil
          return Ret.OK
        end)
      end
    end)   
  elseif(str_contains(widget_name, 'btn_check'))
  then
    iter:on(EventType.CLICK, function(evt)
      win_check_btn = Window.open('win_check_btn')
      if win_check_btn ~= nil then
        if timer_id ~= 0 then
          Timer.remove(timer_id)
          timer_id = 0
        end
        win_check_btn:foreach(win_check_btn_init)
      end
    end) 
  elseif(str_contains(widget_name, 'btn_buton'))
  then
    iter:on(EventType.CLICK, function(evt)
      win_btn = Window.open('win_btn')
      if win_btn ~= nil then
        win_btn:foreach(win_btn_init)
      end
    end)   
  elseif(str_contains(widget_name, 'btn_chart_view'))
  then
    iter:on(EventType.CLICK, function(evt)
      win_chart_view = Window.open('win_chart_view')
      if win_chart_view ~= nil then
        win_chart_view:foreach(chart_view_init)
      end
    end)    
  elseif(str_contains(widget_name, 'btn_gauge'))
  then
    iter:on(EventType.CLICK, function(evt)
      win_gauge = Window.open('win_gauge')
      if win_gauge ~= nil then
        win_gauge:foreach(win_gauge_init)
      end
    end)    
  elseif(str_contains(widget_name, 'btn_sscom'))
  then
    iter:on(EventType.CLICK, function(evt)
      win_sscom = Window.open('win_sscom')
      if win_sscom ~= nil then
        win_sscom:foreach(win_sscom_init)
      end
    end)    
  elseif(str_contains(widget_name, 'btn_gesture_lock'))
  then
    iter:on(EventType.CLICK, function(evt)
      win_gesture_lock = Window.open('win_gesture_lock')
      if win_gesture_lock ~= nil then
        win_gesture_lock:foreach(win_gesture_lock_init)
      end
    end)   
  elseif(str_contains(widget_name, 'btn_pro_circle'))
  then
    iter:on(EventType.CLICK, function(evt)
      win_pro_circle = Window.open('win_pro_circle')
      if win_pro_circle ~= nil then
        win_pro_circle:foreach(win_pro_circle_init)
      end
    end) 
  elseif(str_contains(widget_name, 'btn_radio_btn'))
  then
    iter:on(EventType.CLICK, function(evt)
      win_radio_btn = Window.open('win_radio_btn')
      if win_radio_btn ~= nil then
        win_radio_btn:foreach(win_radio_btn_init)
      end
    end)  
  elseif(str_contains(widget_name, 'btn_vlabel'))
  then
    iter:on(EventType.CLICK, function(evt)
      win_vlabel = Window.open('win_vlabel')
      if win_vlabel ~= nil then
        win_vlabel:lookup('close', TRUE):on(EventType.CLICK, function(evt)
          win_vlabel:close()
          win_vlabel = nil
          return Ret.OK
        end)
      end
    end) 
  elseif(str_contains(widget_name, 'btn_slider_circle'))
  then
    iter:on(EventType.CLICK, function(evt)
      win_slider_circle = Window.open('win_slider_circle')
      if win_slider_circle ~= nil then
        win_slider_circle:foreach(win_slider_circle_init)
      end
    end) 
  elseif(str_contains(widget_name, 'btn_liquid_flow'))
  then
    iter:on(EventType.CLICK, function(evt)
      win_liquid_flow = Window.open('win_liquid_flow')
      if win_liquid_flow ~= nil then
        win_liquid_flow:foreach(win_liquid_flow_init)
      end
    end) 
  end
  
  return Ret.OK
end

function show_preload_res_window()
  local win = Window.open('win_preload')
  local interval =  math.ceil(1000 / #s_preload_res)
  local bar = win:lookup('progress_bar', TRUE)
  local total = #s_preload_res
  local finish = 0
  local bitmap = Bitmap.create()

  bar:set_value(10)

  Timer.add(function(info) 
    if(finish == total)
    then
      win_home_page = Window.open('win_home_page')
      if win_home_page ~= nil then
        win_home_page:foreach(home_page_init);
      end
      bitmap:destroy()

      return Ret.REMOVE
    else
      local type = s_preload_res[finish+1].type
      local name = s_preload_res[finish+1].name

      if(type == AssetType.IMAGE)
      then
        ImageManager.instance():get_bitmap(name, bitmap)
      end

      finish = finish + 1
      local value = finish * 100 / total

      bar:set_value(value)

      return Ret.REPEAT
    end
  end, interval)

end

function application_init()
  show_preload_res_window()
end

application_init()

工具详见网盘

链接: https://pan.baidu.com/s/10QYm-_fLMvVWYAPqLKJsBA?pwd=075g
提取码:075g

#3 Re: 全志 SOC » f1c100s awtk lua 串口屏之串口调试助手应用分享 » 2024-02-28 16:17:25

awtk设计器社区版就是需要以公司信息注册,然后就会定期送卷,专业版应该要收费。

知道大彩有lua脚本,没具体了解过,不知道具体有啥区别;)

#4 全志 SOC » f1c100s awtk lua 串口屏之串口调试助手应用分享 » 2024-02-28 10:34:09

tomyqg
回复: 4


一、产品简介

一款采用全志F1C100S芯片,运行国产实时操作系统RT-thread和ZLG 开源的AWTK  UI库开发的可使用lua(合宙Luatos)语言进行二次开发的串口

屏,双串口支持modbus rtu主从、dlt645 2007/1997、自由协议等。

二、应用场景

1.    常见的串口屏使用场景,如医疗、仪器仪表、工控、智能建筑等需要使用人机界面的场合。

2.    外扩modbus rtu io模块,可实现无纸记录仪的相关功能。

三、产品概述

本串口屏具备以下特点:

1.    支持双485(也可支持232及ttl串口)。
2.    支持modbus rtu主从。
3.    支持modbus rtu master转slave(有效解决HMI独占设备串口问题)。
4.    支持采集dlt645 1997/2007协议电表数据,并显示在界面上。
5.    支持dlt645 master转modbus rtu slave。
6.    支持数据、日志记录(csv或pdf格式记录,代替无纸记录仪功能,csv格式记录数据可在屏上直接查看,HMI内部nor flash可以记录最多1000条记
录,外接tf卡单文件可记录最多1,0000条记录, HMI外接modbus rtu io模块即可实现无纸记录仪功能,TF卡挂载日志型FAT文件系统,能有效避免
异常掉电造成的文件系统损坏问题)。
7.    外接充电宝,即可实现移动串口调试助手、modbus 调试助手等功能,方便产品现场调试。
8.    支持配方控件功能(需提前准备好配方数据)。
9.    支持google拼音输入法。
10.    支持多语言。
11.    支持丰富多样的系统控件、扩展控件、矢量字体、常见的图片格式(jpg、png、gif、svg等)。
12.    支持触摸和按键同时进行界面操作,或者无触摸只有按键(按键支持3键或5键模
式)。
具备独立的调试串口,方便脚本调试,其他UI特性参见AWTK相关介绍。

四、产品参数

1.    供电: 使用 USB 5V 供电或者外接5V供电。

2.    4.3寸 480x272或800x480分辨率IPS触摸屏(RTP或CTP)或不带触摸。

3.    16MB 大容量NOR FLASH,用户可用空间不低于10MB。

4.    Lua虚拟机可用内存2MB。

5.    ADC按键,支持3键或5键。

6.    工作温度范围:0-50度。

7.    TF卡:四线数据通信,支持容量最高可达64GB。

8.    串口:双485(也可支持232及ttl串口),RS485总线最多可接32个设备。

        波特率可支持:9600、19200、38400、115200

        奇偶校验支持:不校验、奇校验、偶校验

        数据位可支持:5位、6位、7位、8位

        停止位可支持:1个校验位、2个校验位


五、    使用说明
1.    搭建AWTK开发环境
详见网盘链接。
2.    采用社区版AWTK Designer进行界面设计
详见“AWTK_Designer用户手册.pdf”
3.    编写lua脚本,完成界面切换、更新,数据点位绑定等操作
Luatos相关API接口网盘链接。
HMI支持的Luatos库如下(除去LUA语言base 库外):
table、io、os、string、math、rtos、log、timer、sys、rtc、json、pack、uart、crypto、zbuff等
AWTK相关lua API参见相关文档
4.    界面资源及lua脚本上传到HMI
HMI界面资源可通过tf卡进行更新,将AWTK_Designer设计打包好的资源文件夹(设计器工程目录下的res文件夹),拷贝到tf卡根目录的ui文件
夹下,然后编辑资源更新配置文件(res_cfg.ini文件同样拷贝到ui文件夹下)。

最终ui文件夹如下所示,其中res文件夹存放界面资源(注意界面的图片资源要放到,这个路径下“\res\assets\default\raw\images\xx\“),
formulas文件夹存放配方数据模板,“main.lua”为系统脚本文件(可编译为字节码,如main.luac),”res_cfg.ini”为资源更新配置文件(资源可按需进行
更新)。

鼠标右键编辑“res_cfg.ini”,打开后如下所示:

ini文件分为[data]、[fonts]、[images]、[scripts]、[strings]、[styles]、[ui]、[formula]几大类型,其中数据项update可以控制该类资源是否进行更新
(update = 0不更新,update = 1更新),由于其他资源更新并不频繁,且数据量较小,所以每次都会进行全部更新操作,图片资源由于资源较大且
更新频繁,故实现了全部更新和指定文件进行更新的机制。[images]的update数据项为0时,会去解析该类下的其他数据项(如
image1=color.png …image50=…, 可以指定更新最多50张图片),数据项名称必须为“image+下标=image_name”(下标从1开始顺序排列,
该名称的图片必须位于\res\assets\default\raw\images\xx\目录下才会更新成功)格式,图片下标取值范围为1~50。编辑好相关文件后,将tf卡接入
HMI,然后按下HMI上的update按键,便会自动进行资源更新(开始更新时蜂鸣器会连叫两声提示开始更新),更新完成后蜂鸣器会连叫三声提示更新
完成。
注意:
                 更新数据途中请勿断电或重启(会造成FAT文件系统损坏),若出现文件统统损坏,则需要手动执行格式化命令(msh下执行: mkfs -t elm
elm_fat)。

六、测试视频

      测试视频演示了基本控件功能,同时通过modbus rtu绑点外接了一个温湿度传感器,完成传感器数据采集显示,并且将数据记录到csv文件中(存储
在TF卡上)及串口调试助手应用。

lua代码如下

PROJECT = "hmi_test"
VERSION = "1.0.0"

sys = require("sys")

local do_data = {0, 0, 0, 0, 0, 0, 0, 0}

local sfdb_info

local uart0_baud = 9600

local img_index = 0

local line_series_tm_id = 0

local bar_series_tm_id = 0

local gauge_tm_id = 0

local liquid_flow_tm_id = 0

local flow_tank_img_index = 4

local left_pointer_angle = -129

local right_pointer_angle = -129

local datetime = {0}

local data_queue = {}

local timer_id = 0

local trh_tm_id = 0

local temp_tm_id = 0

local period_send_tm = 0

s_preload_res = {
  {type = AssetType.IMAGE, name = "bg"},
  {type = AssetType.IMAGE, name = "bar_chart"},
  {type = AssetType.IMAGE, name = "button"},
  {type = AssetType.IMAGE, name = "chart_view"},
  {type = AssetType.IMAGE, name = "checkbox"},
  {type = AssetType.IMAGE, name = "clock_bg"},
  {type = AssetType.IMAGE, name = "clock_hour"},
  {type = AssetType.IMAGE, name = "clock_minute"},
  {type = AssetType.IMAGE, name = "clock_second"},
  {type = AssetType.IMAGE, name = "color_picker"},
  {type = AssetType.IMAGE, name = "coolingCoilFalse"},
  {type = AssetType.IMAGE, name = "fanRightFalse"},
  {type = AssetType.IMAGE, name = "damperV5"},
  {type = AssetType.IMAGE, name = "damperH5"},
  {type = AssetType.IMAGE, name = "filterV1"},
  {type = AssetType.IMAGE, name = "heatingCoilv2wRFalse"},
  {type = AssetType.IMAGE, name = "coolingCoilv2wRFalse"},
  {type = AssetType.IMAGE, name = "data_log"},
  {type = AssetType.IMAGE, name = "ductD"},
  {type = AssetType.IMAGE, name = "gesture_lock"},
  {type = AssetType.IMAGE, name = "grid"},
  {type = AssetType.IMAGE, name = "guage_bg_1"},
  {type = AssetType.IMAGE, name = "guage_bg_2"},
  {type = AssetType.IMAGE, name = "img_animation"},
  {type = AssetType.IMAGE, name = "log"},
  {type = AssetType.IMAGE, name = "meter"},
  {type = AssetType.IMAGE, name = "num_lab"},
  {type = AssetType.IMAGE, name = "progress_circle"},
  {type = AssetType.IMAGE, name = "qr_code"},
  {type = AssetType.IMAGE, name = "radio_button"},
  {type = AssetType.IMAGE, name = "slider_circle"},
  {type = AssetType.IMAGE, name = "text_select"},
  {type = AssetType.IMAGE, name = "time_clock"},
  {type = AssetType.IMAGE, name = "uiex_clock_bg"},
  {type = AssetType.IMAGE, name = "uiex_load1_bg"},
  {type = AssetType.IMAGE, name = "uiex_load2_bg"},
  {type = AssetType.IMAGE, name = "uiex_load1_loading"},
  {type = AssetType.IMAGE, name = "uiex_load2_loading"},
  {type = AssetType.IMAGE, name = "Tank_Fuel0"},
  {type = AssetType.IMAGE, name = "Tank_Fuel1"},
  {type = AssetType.IMAGE, name = "Tank_Fuel2"},
  {type = AssetType.IMAGE, name = "Tank_Fuel3"},
  {type = AssetType.IMAGE, name = "Tank_Fuel4"},
  {type = AssetType.IMAGE, name = "Tank_Water0"},
  {type = AssetType.IMAGE, name = "Tank_Water1"},
  {type = AssetType.IMAGE, name = "Tank_Water2"},
  {type = AssetType.IMAGE, name = "Tank_Water3"},
  {type = AssetType.IMAGE, name = "Tank_Water4"},
  {type = AssetType.IMAGE, name = "calendar"}
}

local TIME_PER_DIV = 2000        -- 每个DIV的持续时间
local SAMPLE_COUNT_PER_DIV = 10  -- 每个DIV的采样点数

local trh = 0

local temp = 0

local sscom_uart_cfg = {
  baudrate = 115200, databit = 8, stopbit = 1, paritybit = uart.NONE
}

local sscom_cfg = {
  hex_disp = 0, hex_send = 0, rx_to_file = 0, send_with_crc = 0, send_with_crlf = 0, cycle_send = 0, send_period = 100  
}

local sscom_rx = ""

local sscom_tx = ""

local sscom_rx_num = 0

local sscom_tx_num = 0

--**************************************************** 初始化系统参数 *******************************************************************
AppConf.init_ini("cfg")

if  AppConf.exist("sys.password") == false then
  AppConf.set_str("sys.password", "0124678")
end

local password = AppConf.get_str("sys.password", 0)
log.info("password", password)

if  AppConf.exist("sys.backlight") == false then
  AppConf.set_int("sys.backlight", 100)
end

local backlight = AppConf.get_int("sys.backlight", 80)
log.info("backlight", backlight)

if  AppConf.exist("sys.csv_idx") == false then
  AppConf.set_int("sys.csv_idx", 1)
end

local csv_idx = AppConf.get_int("sys.csv_idx", 1)
log.info("csv_idx", csv_idx)

if  AppConf.exist("sys.beepon") == false then
  AppConf.set_bool("sys.beepon", true)
end
local beepon = AppConf.get_bool("sys.beepon", true)

log.info("beepon", beepon)

if  AppConf.exist("sys.timeout") == false then
  AppConf.set_double("sys.timeout", 0)
end
local timeout = AppConf.get_double("sys.timeout", 0)
log.info("timeout", timeout)

if  AppConf.exist("sys.bootcnt") == false then
  AppConf.set_int("sys.bootcnt", 0)
end

local bootcnt = AppConf.get_int("sys.bootcnt", 0)
bootcnt = bootcnt + 1
AppConf.set_int("sys.bootcnt", bootcnt)
log.info("bootcnt", bootcnt)

local backlight = AppConf.get_int("sys.backlight", 80)
log.info("backlight", backlight)

AppConf.save()

--/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

--****************************************************modbus rtu master 绑点*************************************************************************
--[[

mdb.setup(1, 9600, 8, 1, mdb.NONE, mdb.LSB, 100)
mdb.add_tag(1, 6, mdb.MODBUS_FC_READ_INPUT_REGISTERS, 0, 2, "tag_co2")
mdb.add_tag(1, 6, mdb.MODBUS_FC_READ_INPUT_REGISTERS, 2, 2, "tag_co")
mdb.add_tag(1, 1, mdb.MODBUS_FC_READ_DISCRETE_INPUTS, 0, 8, "tag_di")
mdb.add_tag(1, 8, mdb.MODBUS_FC_READ_INPUT_REGISTERS, 0, 2, "tag_pm25_1")
mdb.add_tag(1, 9, mdb.MODBUS_FC_READ_INPUT_REGISTERS, 0, 2, "tag_pm25_2")
mdb.add_tag(1, 10, mdb.MODBUS_FC_READ_INPUT_REGISTERS, 0, 2, "tag_pm25_3")
mdb.add_tag(1, 11, mdb.MODBUS_FC_READ_INPUT_REGISTERS, 0, 2, "tag_pm25_4")
mdb.add_tag(1, 7, mdb.MODBUS_FC_WRITE_SINGLE_COIL, 0, 1, "tag_do1")
mdb.add_tag(1, 7, mdb.MODBUS_FC_WRITE_SINGLE_COIL, 1, 1, "tag_do2")
mdb.add_tag(1, 7, mdb.MODBUS_FC_WRITE_SINGLE_COIL, 2, 1, "tag_do3")
mdb.add_tag(1, 7, mdb.MODBUS_FC_WRITE_SINGLE_COIL, 3, 1, "tag_do4")
mdb.add_tag(1, 7, mdb.MODBUS_FC_WRITE_MULTIPLE_REGISTERS, 0, 2, "tag_ao1")
mdb.start(1)

]]
  
mdb.setup(0, 9600, 8, 1, mdb.NONE, mdb.LSB, 100)
mdb.add_tag(0, 1, mdb.MODBUS_FC_READ_HOLDING_REGISTERS, 0, 1, "tag_trh")
mdb.add_tag(0, 1, mdb.MODBUS_FC_READ_HOLDING_REGISTERS, 1, 1, "tag_temp")
mdb.start(0)

--****************************************************modbus rtu master 绑点,并转换为modbus rtu slave 点位,供外部其他设备调用*************************************************************************
--[[
--rtu master init uart1
mdb.setup(1, 9600, 8, 1, mdb.NONE, mdb.LSB, 100)

--rtu slave init uart0
mdb.setup_ex(0, 9600, 8, 1, mdb.NONE, mdb.LSB, 100, 1)

mdb.add_tag_ex(1, 0, 6, mdb.MODBUS_FC_READ_INPUT_REGISTERS, 0, 0, 2, mdb.btsw_badc, "tag_co2")
mdb.add_tag_ex(1, 0, 6, mdb.MODBUS_FC_READ_INPUT_REGISTERS, 2, 2, 2, mdb.btsw_badc, "tag_co")
mdb.add_tag_ex(1, 0, 1, mdb.MODBUS_FC_READ_DISCRETE_INPUTS, 0, 0, 8, mdb.btsw_badc, "tag_di")
mdb.add_tag_ex(1, 0, 8, mdb.MODBUS_FC_READ_INPUT_REGISTERS, 0, 0, 2, mdb.btsw_badc, "tag_pm25_1")
mdb.add_tag_ex(1, 0, 9, mdb.MODBUS_FC_READ_INPUT_REGISTERS, 0, 2, 2, mdb.btsw_badc, "tag_pm25_2")
mdb.add_tag_ex(1, 0, 10, mdb.MODBUS_FC_READ_INPUT_REGISTERS, 0, 4, 2, mdb.btsw_badc, "tag_pm25_3")
mdb.add_tag_ex(1, 0, 11, mdb.MODBUS_FC_READ_INPUT_REGISTERS, 0, 6, 2, mdb.btsw_badc, "tag_pm25_4")
mdb.add_tag_ex(1, 0, 7, mdb.MODBUS_FC_WRITE_SINGLE_COIL, 0, 0, 1, mdb.btsw_badc, "tag_do1")
mdb.add_tag_ex(1, 0, 7, mdb.MODBUS_FC_WRITE_SINGLE_COIL, 1, 1, 1, mdb.btsw_badc, "tag_do2")
mdb.add_tag_ex(1, 0, 7, mdb.MODBUS_FC_WRITE_SINGLE_COIL, 2, 2, 1, mdb.btsw_badc, "tag_do3")
mdb.add_tag_ex(1, 0, 7, mdb.MODBUS_FC_WRITE_SINGLE_COIL, 3, 3, 1, mdb.btsw_badc, "tag_do4")
mdb.add_tag_ex(1, 0, 7, mdb.MODBUS_FC_WRITE_MULTIPLE_REGISTERS, 0, 0, 2, mdb.btsw_badc, "tag_ao1")

mdb.start_ex(1, 0)
]]

--[[

--****************************************************dlt645 绑点*************************************************************************

dlt.setup(1, 9600, 8, 1, mdb.NONE, mdb.LSB, 100, 4)
--读A项电压
dlt.add_tag(1, {0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA}, dlt.DIC_2010100, dlt.DLT645_2007, "ch_a_voltage")
--读B项电压
dlt.add_tag(1, {0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA}, dlt.DIC_2010200, dlt.DLT645_2007, "ch_b_voltage")
--读C项电压
dlt.add_tag(1, {0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA}, dlt.DIC_2010300, dlt.DLT645_2007, "ch_c_voltage")
--读A项电流
dlt.add_tag(1, {0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA}, dlt.DIC_2020100, dlt.DLT645_2007, "ch_a_current")
--读B项电流
dlt.add_tag(1, {0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA}, dlt.DIC_2020200, dlt.DLT645_2007, "ch_b_current")
--读C项电流
dlt.add_tag(1, {0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA}, dlt.DIC_2020300, dlt.DLT645_2007, "ch_c_current")
--读正向有功总电能
dlt.add_tag(1, {0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA}, dlt.DIC_10000, dlt.DLT645_2007, "total_energy")

dlt.start(1)

]]

--注册串口1的数据接收通知函数
uart.on(1,"recv", function() sys.publish("UART1_RECEIVE") end)

-- rs232
uart.setup(1, sscom_uart_cfg.baudrate, sscom_uart_cfg.databit, sscom_uart_cfg.stopbit, sscom_uart_cfg.paritybit)

local function uart_read()
  local cacheData = ""

  while true do
      local s = uart.read(1,1)
      if s == "" then
          if not sys.waitUntil("UART1_RECEIVE",  math.ceil(35000/sscom_uart_cfg.baudrate)) then
              local data_len = cacheData:len()
              if data_len > 0 then
                  if win_sscom ~= nil then
                    sscom_rx_num = sscom_rx_num + data_len
                    win_sscom:lookup('rx_num', TRUE):set_text(string.format("%d", sscom_rx_num))
                    sscom_rx = cacheData
                    local data,_ = string.toHex(cacheData, " ")
                    local rx_txt = to_str(win_sscom:lookup('mledit_rx', TRUE):get_text())

                    --大于4K自动清屏
                    if rx_txt:len() > 4096 then
                      win_sscom:lookup('mledit_rx', TRUE):set_text("")
                    end

                    --log.info("rx_txt", rx_txt:len())
                    if sscom_cfg.hex_disp == 1 then
                      data ="\r\nRX: "..data
                      win_sscom:lookup('mledit_rx', TRUE):insert_text(rx_txt:len(), data)
                      rx_txt = to_str(win_sscom:lookup('mledit_rx', TRUE):get_text())
                      --win_sscom:lookup('mledit_rx', TRUE):insert_text(rx_txt:len(), "\r\n")
                    else
                      sscom_rx ="\r\nRX: "..sscom_rx
                      win_sscom:lookup('mledit_rx', TRUE):insert_text(rx_txt:len(), sscom_rx)
                    end

                    local virtual_size = ScrollBar.cast(win_sscom:lookup('mledit_rx', TRUE).scroll_bar_d).virtual_size
                    win_sscom:lookup('mledit_rx', TRUE).scroll_bar_d:set_value(virtual_size)

                    --大于4K自动清屏
                    rx_txt = to_str(win_sscom:lookup('mledit_rx', TRUE):get_text())
                    if rx_txt:len() > 4096 then
                      win_sscom:lookup('mledit_rx', TRUE):set_text("")
                    end
                  end
                  
                  cacheData = ""
                  data = ""
                  sscom_rx = ""

              end
          end
      else
          cacheData = cacheData..s
      end
  end
end

--***************************************************UI界面更新及切换**************************************************************

function str_contains(str, substr) 
  local s, e = string.find(str, substr);

  return s ~= nil;
end

function qr_view_init(iter) 
  local widget_name = iter.name;
  if(str_contains(widget_name, 'btn_update_qr'))
  then
    iter:on(EventType.CLICK, function(evt)
      local qr_data = win_qr_view:lookup('edit_qr_data', TRUE):get_text()
      if qr_data ~= nil then
          win_qr_view:lookup('qr', TRUE):set_value(to_str(qr_data))
      end
    end)
  elseif(str_contains(widget_name, 'close'))
  then
    iter:on(EventType.CLICK, function(evt)
      win_qr_view:close()
      win_qr_view = nil
      return Ret.OK
    end)
  end
  return Ret.OK
end

function win_line_series_parall_init(iter) 
  local widget_name = iter.name;
  if(str_contains(widget_name, 'new_graph'))
  then
    iter:on(EventType.CLICK, function(evt)
      local count = win_line_series_parall:lookup('chartview', TRUE):get_series_capacity_min()
      win_line_series_parall:lookup('chartview', TRUE):on_series_rset_float_data(count)
    end)
  elseif(str_contains(widget_name, 'line'))
  then
    iter:on(EventType.CLICK, function(evt)
      win_line_series_parall:lookup('chartview', TRUE):on_series_prop_changed(WidgetProp.SERIES_PROP_LINE_SHOW, "line", "line", "line_select")
      return Ret.OK
    end)
  elseif(str_contains(widget_name, 'area'))
  then
    iter:on(EventType.CLICK, function(evt)
      win_line_series_parall:lookup('chartview', TRUE):on_series_prop_changed(WidgetProp.SERIES_PROP_LINE_AREA_SHOW, "area", "area", "area_select")
      return Ret.OK
    end)
  elseif(str_contains(widget_name, 'symbol'))
  then
    iter:on(EventType.CLICK, function(evt)
      win_line_series_parall:lookup('chartview', TRUE):on_series_prop_changed(WidgetProp.SERIES_PROP_SYMBOL_SHOW, "symbol", "symbol", "symbol_select")
      return Ret.OK
    end)
  elseif(str_contains(widget_name, 'smooth'))
  then
    iter:on(EventType.CLICK, function(evt)
      win_line_series_parall:lookup('chartview', TRUE):on_series_prop_changed(WidgetProp.SERIES_PROP_LINE_SMOOTH, "smooth", "smooth", "smooth_select")
      return Ret.OK
    end)
  elseif(str_contains(widget_name, 'close'))
  then
    iter:on(EventType.CLICK, function(evt)
      Timer.remove(line_series_tm_id)
      line_series_tm_id = 0
      win_line_series_parall:close()
      win_line_series_parall = nil
      return Ret.OK
    end)
  end
  return Ret.OK
end

function win_bar_series_parall_init(iter) 
  local widget_name = iter.name;
  if(str_contains(widget_name, 'close'))
  then
    iter:on(EventType.CLICK, function(evt)
      Timer.remove(bar_series_tm_id)
      bar_series_tm_id = 0
      win_bar_series_parall:close()
      win_bar_series_parall = nil
      return Ret.OK
    end)
  end
  return Ret.OK
end

function line_series_push_rand_float_data(info)
  local ch_a = {1.23,2.3,2.3,2.3,2.3,2.3,2.3,2.3,2.3}
  local ch_b = {1.23,2.3,2.3,2.3,2.3,2.3,2.3,2.3,2.3}
  local ch_c = {1.23,2.3,2.3,2.3,2.3,2.3,2.3,2.3,2.3}

  for i=1,SAMPLE_COUNT_PER_DIV do
    ch_a[i] = math.random(160, 260)
    ch_b[i] = math.random(160, 260)
    ch_c[i] = math.random(160, 260)
  end 

  win_line_series_parall:lookup('chartview', TRUE):on_series_push_data("s1", TIME_PER_DIV, SAMPLE_COUNT_PER_DIV, SAMPLE_COUNT_PER_DIV, ch_a, 0)
  win_line_series_parall:lookup('chartview', TRUE):on_series_push_data("s2", TIME_PER_DIV, SAMPLE_COUNT_PER_DIV, SAMPLE_COUNT_PER_DIV, ch_b, 0)
  win_line_series_parall:lookup('chartview', TRUE):on_series_push_data("s3", TIME_PER_DIV, SAMPLE_COUNT_PER_DIV, SAMPLE_COUNT_PER_DIV, ch_c, 1)

  return Ret.REPEAT
end

function bar_series_push_rand_float_data(info)
  local ch_a = {1.23,2.3,2.3,2.3,2.3,2.3,2.3,2.3,2.3}
  local ch_b = {1.23,2.3,2.3,2.3,2.3,2.3,2.3,2.3,2.3}
  local ch_c = {1.23,2.3,2.3,2.3,2.3,2.3,2.3,2.3,2.3}

  for i=1,SAMPLE_COUNT_PER_DIV do
    ch_a[i] = math.random(0, 260)
    ch_b[i] = math.random(0, 260)
    ch_c[i] = math.random(0, 260)
  end 

  win_bar_series_parall:lookup('chartview', TRUE):on_series_push_data("s1", TIME_PER_DIV, SAMPLE_COUNT_PER_DIV, SAMPLE_COUNT_PER_DIV, ch_a, 0)
  win_bar_series_parall:lookup('chartview', TRUE):on_series_push_data("s2", TIME_PER_DIV, SAMPLE_COUNT_PER_DIV, SAMPLE_COUNT_PER_DIV, ch_b, 0)
  win_bar_series_parall:lookup('chartview', TRUE):on_series_push_data("s3", TIME_PER_DIV, SAMPLE_COUNT_PER_DIV, SAMPLE_COUNT_PER_DIV, ch_c, 1)

  return Ret.REPEAT
end

function chart_view_init(iter) 
  local widget_name = iter.name;
  if(str_contains(widget_name, 'window_line_series_parall'))
  then
    iter:on(EventType.CLICK, function(evt)
      win_line_series_parall = Window.open('win_line_series_parall')

      if win_line_series_parall ~= nil then
        win_line_series_parall:lookup('chartview', TRUE):axis_time_init(TIME_PER_DIV, SAMPLE_COUNT_PER_DIV)
        win_line_series_parall:foreach(win_line_series_parall_init)
        
        if line_series_tm_id == 0 then
          line_series_tm_id = Timer.add(line_series_push_rand_float_data, TIME_PER_DIV)
        end
      end
    end)
  elseif(str_contains(widget_name, 'window_bar_series_parall'))
  then
    iter:on(EventType.CLICK, function(evt)
      win_bar_series_parall = Window.open('win_bar_series_parall')
      if win_bar_series_parall ~= nil then
        win_bar_series_parall:lookup('chartview', TRUE):axis_time_init(TIME_PER_DIV, SAMPLE_COUNT_PER_DIV)
        win_bar_series_parall:foreach(win_bar_series_parall_init)

        if bar_series_tm_id == 0 then
          bar_series_tm_id = Timer.add(bar_series_push_rand_float_data, TIME_PER_DIV)
        end
      end
    end)    
  elseif(str_contains(widget_name, 'close'))
  then
    iter:on(EventType.CLICK, function(evt)
      Timer.remove(bar_series_tm_id)
      bar_series_tm_id = 0
      win_chart_view:close()
      win_chart_view = nil
      return Ret.OK
    end)
  end
  return Ret.OK
end

function win_btn_init(iter) 
  local widget_name = iter.name;
  if(str_contains(widget_name, 'btn_lvl0'))
  then
    iter:on(EventType.CLICK, function(evt)
      win_btn:lookup('image_lvl', TRUE):set_prop_str("image", "Tank_Fuel0")
    end)
  elseif(str_contains(widget_name, 'btn_lvl1'))
  then
    iter:on(EventType.CLICK, function(evt)
      win_btn:lookup('image_lvl', TRUE):set_prop_str("image", "Tank_Fuel1")
    end)   
  elseif(str_contains(widget_name, 'btn_lvl2'))
  then
    iter:on(EventType.CLICK, function(evt)
      win_btn:lookup('image_lvl', TRUE):set_prop_str("image", "Tank_Fuel2")
    end)   
  elseif(str_contains(widget_name, 'btn_lvl3'))
  then
    iter:on(EventType.CLICK, function(evt)
      win_btn:lookup('image_lvl', TRUE):set_prop_str("image", "Tank_Fuel3")
    end)   
  elseif(str_contains(widget_name, 'btn_lvl4'))
  then
    iter:on(EventType.CLICK, function(evt)
      win_btn:lookup('image_lvl', TRUE):set_prop_str("image", "Tank_Fuel4")
    end)   
  elseif(str_contains(widget_name, 'close'))
  then
    iter:on(EventType.CLICK, function(evt)
      win_btn:close()
      win_btn = nil
      return Ret.OK
    end)
  end

  return Ret.OK
end

function timer_hvac(info)
  local t1 
  t1 = math.random(10,100)
  win_check_btn:lookup('number_label_t1', TRUE):set_value(t1);
  t1 = math.random(10,100)
  win_check_btn:lookup('number_label_t2', TRUE):set_value(t1);
  t1 = math.random(10,100)
  win_check_btn:lookup('number_label_t3', TRUE):set_value(t1);
  t1 = math.random(10,100)
  win_check_btn:lookup('number_label_t4', TRUE):set_value(t1);

  img_index = img_index + 1
  local str_name_v = "damperV"..img_index
  win_check_btn:lookup('gif_damper_v', TRUE):set_prop_str("image", str_name_v)
  local str_name_h = "damperH"..img_index
  win_check_btn:lookup('gif_damper_h', TRUE):set_prop_str("image", str_name_h)

  if img_index == 5 then
    img_index = 1
  end
  
  return Ret.REPEAT
end

function win_check_btn_init(iter)
  local widget_name = iter.name;
  if(str_contains(widget_name, 'btn_check_btn'))
  then
    iter:on(EventType.CLICK, function(evt)
      fan_check_btn = iter:get_value()
      if fan_check_btn == 1 then
        win_check_btn:lookup('gif_fan_r', TRUE):set_prop_str("image", "fanRightTrue")
        if timer_id == 0 then
          timer_id = Timer.add(timer_hvac, 2000)
        end
      else
        win_check_btn:lookup('gif_fan_r', TRUE):set_prop_str("image", "fanRightFalse")
        Timer.remove(timer_id)
        timer_id = 0
      end
    end)
  elseif(str_contains(widget_name, 'slider_set'))
  then
    local set_point = iter:get_value()
    iter:get_window().lab_t_set:set_text(string.format("%d", set_point))
    
    iter:on(EventType.VALUE_CHANGING, function(evt)
      local set_point = iter:get_value()
      iter:get_window().lab_t_set:set_text(string.format("%d", set_point))
    end) 
  elseif(str_contains(widget_name, 'close'))
  then
    iter:on(EventType.CLICK, function(evt)
      win_check_btn:close()
      win_check_btn = nil
      return Ret.OK
    end)
  end
  return Ret.OK
end

function on_gauge_set_angle(info)
  left_pointer_angle = left_pointer_angle + 1
  right_pointer_angle = right_pointer_angle + 1

  --win_gauge:lookup('guage_l', TRUE):lookup('left_pointer', TRUE):set_angle(left_pointer_angle)
  --win_gauge:lookup('guage_r', TRUE):lookup('right_pointer', TRUE):set_angle(right_pointer_angle)

  local guage_pointer_l = win_gauge:lookup('guage_l', TRUE):lookup('left_pointer', TRUE)
  GaugePointer.cast(guage_pointer_l):set_angle(left_pointer_angle)

  --local guage_pointer_r = win_gauge:lookup('guage_r', TRUE):lookup('right_pointer', TRUE)
  --GaugePointer.cast(guage_pointer_r):set_angle(right_pointer_angle)


  if left_pointer_angle >= 128 then
    left_pointer_angle = -129
  end

  if right_pointer_angle >= 128 then
    right_pointer_angle = -129
  end

  return Ret.REPEAT
end

function win_gauge_init(iter)
  local widget_name = iter.name;
  if(str_contains(widget_name, 'btn_start'))
  then
    iter:on(EventType.CLICK, function(evt)
      if gauge_tm_id == 0 then
        gauge_tm_id = Timer.add(on_gauge_set_angle, 100)
      end
    end)
  elseif(str_contains(widget_name, 'btn_stop'))
  then
    iter:on(EventType.CLICK, function(evt)
      Timer.remove(gauge_tm_id)
      gauge_tm_id = 0
    end)   
  elseif(str_contains(widget_name, 'btn_close'))
  then
    iter:on(EventType.CLICK, function(evt)
      Timer.remove(gauge_tm_id)
      gauge_tm_id = 0
      win_gauge:close()
      win_gauge = nil
      return Ret.OK
    end)  
  end
  return Ret.OK
end

function baud_to_comb_index(in_baud)
  local uart_baud = tonumber(in_baud)
  if uart_baud == 2400 then
    combindx = 0
  elseif uart_baud == 4800 then
    combindx = 1
  elseif uart_baud == 9600 then
    combindx = 2
  elseif uart_baud == 14400 then
    combindx = 3
  elseif uart_baud == 19200 then
    combindx = 4
  elseif uart_baud == 38400 then
    combindx = 5
  elseif uart_baud == 56000 then
    combindx = 6
  elseif uart_baud == 57600 then
    combindx = 7
  elseif uart_baud == 115200 then
    combindx = 8
  elseif uart_baud == 128000 then
    combindx = 9
  elseif uart_baud == 230400 then
    combindx = 10
  elseif uart_baud == 256000 then
    combindx = 11
  end

  return combindx
end

function uart_period_send(info)
  local tx_txt = to_str(win_sscom:lookup('edit', TRUE):get_text())
  local rx_txt = to_str(win_sscom:lookup('mledit_rx', TRUE):get_text())    
  local tx_hex = string.fromHex(tx_txt) 
  local tx_disp = ''

  --大于4K自动清屏
  if rx_txt:len() > 4096 then
    win_sscom:lookup('mledit_rx', TRUE):set_text("")
  end

  if sscom_cfg.send_with_crc == 1 then
    local modbus_crc_data= pack.pack('<h', crypto.crc16("MODBUS",tx_hex))
    tx_hex = tx_hex..modbus_crc_data
    tx_disp ="\r\nTX: "..tx_txt..string.toHex(modbus_crc_data)
  else
    tx_disp ="\r\nTX: "..tx_txt
  end 

  win_sscom:lookup('mledit_rx', TRUE):insert_text(rx_txt:len(), tx_disp)
  local virtual_size = ScrollBar.cast(win_sscom:lookup('mledit_rx', TRUE).scroll_bar_d).virtual_size
  win_sscom:lookup('mledit_rx', TRUE).scroll_bar_d:set_value(virtual_size)

  if sscom_cfg.hex_send == 1 then
    --log.info("tx hex", tx_hex:len())
    sscom_tx_num = sscom_tx_num + tx_hex:len()
    win_sscom:lookup('tx_num', TRUE):set_text(string.format("%d", sscom_tx_num))
    uart.write(1, tx_hex, tx_hex:len())
  else
    if sscom_cfg.send_with_crlf == 1 then
      tx_txt = tx_txt.."\r\n"
    end
    sscom_tx_num = sscom_tx_num + tx_txt:len()
    win_sscom:lookup('tx_num', TRUE):set_text(string.format("%d", sscom_tx_num))
    --log.info("tx txt", tx_txt:len())
    uart.write(1, tx_txt, tx_txt:len())
  end

  --大于4K自动清屏
  rx_txt = to_str(win_sscom:lookup('mledit_rx', TRUE):get_text())
  if rx_txt:len() > 4096 then
    win_sscom:lookup('mledit_rx', TRUE):set_text("")
  end

  return Ret.REPEAT
end

function win_serial_setup_init(iter)
  local widget_name = iter.name
  if(str_contains(widget_name, 'comb_baud'))
  then
    iter:on(EventType.VALUE_CHANGED, function(evt)
      local baudrate = iter:get_text_value()
      --log.info("new baudrate", baudrate)
      sscom_uart_cfg.baudrate = baudrate
    end)  
  elseif(str_contains(widget_name, 'comb_databit'))
  then
    iter:on(EventType.VALUE_CHANGED, function(evt)
      local databit = iter:get_text_value()
      --log.info("new databit", databit)
      sscom_uart_cfg.databit = databit
    end)
  elseif(str_contains(widget_name, 'comb_stopbit'))
  then
    iter:on(EventType.VALUE_CHANGED, function(evt)
      local stopbit = iter:get_text_value()
      --log.info("new stopbit", stopbit)
      sscom_uart_cfg.stopbit = stopbit
    end)
  elseif(str_contains(widget_name, 'comb_parity'))
  then
    iter:on(EventType.VALUE_CHANGED, function(evt)
      local parity = iter:get_text_of_selected()
      --log.info("new parity", parity)
      if parity == 'none' then
        sscom_uart_cfg.paritybit = uart.NONE
      elseif parity == 'old' then
        sscom_uart_cfg.paritybit = uart.ODD
      elseif parity == 'even' then
        sscom_uart_cfg.paritybit = uart.EVEN
      end
    end)
  elseif(str_contains(widget_name, 'btn_set'))
  then
    iter:on(EventType.CLICK, function(evt)
      uart.setup(1, sscom_uart_cfg.baudrate, sscom_uart_cfg.databit, sscom_uart_cfg.stopbit, sscom_uart_cfg.paritybit)
      return Ret.OK
    end)
  elseif(str_contains(widget_name, 'btn_ret'))
  then
    iter:on(EventType.CLICK, function(evt)
      win_serial_setup:close()
      win_serial_setup = nil
      return Ret.OK
    end)
  end
  return Ret.OK
end


function win_sscom_init(iter)
  local widget_name = iter.name;
  if(str_contains(widget_name, 'chk_hex_disp'))
  then
    iter:on(EventType.CLICK, function(evt)
      chk_hex_disp = iter:get_value()
      if chk_hex_disp == 1 then
        sscom_cfg.hex_disp = 1
      else
        sscom_cfg.hex_disp = 0
      end
    end)
  elseif(str_contains(widget_name, 'comb_baud'))
  then
    --log.info("baud_to_comb_index", baud_to_comb_index(sscom_uart_cfg.baudrate), sscom_uart_cfg.baudrate)
    iter:set_selected_index(baud_to_comb_index(sscom_uart_cfg.baudrate))
    iter:on(EventType.VALUE_CHANGED, function(evt)
      local baudrate = iter:get_text_value()
      --log.info("new baudrate", baudrate)
      sscom_uart_cfg.baudrate = baudrate
      uart.setup(1, sscom_uart_cfg.baudrate, sscom_uart_cfg.databit, sscom_uart_cfg.stopbit, sscom_uart_cfg.paritybit)
    end)  
  elseif(str_contains(widget_name, 'btn_u_setup'))
  then
    iter:on(EventType.CLICK, function(evt)
      win_serial_setup = Window.open('win_serial_setup')
      if win_serial_setup ~= nil then
        win_serial_setup:foreach(win_serial_setup_init)
      end
    end) 
  elseif(str_contains(widget_name, 'chk_hex_snd'))
  then
    iter:on(EventType.CLICK, function(evt)
      chk_hex_snd = iter:get_value()
      if chk_hex_snd == 1 then
        sscom_cfg.hex_send = 1
      else
        sscom_cfg.hex_send = 0
      end
    end)  
  elseif(str_contains(widget_name, 'chk_add_parity'))
  then
    iter:on(EventType.CLICK, function(evt)
      chk_add_parity = iter:get_value()
      if chk_add_parity == 1 then
        sscom_cfg.send_with_crc = 1
      else
        sscom_cfg.send_with_crc = 0
      end
    end)
  elseif(str_contains(widget_name, 'chk_to_file'))
  then
    iter:on(EventType.CLICK, function(evt)
      chk_to_file = iter:get_value()
      if chk_to_file == 1 then
        sscom_cfg.rx_to_file = 1
      else
        sscom_cfg.rx_to_file = 0
      end
    end)
  elseif(str_contains(widget_name, 'chk_add_cr'))
  then
    iter:on(EventType.CLICK, function(evt)
      chk_add_cr = iter:get_value()
      if chk_add_cr == 1 then
        sscom_cfg.send_with_crlf = 1
      else
        sscom_cfg.send_with_crlf = 0
      end
    end)
  elseif(str_contains(widget_name, 'chk_snd_period'))
  then
    iter:on(EventType.CLICK, function(evt)
      chk_snd_period = iter:get_value()
      if chk_snd_period == 1 then
        sscom_cfg.cycle_send = 1
        sscom_cfg.send_period = win_sscom:lookup("sp_snd_period", TRUE):get_value_int()
        log.info("period send start", sscom_cfg.send_period)

        if period_send_tm == 0 then
          period_send_tm = Timer.add(uart_period_send, sscom_cfg.send_period)
        end
      else
        if period_send_tm > 0 then
          Timer.remove(period_send_tm)
          period_send_tm = 0
        end
        sscom_cfg.cycle_send = 0
        log.info("period send stop", sscom_cfg.send_period)
      end
    end)
  elseif(str_contains(widget_name, 'btn_clr_win'))
  then
    iter:on(EventType.CLICK, function(evt)
      win_sscom:lookup('mledit_rx', TRUE):set_text("")
      sscom_rx = ""
      sscom_rx_num = 0
      win_sscom:lookup('rx_num', TRUE):set_text("0")
      sscom_tx_num = 0
      win_sscom:lookup('tx_num', TRUE):set_text("0")
      return Ret.OK
    end)
  elseif(str_contains(widget_name, 'btn_clr_tx'))
  then
    iter:on(EventType.CLICK, function(evt)
      win_sscom:lookup('edit', TRUE):set_text("")
      sscom_tx = ""
      return Ret.OK
    end)
  elseif(str_contains(widget_name, 'btn_snd'))
  then
    iter:on(EventType.CLICK, function(evt)
      if sscom_cfg.cycle_send == 0 then
        local tx_txt = to_str(win_sscom:lookup('edit', TRUE):get_text())
        local tx_hex = string.fromHex(tx_txt) 
        local tx_disp = ''
        local rx_txt = to_str(win_sscom:lookup('mledit_rx', TRUE):get_text()) 

        --大于4K自动清屏
        if rx_txt:len() > 4096 then
          win_sscom:lookup('mledit_rx', TRUE):set_text("")
        end

        if sscom_cfg.send_with_crlf == 1 then
          tx_txt = tx_txt.."\r\n"
        end
        
        if sscom_cfg.send_with_crc == 1 then
          local modbus_crc_data= pack.pack('<h', crypto.crc16("MODBUS",tx_hex))
          tx_hex = tx_hex..modbus_crc_data
          tx_disp ="\r\nTX: "..tx_txt..string.toHex(modbus_crc_data)
        else
          tx_disp ="\r\nTX: "..tx_txt
        end

        win_sscom:lookup('mledit_rx', TRUE):insert_text(rx_txt:len(), tx_disp)
        local virtual_size = ScrollBar.cast(win_sscom:lookup('mledit_rx', TRUE).scroll_bar_d).virtual_size
        win_sscom:lookup('mledit_rx', TRUE).scroll_bar_d:set_value(virtual_size)

        if sscom_cfg.hex_send == 1 then
          --log.info("tx hex", tx_hex:len())
          sscom_tx_num = sscom_tx_num + tx_hex:len()
          win_sscom:lookup('tx_num', TRUE):set_text(string.format("%d", sscom_tx_num))
          uart.write(1, tx_hex, tx_hex:len())
        else
          --log.info("tx txt", tx_txt:len())
          sscom_tx_num = sscom_tx_num + tx_txt:len()
          win_sscom:lookup('tx_num', TRUE):set_text(string.format("%d", sscom_tx_num))
          uart.write(1, tx_txt, tx_txt:len())
        end
        --大于4K自动清屏
        rx_txt = to_str(win_sscom:lookup('mledit_rx', TRUE):get_text())
        if rx_txt:len() > 4096 then
          win_sscom:lookup('mledit_rx', TRUE):set_text("")
        end
      end
      return Ret.OK
    end)
  elseif(str_contains(widget_name, 'close'))
  then
    iter:on(EventType.CLICK, function(evt)
      if period_send_tm > 0 then
        Timer.remove(period_send_tm)
        sscom_cfg.cycle_send = 0
      end
      win_sscom:close()
      win_sscom = nil
      return Ret.OK
    end)
  end
  return Ret.OK
end

function win_gesture_lock_init(iter)
  local widget_name = iter.name;
  if(str_contains(widget_name, 'close'))
  then
    iter:on(EventType.CLICK, function(evt)
      win_gesture_lock:close()
      win_gesture_lock = nil
      return Ret.OK
    end)  
  elseif(str_contains(widget_name, 'gesture_lock_set'))
  then
    iter:on(EventType.VALUE_CHANGED, function(evt)
      local value = ValueChangeEvent.cast(evt).new_value
      local pass_input = Value.cast(value):str()

      log.info("password input ", pass_input)
      if password == pass_input then
        win_popup = Window.open('win_popup')
        win_popup.lab_pass_info:set_text("密码正确!")
        win_popup.btn_ret:on(EventType.CLICK, function(evt)
          win_popup:close()
          win_popup = nil
          return Ret.OK
        end)  
      else
        win_popup = Window.open('win_popup')
        win_popup.lab_pass_info:set_text("密码错误!")
        win_popup.btn_ret:on(EventType.CLICK, function(evt)
          win_popup:close()
          win_popup = nil
          return Ret.OK
        end)  
      end
      
      return Ret.REMOVE
    end)
  end
  return Ret.OK
end

function win_pro_circle_init(iter)
  local widget_name = iter.name;
  if(str_contains(widget_name, 'close'))
  then
    iter:on(EventType.CLICK, function(evt)
      iter:get_window():close()
      win_pro_circle = nil
      return Ret.OK
    end)  
  end
  return Ret.OK
end

function win_text_select_init(iter)
  local widget_name = iter.name
  if(str_contains(widget_name, 'close'))
  then
    iter:on(EventType.CLICK, function(evt)
      datetime:destroy()
      iter:get_window():close()
      win_text_select = nil
      return Ret.OK
    end)  
  elseif(str_contains(widget_name, 'text_selector_year'))
  then
    iter:set_selected_index(24)
  elseif(str_contains(widget_name, 'text_selector_mon'))
  then
    iter:set_selected_index(1)
  elseif(str_contains(widget_name, 'text_selector_day'))
  then
    iter:set_selected_index(17)
  elseif(str_contains(widget_name, 'text_selector_hour'))
  then
    iter:set_selected_index(12)
  elseif(str_contains(widget_name, 'text_selector_min'))
  then
    iter:set_selected_index(46)
  elseif(str_contains(widget_name, 'text_selector_sec'))
  then
    iter:set_selected_index(30)
  elseif(str_contains(widget_name, 'btn_time_set'))
  then
    iter:on(EventType.CLICK, function(evt)
      local year = iter:get_window():lookup('text_selector_year'):get_value_int()
      local month = iter:get_window():lookup('text_selector_mon'):get_value_int()
      local day = iter:get_window():lookup('text_selector_day'):get_value_int()
      local hour = iter:get_window():lookup('text_selector_hour'):get_value_int()
      local minute = iter:get_window():lookup('text_selector_min'):get_value_int()
      local second = iter:get_window():lookup('text_selector_sec'):get_value_int()

      datetime:set_year(year)
      datetime:set_month(month)
      datetime:set_day(day)
      datetime:set_hour(hour)
      datetime:set_minute(minute)
      datetime:set_second(second)
      datetime:set()
      
      return Ret.OK
    end) 
  end
  return Ret.OK
end

function win_slider_circle_init(iter)
  local widget_name = iter.name;
  if(str_contains(widget_name, 'close'))
  then
    iter:on(EventType.CLICK, function(evt)
      iter:get_window():close()
      win_slider_circle = nil
      return Ret.OK
    end)  
  elseif(str_contains(widget_name, 'slider_circle_l'))
  then
    iter:on(EventType.VALUE_CHANGING, function(evt)
      local vlab = iter:get_value()
      local v_txt = string.format("%d", vlab)
      iter:get_window():lookup('slider_circle_l', TRUE):lookup('value_l', TRUE):set_text(v_txt)
      return Ret.OK
    end) 
  elseif(str_contains(widget_name, 'slider_circle_r'))
  then
    iter:on(EventType.VALUE_CHANGING, function(evt)
      local vlab = iter:get_value()
      local v_txt = string.format("%d", vlab)
      iter:get_window():lookup('slider_circle_r', TRUE):lookup('value_r', TRUE):set_text(v_txt)
      return Ret.OK
    end) 
  end
  return Ret.OK
end

function win_radio_btn_init(iter)
  local widget_name = iter.name;
  if(str_contains(widget_name, 'close'))
  then
    iter:on(EventType.CLICK, function(evt)
      iter:get_window():close()
      win_radio_btn = nil
      return Ret.OK
    end)  
  end
  return Ret.OK
end


function win_temp_chart_view_init(iter) 
  local widget_name = iter.name;
  if(str_contains(widget_name, 'new_graph'))
  then
    iter:on(EventType.CLICK, function(evt)
      local count = win_temp_chart_view:lookup('chartview', TRUE):get_series_capacity_min()
      win_temp_chart_view:lookup('chartview', TRUE):on_series_rset_float_data(count)
    end)
  elseif(str_contains(widget_name, 'line'))
  then
    iter:on(EventType.CLICK, function(evt)
      win_temp_chart_view:lookup('chartview', TRUE):on_series_prop_changed(WidgetProp.SERIES_PROP_LINE_SHOW, "line", "line", "line_select")
      return Ret.OK
    end)
  elseif(str_contains(widget_name, 'area'))
  then
    iter:on(EventType.CLICK, function(evt)
      win_temp_chart_view:lookup('chartview', TRUE):on_series_prop_changed(WidgetProp.SERIES_PROP_LINE_AREA_SHOW, "area", "area", "area_select")
      return Ret.OK
    end)
  elseif(str_contains(widget_name, 'symbol'))
  then
    iter:on(EventType.CLICK, function(evt)
      win_temp_chart_view:lookup('chartview', TRUE):on_series_prop_changed(WidgetProp.SERIES_PROP_SYMBOL_SHOW, "symbol", "symbol", "symbol_select")
      return Ret.OK
    end)
  elseif(str_contains(widget_name, 'smooth'))
  then
    iter:on(EventType.CLICK, function(evt)
      win_temp_chart_view:lookup('chartview', TRUE):on_series_prop_changed(WidgetProp.SERIES_PROP_LINE_SMOOTH, "smooth", "smooth", "smooth_select")
      return Ret.OK
    end)
  elseif(str_contains(widget_name, 'close'))
  then
    iter:on(EventType.CLICK, function(evt)
      Timer.remove(temp_tm_id)
      temp_tm_id = 0
      win_temp_chart_view:close()
      win_temp_chart_view = nil
      return Ret.OK
    end)
  end
  return Ret.OK
end

function win_trh_chart_view_init(iter) 
  local widget_name = iter.name;
  if(str_contains(widget_name, 'new_graph'))
  then
    iter:on(EventType.CLICK, function(evt)
      local count = win_trh_chart_view:lookup('chartview', TRUE):get_series_capacity_min()
      win_trh_chart_view:lookup('chartview', TRUE):on_series_rset_float_data(count)
    end)
  elseif(str_contains(widget_name, 'line'))
  then
    iter:on(EventType.CLICK, function(evt)
      win_trh_chart_view:lookup('chartview', TRUE):on_series_prop_changed(WidgetProp.SERIES_PROP_LINE_SHOW, "line", "line", "line_select")
      return Ret.OK
    end)
  elseif(str_contains(widget_name, 'area'))
  then
    iter:on(EventType.CLICK, function(evt)
      win_trh_chart_view:lookup('chartview', TRUE):on_series_prop_changed(WidgetProp.SERIES_PROP_LINE_AREA_SHOW, "area", "area", "area_select")
      return Ret.OK
    end)
  elseif(str_contains(widget_name, 'symbol'))
  then
    iter:on(EventType.CLICK, function(evt)
      win_trh_chart_view:lookup('chartview', TRUE):on_series_prop_changed(WidgetProp.SERIES_PROP_SYMBOL_SHOW, "symbol", "symbol", "symbol_select")
      return Ret.OK
    end)
  elseif(str_contains(widget_name, 'smooth'))
  then
    iter:on(EventType.CLICK, function(evt)
      win_trh_chart_view:lookup('chartview', TRUE):on_series_prop_changed(WidgetProp.SERIES_PROP_LINE_SMOOTH, "smooth", "smooth", "smooth_select")
      return Ret.OK
    end)
  elseif(str_contains(widget_name, 'close'))
  then
    iter:on(EventType.CLICK, function(evt)
      Timer.remove(trh_tm_id)
      trh_tm_id = 0
      win_trh_chart_view:close()
      win_trh_chart_view = nil
      return Ret.OK
    end)
  end
  return Ret.OK
end

function temp_line_series_push_float_data(info)
  local temp_v = {0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0}

  for i=1,SAMPLE_COUNT_PER_DIV do
    local reg_temp = mdb.get_tag_data(0, 1, "tag_temp")
    if reg_temp[1] & 0x8000 > 0 then
      temp_v[i] = (~reg_temp[1] + 1)/10
    else
      temp_v[i] = reg_temp[1]/10
    end
  end 

  win_temp_chart_view:lookup('chartview', TRUE):on_series_push_data("s1", TIME_PER_DIV, SAMPLE_COUNT_PER_DIV, SAMPLE_COUNT_PER_DIV, temp_v, 1)

  return Ret.REPEAT
end

function trh_line_series_push_float_data(info)
  local trh_v = {0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0}

  for i=1,SAMPLE_COUNT_PER_DIV do
    local reg_trh = mdb.get_tag_data(0, 1, "tag_trh")
    trh_v[i] = reg_trh[1]/10
  end 

  win_trh_chart_view:lookup('chartview', TRUE):on_series_push_data("s1", TIME_PER_DIV, SAMPLE_COUNT_PER_DIV, SAMPLE_COUNT_PER_DIV, trh_v, 1)

  return Ret.REPEAT
end

function win_trh_view_init(iter)
  local widget_name = iter.name;
  if(str_contains(widget_name, 'close'))
  then
    iter:on(EventType.CLICK, function(evt)
      iter:get_window():close()
      win_trh_view = nil
      return Ret.OK
    end)  
  elseif(str_contains(widget_name, 'btn_temp_chart'))
  then
    iter:on(EventType.CLICK, function(evt)
      win_temp_chart_view = Window.open('win_temp_chart_view')

      if win_temp_chart_view ~= nil then
        win_temp_chart_view:lookup('chartview', TRUE):axis_time_init(TIME_PER_DIV, SAMPLE_COUNT_PER_DIV)
        win_temp_chart_view:foreach(win_temp_chart_view_init)
        
        if temp_tm_id == 0 then
          temp_tm_id = Timer.add(temp_line_series_push_float_data, TIME_PER_DIV)
        end
      end
    end)
  elseif(str_contains(widget_name, 'btn_trh_chart'))
  then
    iter:on(EventType.CLICK, function(evt)
      win_trh_chart_view = Window.open('win_trh_chart_view')

      if win_trh_chart_view ~= nil then
        win_trh_chart_view:lookup('chartview', TRUE):axis_time_init(TIME_PER_DIV, SAMPLE_COUNT_PER_DIV)
        win_trh_chart_view:foreach(win_trh_chart_view_init)
        
        if trh_tm_id == 0 then
          trh_tm_id = Timer.add(trh_line_series_push_float_data, TIME_PER_DIV)
        end
      end
    end)
  elseif(str_contains(widget_name, 'btn_trh_temp_data'))
  then
    iter:on(EventType.CLICK, function(evt)
      win_tt_data = Window.open('win_tt_data')

      if win_tt_data ~= nil then
        win_tt_data:lookup('close', TRUE):on(EventType.CLICK, function(evt)
          win_tt_data:close()
          win_tt_data = nil
          return Ret.OK
        end)
      end
    end)
  end
  return Ret.OK
end

function win_liquid_flow_init(iter)
  local widget_name = iter.name;
  if(str_contains(widget_name, 'close'))
  then
    iter:on(EventType.CLICK, function(evt)
      Timer.remove(liquid_flow_tm_id)
      liquid_flow_tm_id = 0
      flow_tank_img_index = 4
      iter:get_window():close()
      win_liquid_flow = nil
      return Ret.OK
    end)  
  elseif(str_contains(widget_name, 'btn_flow_stop'))
  then
    iter:on(EventType.CLICK, function(evt)
      iter:get_window():lookup('gif_pump', TRUE):set_prop_str("image", "generatorFalse")
      iter:get_window():lookup('gif_boiler', TRUE):set_prop_str("image", "Boiler_Generic_Left_Off")
      iter:get_window():lookup('flow1', TRUE):set_running(false)
      iter:get_window():lookup('flow2', TRUE):set_running(false)
      iter:get_window():lookup('flow3', TRUE):set_running(false)
      iter:get_window():lookup('flow4', TRUE):set_running(false)
      Timer.remove(liquid_flow_tm_id)
      liquid_flow_tm_id = 0
    end)
  elseif(str_contains(widget_name, 'btn_flow_start'))
  then
    iter:on(EventType.CLICK, function(evt)
      iter:get_window():lookup('gif_pump', TRUE):set_prop_str("image", "generatorTrue")
      iter:get_window():lookup('gif_boiler', TRUE):set_prop_str("image", "Boiler_Generic_Left_On")
      iter:get_window():lookup('flow1', TRUE):set_running(true)
      iter:get_window():lookup('flow2', TRUE):set_running(true)
      iter:get_window():lookup('flow3', TRUE):set_running(true)
      iter:get_window():lookup('flow4', TRUE):set_running(true)
      if liquid_flow_tm_id == 0 then 
          liquid_flow_tm_id = Timer.add(function(info) 
          local tank_name_v = "Tank_Fuel"..flow_tank_img_index
          iter:get_window():lookup('img_tank', TRUE):set_prop_str("image", tank_name_v)
          flow_tank_img_index = flow_tank_img_index - 1
          if flow_tank_img_index == 0 then
            flow_tank_img_index = 4
          end

          return Ret.REPEAT
        end, 2000)
      end
    end)  
  elseif(str_contains(widget_name, 'flow1') or str_contains(widget_name, 'flow2') or str_contains(widget_name, 'flow3') or str_contains(widget_name, 'flow4'))
  then
    iter:set_running(false)
    iter:set_forward(true)
    iter:set_update_delta(20)
    iter:set_update_interval(200)
  elseif(str_contains(widget_name, 'img_tank'))
  then
    iter:set_prop_str("image", "Tank_Fuel4")
  elseif(str_contains(widget_name, 'gif_pump'))
  then
    iter:set_prop_str("image", "generatorFalse")
  elseif(str_contains(widget_name, 'gif_boiler'))
  then
    iter:set_prop_str("image", "Boiler_Generic_Left_Off")
  end
  return Ret.OK
end

function home_page_init(iter) 
  local widget_name = iter.name;
  if(str_contains(widget_name, 'btn_qr'))
  then
    iter:on(EventType.CLICK, function(evt)
      win_qr_view = Window.open('win_qr_view')
      if win_qr_view ~= nil then
        win_qr_view:foreach(qr_view_init);
      end
    end)   
  elseif(str_contains(widget_name, 'btn_number_lab'))
  then
    iter:on(EventType.CLICK, function(evt)
      win_number_lab = Window.open('win_number_lab')
      if win_number_lab ~= nil then
        win_number_lab:lookup('close', TRUE):on(EventType.CLICK, function(evt)
          win_number_lab:close()
          win_number_lab = nil
          return Ret.OK
        end)   
      end
    end)   
  elseif(str_contains(widget_name, 'btn_select'))
  then
    iter:on(EventType.CLICK, function(evt)
      win_text_select = Window.open('win_text_select')
      if win_text_select ~= nil then
        datetime = DateTime.create()
        win_text_select:foreach(win_text_select_init)
      end
    end)   
  elseif(str_contains(widget_name, 'btn_trh_view'))
  then
    iter:on(EventType.CLICK, function(evt)
      win_trh_view = Window.open('win_trh_view')
      if win_trh_view ~= nil then
        win_trh_view:foreach(win_trh_view_init)
      end
    end)
  elseif(str_contains(widget_name, 'btn_image_anim'))
  then
    iter:on(EventType.CLICK, function(evt)
      win_image_anim = Window.open('win_image_anim')
      if win_image_anim ~= nil then
        win_image_anim:lookup('close', TRUE):on(EventType.CLICK, function(evt)
          win_image_anim:close()
          win_image_anim = nil
          return Ret.OK
        end) 
      end
    end)   
  elseif(str_contains(widget_name, 'btn_grid'))
  then
    iter:on(EventType.CLICK, function(evt)
      win_grid = Window.open('win_grid')
      if win_grid ~= nil then
        win_grid:lookup('close', TRUE):on(EventType.CLICK, function(evt)
          win_grid:close()
          win_grid = nil
          return Ret.OK
        end)
      end
    end)   
  elseif(str_contains(widget_name, 'btn_time_clock'))
  then
    iter:on(EventType.CLICK, function(evt)
      win_time_clock = Window.open('win_time_clock')
      if win_time_clock ~= nil then
        win_time_clock:lookup('close', TRUE):on(EventType.CLICK, function(evt)
          win_time_clock:close()
          win_time_clock = nil
          return Ret.OK
        end)
      end
    end)   
  elseif(str_contains(widget_name, 'btn_check'))
  then
    iter:on(EventType.CLICK, function(evt)
      win_check_btn = Window.open('win_check_btn')
      if win_check_btn ~= nil then
        if timer_id ~= 0 then
          Timer.remove(timer_id)
          timer_id = 0
        end
        win_check_btn:foreach(win_check_btn_init)
      end
    end) 
  elseif(str_contains(widget_name, 'btn_buton'))
  then
    iter:on(EventType.CLICK, function(evt)
      win_btn = Window.open('win_btn')
      if win_btn ~= nil then
        win_btn:foreach(win_btn_init)
      end
    end)   
  elseif(str_contains(widget_name, 'btn_chart_view'))
  then
    iter:on(EventType.CLICK, function(evt)
      win_chart_view = Window.open('win_chart_view')
      if win_chart_view ~= nil then
        win_chart_view:foreach(chart_view_init)
      end
    end)    
  elseif(str_contains(widget_name, 'btn_gauge'))
  then
    iter:on(EventType.CLICK, function(evt)
      win_gauge = Window.open('win_gauge')
      if win_gauge ~= nil then
        win_gauge:foreach(win_gauge_init)
      end
    end)    
  elseif(str_contains(widget_name, 'btn_sscom'))
  then
    iter:on(EventType.CLICK, function(evt)
      win_sscom = Window.open('win_sscom')
      if win_sscom ~= nil then
        win_sscom:foreach(win_sscom_init)
      end
    end)    
  elseif(str_contains(widget_name, 'btn_gesture_lock'))
  then
    iter:on(EventType.CLICK, function(evt)
      win_gesture_lock = Window.open('win_gesture_lock')
      if win_gesture_lock ~= nil then
        win_gesture_lock:foreach(win_gesture_lock_init)
      end
    end)   
  elseif(str_contains(widget_name, 'btn_pro_circle'))
  then
    iter:on(EventType.CLICK, function(evt)
      win_pro_circle = Window.open('win_pro_circle')
      if win_pro_circle ~= nil then
        win_pro_circle:foreach(win_pro_circle_init)
      end
    end) 
  elseif(str_contains(widget_name, 'btn_radio_btn'))
  then
    iter:on(EventType.CLICK, function(evt)
      win_radio_btn = Window.open('win_radio_btn')
      if win_radio_btn ~= nil then
        win_radio_btn:foreach(win_radio_btn_init)
      end
    end)  
  elseif(str_contains(widget_name, 'btn_vlabel'))
  then
    iter:on(EventType.CLICK, function(evt)
      win_vlabel = Window.open('win_vlabel')
      if win_vlabel ~= nil then
        win_vlabel:lookup('close', TRUE):on(EventType.CLICK, function(evt)
          win_vlabel:close()
          win_vlabel = nil
          return Ret.OK
        end)
      end
    end) 
  elseif(str_contains(widget_name, 'btn_slider_circle'))
  then
    iter:on(EventType.CLICK, function(evt)
      win_slider_circle = Window.open('win_slider_circle')
      if win_slider_circle ~= nil then
        win_slider_circle:foreach(win_slider_circle_init)
      end
    end) 
  elseif(str_contains(widget_name, 'btn_liquid_flow'))
  then
    iter:on(EventType.CLICK, function(evt)
      win_liquid_flow = Window.open('win_liquid_flow')
      if win_liquid_flow ~= nil then
        win_liquid_flow:foreach(win_liquid_flow_init)
      end
    end) 
  end
  
  return Ret.OK
end

function show_preload_res_window()
  local win = Window.open('win_preload')
  local interval =  math.ceil(1000 / #s_preload_res)
  local bar = win:lookup('progress_bar', TRUE)
  local total = #s_preload_res
  local finish = 0
  local bitmap = Bitmap.create()

  bar:set_value(10)

  Timer.add(function(info) 
    if(finish == total)
    then
      win_home_page = Window.open('win_home_page')
      if win_home_page ~= nil then
        win_home_page:foreach(home_page_init);
      end
      bitmap:destroy()

      return Ret.REMOVE
    else
      local type = s_preload_res[finish+1].type
      local name = s_preload_res[finish+1].name

      if(type == AssetType.IMAGE)
      then
        ImageManager.instance():get_bitmap(name, bitmap)
      end

      finish = finish + 1
      local value = finish * 100 / total

      bar:set_value(value)

      return Ret.REPEAT
    end
  end, interval)

end

function application_init()
  show_preload_res_window()
end

application_init()

sys.timerLoopStart(function() 

  --[[

  local a_v = dlt.get_tag_data(1, {0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA}, "ch_a_voltage")
  log.info("ch_a_voltage", a_v, " V")
  local b_v = dlt.get_tag_data(1, {0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA}, "ch_b_voltage")
  log.info("ch_b_voltage", b_v, " V")
  local c_v = dlt.get_tag_data(1, {0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA}, "ch_c_voltage")
  log.info("ch_c_voltage", c_v, " V")
  local a_a = dlt.get_tag_data(1, {0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA}, "ch_a_current")
  log.info("ch_a_current", a_a, " A")
  local b_a = dlt.get_tag_data(1, {0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA}, "ch_b_current")
  log.info("ch_b_current", b_a, " A")
  local c_a = dlt.get_tag_data(1, {0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA}, "ch_c_current")
  log.info("ch_c_current", c_a, " A")
  local p_all = dlt.get_tag_data(1, {0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA}, "total_energy")
  log.info("total_energy", p_all, " kw/h")

  ]]

  --local co2_regs = mdb.get_tag_data(1, 6, "tag_co2")

  --两个16位寄存器转flaot,高16位在前
  --local co2 = mdb.get_f32(co2_regs[1], co2_regs[2])
  --log.info("co2", co2, " ppm")
  --两个16位寄存器转flaot,低16位在前
  --co2 = mdb.get_f32le(co2_regs[1], co2_regs[2])
  --log.info("co2_1", co2, " ppm")

  --[[

  local co_regs = mdb.get_tag_data(1, 6, "tag_co")
  local co = mdb.get_f32(co_regs[1], co_regs[2])
  log.info("co", co, " ppm")

  local pm25_regs = mdb.get_tag_data(1, 8, "tag_pm25_1")
  local pm25 = mdb.get_f32(pm25_regs[1], pm25_regs[2])
  log.info("pm25_1", pm25, " mg/m3")

  pm25_regs = mdb.get_tag_data(1, 9, "tag_pm25_2")
  pm25 = mdb.get_f32(pm25_regs[1], pm25_regs[2])
  log.info("pm25_2", pm25, " mg/m3")

  pm25_regs = mdb.get_tag_data(1, 10, "tag_pm25_3")
  pm25 = mdb.get_f32(pm25_regs[1], pm25_regs[2])
  log.info("pm25_3", pm25, " mg/m3")

  pm25_regs = mdb.get_tag_data(1, 11, "tag_pm25_4")
  pm25 = mdb.get_f32(pm25_regs[1], pm25_regs[2])
  log.info("pm25_4", pm25, " mg/m3")

  local di_regs = mdb.get_tag_data(1, 1, "tag_di")
  log.info("di_regs1", di_regs[1])
  log.info("di_regs2", di_regs[2])
  log.info("di_regs3", di_regs[3])
  log.info("di_regs4", di_regs[4])
  log.info("di_regs5", di_regs[5])
  log.info("di_regs6", di_regs[6])
  log.info("di_regs7", di_regs[7])
  log.info("di_regs8", di_regs[8])

  if di_regs[1] > 0 then
    mdb.set_tag_data(1, 7, "tag_do1", {1})
  else
    mdb.set_tag_data(1, 7, "tag_do1", {0})
  end

  if di_regs[2] > 0 then
    mdb.set_tag_data(1, 7, "tag_do2", {1})
  else
    mdb.set_tag_data(1, 7, "tag_do2", {0})
  end

  if di_regs[3] > 0 then
    mdb.set_tag_data(1, 7, "tag_do3", {1})
  else
    mdb.set_tag_data(1, 7, "tag_do3", {0})
  end

  if di_regs[4] > 0 then
    mdb.set_tag_data(1, 7, "tag_do4", {1})
  else
    mdb.set_tag_data(1, 7, "tag_do4", {0})
  end

  local ao = math.random(10, 100) + math.random()
  --float转两个16位寄存器,高16位在前
  log.info("wr ao1 ", ao)

  local reg1,reg2 = mdb.set_f32(ao)
  mdb.set_tag_data(1, 7, "tag_ao1", {reg1, reg2})

  ]]
  
  local reg_trh = mdb.get_tag_data(0, 1, "tag_trh")
  trh = reg_trh[1]/10
  log.info("trh", trh, " %")
  local reg_temp = mdb.get_tag_data(0, 1, "tag_temp")
  if reg_temp[1] & 0x8000 > 0 then
    temp = (~reg_temp[1] + 1)/10
  else
    temp = reg_temp[1]/10
  end
  log.info("temp", temp, " C")

  if win_tt_data ~= nil then
    if reg_temp[1] & 0x8000 > 0 then
      win_tt_data:lookup('lab_dat_temp', TRUE):set_value(-temp)
    else
      win_tt_data:lookup('lab_dat_temp', TRUE):set_value(temp)
    end
    win_tt_data:lookup('lab_dat_trh', TRUE):set_value(trh)
  end

  --模拟数据
  local d1 = math.random(20, 500) + math.random()
  local d2 = math.random(10, 600) + math.random()
  local d3 = math.random(20, 500) + math.random()
  local d4 = math.random(10, 600) + math.random()
  local d5 = math.random(20, 500) + math.random()
  local d6 = math.random(10, 600) + math.random()
  local d7 = math.random(10, 600) + math.random()

  local data2save = {trh = 0.0, temp = 0.0, pm1 = 0.0, pm10 = 0.0, tvoc = 0.0, co2 = 0.0, ch2o = 0.0}
  data2save.trh = trh
  data2save.temp = temp
  data2save.pm1 = d3
  data2save.pm10 = d4
  data2save.tvoc = d5
  data2save.co2 = d6
  data2save.ch2o = d7

  table.insert(data_queue, data2save)

end, 1000)


sys.taskInit(function ()
  local line_idx = 1
  local page_idx = 1
  local file_idx = 1
  local pdfdoc = nil
  
  --初始化记录数据
  local csv_path = string.format("caq_data_%d.csv", csv_idx)
  sfdb_info = sfdb.read_info(sfdb.TF, csv_path)
  if sfdb_info then 
      log.info("record_index", "record_count", "record_len", "max_record_num", sfdb_info[1], sfdb_info[2], sfdb_info[3], sfdb_info[4])
      if sfdb_info[2] == 0 then
        sfdb.append(sfdb.TF, csv_path, "caq数据纪录")
        sfdb.append(sfdb.TF, csv_path, "trh,temp,pm1,pm10,tvoc,co2,ch2o")
      elseif sfdb_info[2] == 1000000 then
        csv_idx = csv_idx + 1
        csv_path = string.format("caq_data_%d.csv", csv_idx)
      end
  end

  while true do
    --存储缓存数据
    if #data_queue > 0 then

      for i=1,#data_queue do

        local data2save = {trh = 0.0, temp = 0.0, pm1 = 0.0, pm10 = 0.0, tvoc = 0.0, co2 = 0.0, ch2o = 0.0}
        data2save = table.remove(data_queue, 1)

        if data2save then
          if sfdb_info then
            --存满了,新建个文件
            if sfdb_info[2] == 1000000 then
              csv_idx = csv_idx + 1
              csv_path = string.format("caq_data_%d.csv", csv_idx)
              AppConf.set_int("sys.csv_idx", csv_idx)
              AppConf.save()
            end
          end
          local data_str = string.format("%.2f,%.2f,%.2f,%.2f,%.2f,%.2f,%.2f", data2save.trh, data2save.temp, data2save.pm1, data2save.pm10, data2save.tvoc, data2save.co2, data2save.ch2o)
          --sfdb.append(sfdb.TF, csv_path, data_str)
          --sfdb_info[2] = sfdb_info[2] + 1

          --[[
          --每10页新建一个pdf文档,减少单文档存储时间
          if page_idx == 10 then
            if line_idx == 32 then
              page_idx = 1
              line_idx = 1
              if pdfdoc then
                local pdf_path = string.format("/mmc/caq_data_%d_%d.pdf", bootcnt, file_idx)
                PDFgen.save(pdfdoc, pdf_path)
                PDFgen.destroy(pdfdoc)
                pdfdoc = nil
                log.info("save new pdfdoc")
              end
              file_idx = file_idx + 1
            end
          end

          if page_idx == 1 then
            if pdfdoc == nil then
              log.info("create new pdfdoc")
              pdfdoc = PDFgen.create(PdfPaper.A3_HEIGHT, PdfPaper.A3_WIDTH)
              PDFgen.set_font(pdfdoc, "Times-Roman")
              PDFgen.append_page(pdfdoc)
            end
          end

          if pdfdoc then
            --一页存32行数据
            if line_idx == 32 then
              PDFgen.append_page(pdfdoc)
              line_idx = 1
              page_idx = page_idx +1
            end
            local pdf_data_str = string.format("trh: %.2f, temp: %.2f, pm1: %.2f, pm10: %.2f, tvoc: %.2f, co2: %.2f, ch2o: %.2f", data2save.trh, data2save.temp, data2save.pm1, data2save.pm10, data2save.tvoc, data2save.co2, data2save.ch2o)
            PDFgen.add_text(pdfdoc, pdf_data_str, 16, 40, 800 - line_idx*24, FontColour.BLACK)
            line_idx = line_idx + 1
          end
          ]]
        end

        sys.wait(100)

      end

      --if pdfdoc then
      --  local pdf_path = string.format("/mmc/caq_data_%d_%d.pdf", bootcnt, file_idx)
      --  PDFgen.save(pdfdoc, pdf_path)
      --ends
      
    end

    log.info("lua", rtos.meminfo("lua"))
    log.info("sys", rtos.meminfo("sys"))

    sys.wait(10000)
  end

end)


--启动串口数据接收任务
sys.taskInit(uart_read)

-- 用户代码已结束---------------------------------------------
-- 结尾总是这一句
sys.run()
-- sys.run()之后后面不要加任何语句!!!!!

详细资料网盘链接

链接: https://pan.baidu.com/s/1crMS8zZnZXJiGJF4bH0xbg?pwd=26ar

提取码:26ar

#9 Re: 工业芯 匠芯创 » RISC-V高性能显示控制跨界MCU D13x系列Datasheet » 2023-11-14 23:40:03

海石生风 说:
tomyqg 说:

@海石生风
听说c906的浮点也是个残废啊

哪里道听途说的,RVV + FPU 的浮点性能怕是跟ARM9比得差两个量级

这里
https://github.com/revyos/revyos/issues/17

#12 全志 SOC » f1c200s awtk+luatos串口屏固件 » 2023-09-21 09:52:07

tomyqg
回复: 0

如题,此固件基于芒果r1加5寸 800x480电阻屏开发,串口屏开发步骤如下:

1.首先使用awtk设计器设计界面,完成后打包资源文件

2.将设计器工程目录下的res(删除掉inc目录及不需要的资源)文件夹拷贝到U盘或SD卡根目录的ui文件下

3.在lua脚本中完成界面切换及更新逻辑(目前只支持串口2 pe7/8 的modbus rtu主机模式进行点位绑定,为啥要用lua,当然是为了直接使用合宙现成的轮子啊),在vscode中完成main.lua脚本编辑后(utf8 模式进行脚本编辑,后期可编译成字节码运行,即main.luac),同样拷贝到U盘或SD卡根目录的ui目录中

4.将U盘或SD卡插到板子上进行ui更新(根据log提示,当提示更新完成需要复位时拔掉SD或U盘重启即可,只更新脚本时,可以将res文件夹删除或重命名)


这个方案比传统串口屏更灵活,比sdk开发模式更简单,各位大佬有啥建议啊

f1c200s_hmi_tool_20230921-1153.7z

#14 Re: ESP32/ESP8266 » 乐鑫要发的新芯片esp32-P4 » 2023-01-07 14:08:24

生态也很重要啊,软件支持不行,也是白搭

#15 Re: 上海航芯 » ACM32H5新产品需求及意见收集 » 2022-12-19 19:18:46

@海石生风

ch32v307正准备用,不知有啥坑不,集成的10M phy确实不错,就是flash有点小

#17 Re: 全志 SOC » SWMS4S LCD RGB565驱动 » 2022-11-03 19:00:55

他家咋不出个带以太网,内置sdram的片子啊,还有xip功能有待加强

#20 Re: 全志 SOC » t113跑lvgl帧率 » 2022-10-26 11:36:27

awtk在这上能跑多少fps啊?

#21 Re: 全志 SOC » t113跑lvgl帧率 » 2022-10-26 11:29:56

这是mipi接口的屏了吧,裸机mipi接口也搞好了?

#26 Re: 全志 SOC » 用 MSVC2017 编译 XFEL 项目 » 2021-06-17 09:27:53

没有sunxi-tools速度快(sunxi-tools:60多kB, xfel:40多kB),是哪里姿势不对吗

#27 Re: 全志 SOC » 用 MSVC2017 编译 XFEL 项目 » 2021-06-17 09:17:22

好的,我的固件有点大(>5M),我来试下下载速度

#28 Re: ESP32/ESP8266 » WT32-ETH01 WIFI+蓝牙 RJ45网关 二合一嵌入式以太网模块串口透传 » 2021-06-17 09:10:46

看来esp32用来搞个小网关(wifi和以太网同时开启)还挺合适的

#30 Re: 全志 SOC » 用 MSVC2017 编译 XFEL 项目 » 2021-06-17 08:56:46

听说这个支持f1c100s,试下下载速度如何

#31 Re: SigmaStar/SSD201/SSD202/SSD212 » 小伙伴们SigmaStar有自己的官方社区了 » 2021-04-02 16:54:19

你们的官方论坛成了方案商打广告的地方了,没啥有用的东西,还不如启明的微信群

#32 Re: 计算机图形/GUI/RTOS/FileSystem/OpenGL/DirectX/SDL2 » 自己做的样机,UI效果不错,实时系统openrtos » 2020-07-19 20:51:56

ite自己的ui,还有设计器提供啊,sdk还是用cmake编译吗,lz是代理?

#35 Re: 全志 SOC » f1c200s运行tina抖屏问题,请大家支支招 » 2020-06-12 09:40:29

2433a8f8c825c24769c0ceec075b30b.jpg我的触摸基本也OK了(他这个I2C跑100~200 k才可以),cache的话试着把FB的内存分配到写穿区域

#36 Re: 全志 SOC » f1c200s运行tina抖屏问题,请大家支支招 » 2020-06-11 20:46:13

抖屏的话就是调整DCLK,还有看下CACHE配置有无问题,白线那个他们技术支持说是要调整porch(我好像微调了下垂直v back porch),另外看你的触摸好着,他这个FT6336复位后就可以进行操作吗,我读出的坐标都不太对 :rolleyes

#38 Re: 全志 SOC » 潜水已久,发一个我玩的东西,开发板widora tiny200,系统rt-thread, 脚本lua » 2020-06-09 16:35:51

用了一下fastlz,3015824字节的程序压缩到1953184字节,几百ms就启动起来了  ^-^

#40 Re: 全志 SOC » f1c200s运行tina抖屏问题,请大家支支招 » 2020-06-01 20:57:51

我也在用他这个屏,我的DCLK设置到40M屏幕才不闪烁,但是开机画面下面有一段白线,主界面和你一样屏幕上边偶尔会有一条白线出现。(冠显他们自己的串口屏也是用F1C100s和这款屏,他们的DCLK设置的33M 没发现有啥异常)

#41 Re: 全志 SOC » 哇酷网友都乐于分享:为大家制作了F1C100s的RTX4+emWin5稳定项目! » 2020-04-28 17:32:45

sunxi-fel直接烧写SD卡还是等大佬来实现吧,至少需要搞定类似spi flash的这些驱动(编译成位置无关代码)

#43 Re: 全志 SOC » 哇酷网友都乐于分享:为大家制作了F1C100s的RTX4+emWin5稳定项目! » 2020-04-28 15:15:10

思路没问题就好了,USB从机论坛大神不是已经搞定了吗,研究下应该可以搞好。另外这个f1c100s-spl_uart0.bin是从其他工程编译出来的吗?

#44 Re: 全志 SOC » 哇酷网友都乐于分享:为大家制作了F1C100s的RTX4+emWin5稳定项目! » 2020-04-28 14:58:05

比如我想从SD NAND(贴片SD卡)里启动,要么在SD NAND 焊到板子上之前将程序烧进去,要么焊到板子上再烧程序上去,这时如果能将DRAM模拟成U盘,直接在电脑上将spl和app拖进去,然后将spl和app烧录进SD NAND,实现程序烧录

#45 Re: 全志 SOC » 哇酷网友都乐于分享:为大家制作了F1C100s的RTX4+emWin5稳定项目! » 2020-04-28 14:35:47

我的意思是这个f1c100s-spl_uart0.bin是从那个工程编译出来的,FELinside这个工程如果直接出来DRAM U盘就可以将spl和app文件写入SD卡,spl里面只要能读写SD卡就可以加载app了吧

#46 Re: 全志 SOC » 哇酷网友都乐于分享:为大家制作了F1C100s的RTX4+emWin5稳定项目! » 2020-04-28 14:18:05

洪工,这个spl(f1c100s-spl_uart0.bin)是那生成的啊,另外FELinside这个工程可以直接在DDR运行,后面如果加上usb dram U盘及SD驱动功能,是不是可以做SD NAND启动的SPL了啊

#48 Re: 全志 SOC » 有人知道100s的图层融合怎么用吗 » 2020-03-14 15:46:03

vmalloc 说:

f1c100虽然是16位色,但是每个像素仍然占用4个字节

f1c100可以565啊(一个像素两个字节,你必须要用32位色?),这样数据量减半,应该还有提升

#49 Re: 全志 SOC » 要做这样的一个东西,全志那个cpu比较合适?V3s? » 2020-03-12 16:20:23

staunchheart 说:

他有两个核心,然后选型比较多。
IT9864, 参考价USD2.9

联阳这个sdk做的可以,东西挺全的,设计器源码都有,文件系统用的还是hcc的

页脚

工信部备案:粤ICP备20025096号 Powered by FluxBB

感谢为中文互联网持续输出优质内容的各位老铁们。 QQ: 516333132, 微信(wechat): whycan_cn (哇酷网/挖坑网/填坑网) service@whycan.cn