前言
尝试通过lvgl的bar控件,显示mpu6050的xyz数值。
代码
主控代码
- 加载四个文件(lcd初始化,mpu初始化及参数获取,lvgl示例,mpu的cont内容)
- 初始化lcd/lvgl/cont/bar
- 循环中获取mpu6050数值,然后对数值进行处理
- 设置bar的数值
-- main.lua
--- 模块功能:gsensor- esp32_mpu6050
-- @module mpu6050
-- @author youkai
-- @release 2022.01.23
-- LuaTools需要PROJECT和VERSION这两个信息
PROJECT = "esp32_mpu6050"
VERSION = "1.0.0"
log.info("main", PROJECT, VERSION)
-- sys库是标配
_G.sys = require("sys")
require("esp32_st7735") --setup lcd
require("mpu6xxx_nolocal") --setup mpu6050
require("lvgl_demo")
require("mpucont")
--添加硬狗防止程序卡死
-- wdt.init(15000)--初始化watchdog设置为15s
-- sys.timerLoopStart(wdt.feed, 10000)--10s喂一次狗
-- ----------------setup start----------------------
-- 初始化屏幕
init_esp32_st7735 ()
init_lvgl()
-- ----------------setup end------------------------
-- ================main start================
sys.taskInit(function()
init_mpu6050() -- 有wait不能放在外面
init_mpu6050_cont()
-- si_x = init_mpu6050_slider_x()
-- si_y = init_mpu6050_slider_y()
-- si_z = init_mpu6050_slider_z()
sys.wait(1500)
init_bar("x")
init_bar("y")
init_bar("z")
while 1 do
temp_a = get_mpu6xxx_value()
-- get_mpu6xxx_value()
temp_x = set_bar_value(value_range[1][1],value_range[1][2],temp_a.x,"x")
temp_y = set_bar_value(value_range[2][1],value_range[2][2],temp_a.y,"y")
temp_z = set_bar_value(value_range[3][1],value_range[3][2],temp_a.z,"z")
-- log.info("temp_x",temp_x)
-- temp_x = set_slider_value(value_range[1][1],value_range[1][2],temp_a.x)
-- temp_y = set_slider_value(value_range[2][1],value_range[2][2],temp_a.y,"y")
-- temp_z = set_slider_value(value_range[3][1],value_range[3][2],temp_a.z)
-- lvgl.bar_set_value(barx["bar"], 0, lvgl.ANIM_OFF)
lvgl.bar_set_value(bar_list["x"]["bar"], temp_x, lvgl.ANIM_OFF)
lvgl.bar_set_value(bar_list["y"]["bar"], temp_y, lvgl.ANIM_OFF)
lvgl.bar_set_value(bar_list["z"]["bar"], temp_z, lvgl.ANIM_OFF)
-- lvgl.slider_set_value(si_x, temp_x, lvgl.ANIM_OFF)
-- lvgl.slider_set_value(si_y, temp_y, lvgl.ANIM_OFF)
-- lvgl.slider_set_value(si_z, temp_z, lvgl.ANIM_OFF)
-- log.debug("get-------",lvgl.slider_get_value(si_1))
-- log.info("layout update")
sys.wait(10)
end
end)
-- ================main end==================
sys.run()
官方提供的mpu6050的demo,修改一点。
-- mpu6xxx_nolocal.lua
--- 模块功能:mpu6xxx
-- @module mpu6xxx
-- @author Dozingfiretruck
-- @license MIT
-- @copyright OpenLuat.com
-- @release 2020.12.22
--支持mpu6500,mpu6050,mpu9250,icm2068g,icm20608d,自动判断器件id,只需要配置i2c id就可以
sys = require "sys"
--pm.wake("mpu6xxx")
i2cid = 0 --i2cid
i2cslaveaddr = MPU6XXX_ADDRESS_AD0_LOW
deviceid = MPU6050_WHO_AM_I
MPU6XXX_ADDRESS_AD0_LOW = 0x68 -- address pin low (GND), default for InvenSense evaluation board
MPU6XXX_ADDRESS_AD0_HIGH = 0x69 -- address pin high (VCC)
---器件通讯地址
MPU6050_WHO_AM_I = 0x68 -- mpu6050
MPU6500_WHO_AM_I = 0x70 -- mpu6500
MPU9250_WHO_AM_I = 0x71 -- mpu9250
ICM20608G_WHO_AM_I = 0xAF -- icm20608G
ICM20608D_WHO_AM_I = 0xAE -- icm20608D
MPU6XXX_ACCEL_SEN = 16384
MPU6XXX_GYRO_SEN = 1310
MPU60X0_TEMP_SEN = 340
MPU60X0_TEMP_OFFSET = 36.5
MPU6500_TEMP_SEN = 333.87
MPU6500_TEMP_OFFSET = 21
---MPU6XXX所用地址
MPU6XXX_RA_ACCEL_XOUT_H = 0x3B
MPU6XXX_RA_ACCEL_XOUT_L = 0x3C
MPU6XXX_RA_ACCEL_YOUT_H = 0x3D
MPU6XXX_RA_ACCEL_YOUT_L = 0x3E
MPU6XXX_RA_ACCEL_ZOUT_H = 0x3F
MPU6XXX_RA_ACCEL_ZOUT_L = 0x40
MPU6XXX_RA_TEMP_OUT_H = 0x41
MPU6XXX_RA_TEMP_OUT_L = 0x42
MPU6XXX_RA_GYRO_XOUT_H = 0x43
MPU6XXX_RA_GYRO_XOUT_L = 0x44
MPU6XXX_RA_GYRO_YOUT_H = 0x45
MPU6XXX_RA_GYRO_YOUT_L = 0x46
MPU6XXX_RA_GYRO_ZOUT_H = 0x47
MPU6XXX_RA_GYRO_ZOUT_L = 0x48
MPU6XXX_RA_SMPLRT_DIV = 0x19 --陀螺仪采样率,典型值:0x07(125Hz)
MPU6XXX_RA_CONFIG = 0x1A --低通滤波频率,典型值:0x06(5Hz)
MPU6XXX_RA_GYRO_CONFIG = 0x1B --陀螺仪自检及测量范围,典型值:0x18(不自检,2000deg/s)
MPU6XXX_RA_ACCEL_CONFIG = 0x1C --加速计自检、测量范围及高通滤波频率,典型值:0x01(不自检,2G,5Hz)
MPU6XXX_RA_FIFO_EN = 0x23 --fifo使能
MPU6XXX_RA_INT_PIN_CFG = 0x37 --int引脚有效电平
MPU6XXX_RA_INT_ENABLE = 0x38 --中断使能
MPU6XXX_RA_USER_CTRL = 0x6A
MPU6XXX_RA_PWR_MGMT_1 = 0x6B --电源管理,典型值:0x00(正常启用)
MPU6XXX_RA_PWR_MGMT_2 = 0x6C
MPU6XXX_RA_WHO_AM_I = 0x75
--器件ID检测
function mpu6xxx_check()
i2c.send(i2cid, MPU6XXX_ADDRESS_AD0_LOW, MPU6XXX_RA_WHO_AM_I)--读器件地址
sys.wait(50)
revData = i2c.recv(i2cid, MPU6XXX_ADDRESS_AD0_LOW, 1)
if revData:byte() ~= nil then
i2cslaveaddr = MPU6XXX_ADDRESS_AD0_LOW
else
i2c.send(i2cid, MPU6XXX_ADDRESS_AD0_HIGH, MPU6XXX_RA_WHO_AM_I)--读器件地址
sys.wait(50)
revData = i2c.recv(i2cid, MPU6XXX_ADDRESS_AD0_HIGH, 1)
if revData:byte() ~= nil then
i2cslaveaddr = MPU6XXX_ADDRESS_AD0_HIGH
else
log.info("i2c", "Can't find device")
return 1
end
end
i2c.send(i2cid, i2cslaveaddr, MPU6XXX_RA_WHO_AM_I)--读器件地址
sys.wait(50)
revData = i2c.recv(i2cid, i2cslaveaddr, 1)
log.info("Device i2c address is#:", revData:toHex())
if revData:byte() == MPU6050_WHO_AM_I then
deviceid = MPU6050_WHO_AM_I
log.info("Device i2c id is: MPU6050")
elseif revData:byte() == MPU6500_WHO_AM_I then
deviceid = MPU6500_WHO_AM_I
log.info("Device i2c id is: MPU6500")
elseif revData:byte() == MPU9250_WHO_AM_I then
deviceid = MPU9250_WHO_AM_I
log.info("Device i2c id is: MPU9250")
elseif revData:byte() == ICM20608G_WHO_AM_I then
deviceid = ICM20608G_WHO_AM_I
log.info("Device i2c id is: ICM20608G")
elseif revData:byte() == ICM20608D_WHO_AM_I then
deviceid = ICM20608D_WHO_AM_I
log.info("Device i2c id is: ICM20608D")
else
log.info("i2c", "Can't find device")
return 1
end
return 0
end
--器件初始化
function mpu6xxx_init()
i2c.send(i2cid, i2cslaveaddr, {MPU6XXX_RA_PWR_MGMT_1, 0x80})--复位
sys.wait(100)
i2c.send(i2cid, i2cslaveaddr, {MPU6XXX_RA_PWR_MGMT_1, 0x00})--唤醒
sys.wait(100)
i2c.send(i2cid, i2cslaveaddr, {MPU6XXX_RA_SMPLRT_DIV, 0x07})--陀螺仪采样率,典型值:0x07(125Hz)
i2c.send(i2cid, i2cslaveaddr, {MPU6XXX_RA_CONFIG, 0x06})--低通滤波频率,典型值:0x06(5Hz)
i2c.send(i2cid, i2cslaveaddr, {MPU6XXX_RA_GYRO_CONFIG, 0x18})--陀螺仪自检及测量范围,典型值:0x18(不自检,2000deg/s)
i2c.send(i2cid, i2cslaveaddr, {MPU6XXX_RA_ACCEL_CONFIG, 0x01})--加速计自检、测量范围及高通滤波频率,典型值:0x01(不自检,2G,5Hz)
--i2c.send(i2cid, i2cslaveaddr, {MPU6XXX_RA_FIFO_EN, 0x00})--关闭fifo
--i2c.send(i2cid, i2cslaveaddr, {MPU6XXX_RA_INT_ENABLE, 0x00})--关闭所有中断
--i2c.send(i2cid, i2cslaveaddr, {MPU6XXX_RA_USER_CTRL, 0x00})--I2C主模式关闭
i2c.send(i2cid, i2cslaveaddr, {MPU6XXX_RA_PWR_MGMT_1, 0x01})--设置x轴的pll为参考
i2c.send(i2cid, i2cslaveaddr, {MPU6XXX_RA_PWR_MGMT_2, 0x00})--加速度计与陀螺仪开启
log.info("i2c init_ok")
end
--获取温度的原始数据
function mpu6xxx_get_temp_raw()
i2c.send(i2cid, i2cslaveaddr,MPU6XXX_RA_TEMP_OUT_H)--获取的地址
buffer = i2c.recv(i2cid, i2cslaveaddr, 2)--获取2字节
temp = string.unpack(">h",buffer)
--log.info("get_temp_raw type: "..type(buffer).." hex: "..buffer:toHex().." temp: "..temp)
return temp or 0
end
--获取加速度计的原始数据
function mpu6xxx_get_accel_raw()
accel={x=nil,y=nil,z=nil}
i2c.send(i2cid, i2cslaveaddr,MPU6XXX_RA_ACCEL_XOUT_H)--获取的地址
x = i2c.recv(i2cid, i2cslaveaddr, 2)--获取6字节
accel.x = string.unpack(">h",x)
i2c.send(i2cid, i2cslaveaddr,MPU6XXX_RA_ACCEL_YOUT_H)--获取的地址
y = i2c.recv(i2cid, i2cslaveaddr, 2)--获取6字节
accel.y = string.unpack(">h",y)
i2c.send(i2cid, i2cslaveaddr,MPU6XXX_RA_ACCEL_ZOUT_H)--获取的地址
z = i2c.recv(i2cid, i2cslaveaddr, 2)--获取6字节
accel.z = string.unpack(">h",z)
--log.info("get_accel_raw: x="..x:toHex().." y="..y:toHex().." z="..z:toHex())
return accel or 0
end
--获取陀螺仪的原始数据
function mpu6xxx_get_gyro_raw()
gyro={x=nil,y=nil,z=nil}
i2c.send(i2cid, i2cslaveaddr,MPU6XXX_RA_GYRO_XOUT_H)--获取的地址
x = i2c.recv(i2cid, i2cslaveaddr, 2)--获取6字节
gyro.x = string.unpack(">h",x)
i2c.send(i2cid, i2cslaveaddr,MPU6XXX_RA_GYRO_YOUT_H)--获取的地址
y = i2c.recv(i2cid, i2cslaveaddr, 2)--获取6字节
gyro.y = string.unpack(">h",y)
i2c.send(i2cid, i2cslaveaddr,MPU6XXX_RA_GYRO_ZOUT_H)--获取的地址
z = i2c.recv(i2cid, i2cslaveaddr, 2)--获取6字节
gyro.z = string.unpack(">h",z)
return gyro or 0
end
--获取温度的原始数据
function mpu6xxx_get_temp()
temp=nil
tmp = mpu6xxx_get_temp_raw()
if deviceid == MPU6050_WHO_AM_I then
temp = tmp / MPU60X0_TEMP_SEN + MPU60X0_TEMP_OFFSET
else
temp = tmp / MPU6500_TEMP_SEN + MPU6500_TEMP_OFFSET
end
return temp
end
--获取加速度计的数据,单位: mg
function mpu6xxx_get_accel()
accel={x=nil,y=nil,z=nil}
tmp = mpu6xxx_get_accel_raw()
accel.x = tmp.x*1000/MPU6XXX_ACCEL_SEN
accel.y = tmp.y*1000/MPU6XXX_ACCEL_SEN
accel.z = tmp.z*1000/MPU6XXX_ACCEL_SEN
return accel
end
--获取陀螺仪的数据,单位: deg / 10s
function mpu6xxx_get_gyro()
gyro={x=nil,y=nil,z=nil}
tmp = mpu6xxx_get_gyro_raw()
gyro.x = tmp.x*100/MPU6XXX_GYRO_SEN
gyro.y = tmp.y*100/MPU6XXX_GYRO_SEN
gyro.z = tmp.z*100/MPU6XXX_GYRO_SEN
return gyro
end
function check_i2c()
if i2c.setup(i2cid,i2c.SLOW) ~= i2c.SLOW then
log.error("testI2c.init","fail")
return
end
if mpu6xxx_check()~= 0 then
return
end
end
function init_mpu6050()
log.info("init_mpu6050 start---------------")
sys.wait(1000)
check_i2c()
mpu6xxx_init()
log.info("init_mpu6050 end---------------")
-- -- judge value range
-- x_max =0
-- x_min =0
-- y_max =0
-- y_min =0
-- z_max =0
-- z_min =0
-- temp_a_ymax = 0
value_range = {{1100,-994},{1020,-1090},{1590,-1320}}
-- log.info(value_range[2][2])
end
-- judge value range
function judge_x(temp)
if temp > x_max then
x_max = temp
return
end
if temp < x_min then
x_min = temp
return
end
end
function judge_y(temp)
if temp > y_max then
y_max = temp
return
end
if temp < y_min then
y_min = temp
return
end
end
function judge_z(temp)
if temp > z_max then
z_max = temp
return
end
if temp < z_min then
z_min = temp
return
end
end
function get_mpu6xxx_value()
t = mpu6xxx_get_temp()
-- log.info("6050temptest", t)
a = mpu6xxx_get_accel()
-- log.info("6050acceltest", "accel.x",a.x,"accel.y",a.y,"accel.z",a.z)
g = mpu6xxx_get_gyro()
-- log.info("6050gyrotest", "gyro.x",g.x,"gyro.y",g.y,"gyro.z",g.z)
-- judge value range
-- judge_x(a.x)
-- judge_y(a.y)
-- judge_z(a.z)
-- log.info("x",x_max,x_min,"y",y_max,y_min,"z",z_max,z_min)
return a
end
创建cont和bar
-- mpucont.lua
function init_mpu6050_cont()
-- 初始化容器cont
--{
mpu6050_cont = lvgl.cont_create(lvgl.scr_act(), nil)
lvgl.obj_set_size(mpu6050_cont,128,160)
lvgl.obj_set_auto_realign(mpu6050_cont, true) --Auto realign when the size changes*/
lvgl.obj_align_origo(mpu6050_cont, nil, lvgl.ALIGN_IN_TOP_MID, 0, 0) --This parametrs will be sued when realigned*/
-- lvgl.cont_set_fit(mpu6050_cont, lvgl.FIT_TIGHT) --此时cont依据内容拓展,容易左右超过界限
-- lvgl.cont_set_fit(mpu6050_cont, lvgl.FIT_MAX)
lvgl.cont_set_fit(mpu6050_cont, lvgl.FIT_NONE) --此时cont未设置自适应状态,则内容在cont中
-- lvgl.cont_set_layout(mpu6050_cont, lvgl.LAYOUT_COLUMN_MID)--字符布局居中
-- lvgl.cont_set_layout(mpu6050_cont, lvgl.LAYOUT_COLUMN_LEFT) --布局靠左
--}
log.info("scr_load",lvgl.scr_load(mpu6050_cont)) --显示 容器
label_mpu = lvgl.label_create(mpu6050_cont,nil)
lvgl.label_set_text(label_mpu,"xyz accel value")
lvgl.obj_align(label_mpu, nil,lvgl.ALIGN_IN_TOP_MID,0,0)
return mpu6050_cont
end
-- x=1,y=2,z=3
bar_x_table = {}
bar_y_table = {}
bar_z_table = {}
bar_list = {}
bar_list["x"] = bar_x_table
bar_list["y"] = bar_y_table
bar_list["z"] = bar_z_table
function init_bar_x()
--初始化
--{
bar_x_table["bar"] = lvgl.bar_create(mpu6050_cont, nil) -- 创建进度条
lvgl.obj_set_size(bar_x_table["bar"], 115, 5) -- 设置尺寸
-- lvgl.obj_align(bar_x_table["bar"], NULL, lvgl.ALIGN_IN_TOP_MID, 0, 0)-- 设置位置居中
lvgl.obj_set_pos(bar_x_table["bar"], 5, 5)
--}
lvgl.bar_set_value(bar_x_table["bar"], 0, lvgl.ANIM_OFF)-- 设置加载到的值,默认范围为0-100
log.info("scr_load",lvgl.scr_load(bar_x_table["bar"])) --显示
bar_x_lab = lvgl.label_create(mpu6050_cont, nil)
-- lvgl.obj_set_size(bar_x_lab, 10, 10)
lvgl.label_set_text(bar_x_lab,"x")
-- lvgl.obj_set_auto_realign(bar_x_lab, true)
lvgl.obj_align(bar_x_lab, bar_x_table["bar"], lvgl.ALIGN_OUT_BOTTOM_MID, 0, 0)
-- lvgl.obj_set_pos(bar_x_lab,0,20)
-- lvgl.label_set_text(bar_x_lab,"x")
-- log.info("scr_load",lvgl.disp_load_scr(bar_x_lab))
-- log.info("scr_load",lvgl.scr_load(bar_x_lab))
-- range_bar_min_x= 0 -- bar最小值
-- range_bar_max_x =100 -- bar最大值
-- range_bar = range_bar_max_x - range_bar_min_x
bar_x_table["range_min"] = 0
bar_x_table["range_max"] = 100
lvgl.bar_set_range(bar_x_table["bar"], bar_x_table["range_min"],bar_x_table["range_max"])
-- log.info("x range",bar_x_table["range_min"],bar_x_table["range_max"])
-- log.info("x range",bar_list["x"]["range_min"],bar_list["x"]["range_max"])
-- bar_x_table["range_max"] = 1000
-- log.info("x range",bar_x_table["range_min"],bar_x_table["range_max"])
-- log.info("x range",bar_list["x"]["range_min"],bar_list["x"]["range_max"])
-- return bar_x_table
end
function init_bar(xyz)
--初始化
--{
bar_list[xyz]["bar"] = lvgl.bar_create(mpu6050_cont, nil) -- 创建进度条
lvgl.obj_set_size(bar_list[xyz]["bar"], 115, 5) -- 设置尺寸
-- lvgl.obj_align(bar_x_table["bar"], NULL, lvgl.ALIGN_IN_TOP_MID, 0, 0)-- 设置位置居中
if xyz == "x"then
lvgl.obj_set_pos(bar_list[xyz]["bar"], 5, 30)
elseif xyz == "y" then
lvgl.obj_set_pos(bar_list[xyz]["bar"], 5, 60)
elseif xyz == "z" then
lvgl.obj_set_pos(bar_list[xyz]["bar"], 5, 90)
end
--}
lvgl.bar_set_value(bar_list[xyz]["bar"], 0, lvgl.ANIM_OFF)-- 设置加载到的值,默认范围为0-100
bar_list[xyz]["label"] = lvgl.label_create(mpu6050_cont, nil)
lvgl.label_set_text(bar_list[xyz]["label"],xyz)
-- lvgl.obj_set_auto_realign(bar_x_lab, true)
lvgl.obj_align(bar_list[xyz]["label"], bar_list[xyz]["bar"], lvgl.ALIGN_OUT_BOTTOM_MID, 0, 0)
-- lvgl.obj_set_pos(bar_x_lab,0,20)
-- lvgl.label_set_text(bar_x_lab,"x")
-- log.info("scr_load",lvgl.disp_load_scr(bar_x_lab))
-- log.info("scr_load",lvgl.scr_load(bar_x_lab))
bar_list[xyz]["range_min"] = 0
bar_list[xyz]["range_max"] = 100
lvgl.bar_set_range(bar_list[xyz]["bar"], bar_list[xyz]["range_min"],bar_list[xyz]["range_max"])
end
function set_bar_value(range_max,range_min,value,xyz)
-- 这里的temp值是用于获取传感器的数值动态显示的
value_temp = value
value_range_min,value_range_max = range_max,range_min
value_temp2perc = (value_temp- value_range_min)/(value_range_max - value_range_min)
bar_list[xyz]["range_min"] = 0 -- xyz需要三种最小值,该函数无法兼容,先强制设定
value_perc2slider = math.floor(value_temp2perc * (bar_list[xyz]["range_max"]-bar_list[xyz]["range_min"]) + bar_list[xyz]["range_min"])
-- log.info(value_perc2slider)
return value_perc2slider
end
function init_mpu6050_slider_x()
--初始化
--{
slider_mpu6050_x = lvgl.slider_create(mpu6050_cont, nil) ---创建滑动条
lvgl.obj_set_size(slider_mpu6050_x, 100, 5) -- 设置尺寸
lvgl.obj_align(slider_mpu6050_x, nil, lvgl.ALIGN_CENTER, 0, -50)--设置居中
--}
range_slider_min_x= 0 -- slider最小值
range_slider_max_x =100 -- slider最大值
range_slider = range_slider_max_x - range_slider_min_x
lvgl.slider_set_range(slider_mpu6050_x, range_slider_min_x, range_slider_max_x) --设置范围,默认0-100
lvgl.slider_set_value(slider_mpu6050_x, 0, lvgl.ANIM_OFF)
log.info("scr_load",lvgl.scr_load(slider_mpu6050_x)) --显示
-- lvgl.slider_set_value(slider_mpu6050_x, 67, lvgl.ANIM_OFF)
log.info("lvgl demo: slider_mpu6050_x")
return slider_mpu6050_x
end
function init_mpu6050_slider_y()
--初始化
--{
slider_mpu6050_y = lvgl.slider_create(mpu6050_cont, nil) ---创建滑动条
lvgl.obj_set_size(slider_mpu6050_y, 100, 5) -- 设置尺寸
-- lvgl.obj_align(slider_mpu6050_y, nil, lvgl.ALIGN_CENTER, 0, 0)--设置居中
lvgl.obj_align(slider_mpu6050_y, slider_mpu6050_x, lvgl.ALIGN_OUT_BOTTOM_MID, 0, 50)--设置居中
--}
range_slider_min_y= 0 -- slider最小值
range_slider_max_y =100 -- slider最大值
range_slider = range_slider_max_y - range_slider_min_y
lvgl.slider_set_range(slider_mpu6050_y, range_slider_min_y, range_slider_max_y) --设置范围,默认0-100
lvgl.slider_set_value(slider_mpu6050_y, 0, lvgl.ANIM_OFF)
log.info("scr_load",lvgl.scr_load(slider_mpu6050_y)) --显示
-- lvgl.slider_set_value(slider_mpu6050_y, 67, lvgl.ANIM_OFF)
log.info("lvgl demo: slider_mpu6050_y")
return slider_mpu6050_y
end
function init_mpu6050_slider_z()
--初始化
--{
slider_mpu6050_z = lvgl.slider_create(mpu6050_cont, nil) ---创建滑动条
lvgl.obj_set_size(slider_mpu6050_z, 100, 5) -- 设置尺寸
lvgl.obj_align(slider_mpu6050_z, nil, lvgl.ALIGN_CENTER, 0, 50)--设置居中
--}
range_slider_min_z= 0 -- slider最小值
range_slider_max_z =100 -- slider最大值
range_slider = range_slider_max_z - range_slider_min_z
lvgl.slider_set_range(slider_mpu6050_z, range_slider_min_z, range_slider_max_z) --设置范围,默认0-100
lvgl.slider_set_value(slider_mpu6050_z, 0, lvgl.ANIM_OFF)
log.info("scr_load",lvgl.scr_load(slider_mpu6050_z)) --显示
-- lvgl.slider_set_value(slider_mpu6050_z, 67, lvgl.ANIM_OFF)
log.info("lvgl demo: slider_mpu6050_z")
return slider_mpu6050_z
end
-- function init_mpu6050_slider()
-- --初始化
-- --{
-- slider = lvgl.slider_create(lvgl.scr_act(), nil) ---创建滑动条
-- lvgl.obj_set_size(slider, 128, 5) -- 设置尺寸
-- lvgl.obj_align(slider, nil, lvgl.ALIGN_CENTER, 0, 0)--设置居中
-- --}
-- range_slider_min= 0 -- slider最小值
-- range_slider_max =100 -- slider最大值
-- range_slider = range_slider_max - range_slider_min
-- lvgl.slider_set_range(slider, range_slider_min, range_slider_max) --设置范围,默认0-100
-- lvgl.slider_set_value(slider, 0, lvgl.ANIM_OFF)
-- log.info("scr_load",lvgl.scr_load(slider)) --显示
-- -- lvgl.slider_set_value(slider, 67, lvgl.ANIM_OFF)
-- log.info("lvgl demo: slider")
-- end
function set_slider_value(range_max,range_min,value)
-- 这里的temp值是用于获取传感器的数值动态显示的
value_temp = value
value_range_min,value_range_max = range_max,range_min
value_temp2perc = (value_temp- value_range_min)/(value_range_max - value_range_min)
range_slider_min = 0 -- xyz需要三种最小值,该函数无法兼容,先强制设定
value_perc2slider = math.floor(value_temp2perc * range_slider + range_slider_min)
-- log.info(value_perc2slider)
return value_perc2slider
-- lvgl.slider_set_value(slider, value_perc2slider, lvgl.ANIM_OFF)
-- log.info("scr_load",lvgl.scr_load(slider)) --显示
-- value_temp = temp_value
-- value_range_min,value_range_max = 0,50
-- value_temp2perc = value_temp/(value_range_max - value_range_min)
-- value_perc2slider = value_temp2perc * range_slider + range_slider_min
-- lvgl.slider_set_value(slider, value_perc2slider, lvgl.ANIM_OFF) --直接设置不需要再执行scr_loadl
end
我基于官方教程整理的部分示例,这里只有lvgl_init用到了。其他的可以自己跑了熟悉一下lvgl
-- lvgl_demo.lua
--代码来源--https://doc.openluat.com/wiki/21?wiki_page_id=2561
-- 整理:youkai
-- 注意事项:部分函数中存在wait,需要在sys.taskInit中调用。
function init_lvgl()
LCD_W, LCD_H = 128,160
-- LCD_W, LCD_H = spi_lcd.getSize()
log.info("lcd", "size", LCD_W, LCD_H )
-- log.info(spi_lcd.w)
log.info("init lvgl")
-- log.info("lvgl", lvgl.init(128,160))
-- m = lvgl.init(128,160)
-- if ( m == true )
if ( lvgl.init(128,160) == true )
then
log.debug("lvgl init ok.")
else
log.debug("lvgl init error.")
end
end
function clear_lvgl()
-- lcd.clear(0xFFFFFF)
-- lcd.draw()
sys.wait(2000)
end
function arc()
-- 1. 初始化
--{
scr = lvgl.obj_create(nil, nil)
arc = lvgl.arc_create(scr, nil) -- 创建曲线
-- arc = lvgl.arc_create(lvgl.scr_act(), nil) -- 创建曲线
lvgl.obj_set_size(arc, 128, 128) -- 设置尺寸
lvgl.obj_align(arc, nil, lvgl.ALIGN_CENTER, 0, 0)-- 设置位置居中
-- 绘制弧度
-- lvgl.arc_set_end_angle(arc, 100)
-- }
-- -- 方法1:直接是设置固定角度
-- -- 绘制背景角度
-- lvgl.arc_set_bg_angles(arc, 0, 180) --背景0-180度
-- -- 绘制前景角度(填充的)
-- lvgl.arc_set_angles(arc, 0, 90) --前景0-90度
-- log.info("scr_load",lvgl.scr_load(arc))--显示
-- -- 方法2:设置背景角度后,设置背景范围,通过传入数值显示
-- lvgl.arc_set_bg_angles(arc, 150, 30) --背景0-180度
-- lvgl.arc_set_range(arc, 0, 100) --设置数值范围
-- lvgl.arc_set_value(arc, 30) --传入数值
-- log.info("scr_load",lvgl.scr_load(arc))--显示
-- 方法3:隔1s显示不同数值
lvgl.arc_set_bg_angles(arc, 150, 30) --背景0-180度
lvgl.arc_set_adjustable(arc, true) --允许输入
lvgl.arc_set_value(arc, 30) --传入数值
log.info("scr_load",lvgl.scr_load(arc))--显示
sys.wait(1000) -- 等1s传入新值
lvgl.arc_set_value(arc, 50) --传入数值
-- m = lvgl.scr_load(arc)
-- log.info(m)
log.info("scr_load",lvgl.scr_load(arc))
sys.wait(1000)
log.info("lvgl demo: arc")
-- -- test
-- y = 0
-- log.info(y)
-- -- temp_status = lvgl.obj_clean(scr)
-- -- temp_status = lvgl.obj_del(arc)
-- temp_status = lvgl.obj_clean(arc)
-- log.info(temp_status) --清除其内容
-- x = 1
-- log.info(x)
-- -- log.info("scr_load",lvgl.scr_load(arc))--显示
-- -- lvgl.obj_del(arc) --删除
end
-- arc()
function bar()
--初始化
--{
bar = lvgl.bar_create(lvgl.scr_act(), nil) -- 创建进度条
lvgl.obj_set_size(bar, 120, 5) -- 设置尺寸
lvgl.obj_align(bar, NULL, lvgl.ALIGN_CENTER, 0, 0)-- 设置位置居中
--}
--方法1:2s加载完
lvgl.bar_set_anim_time(bar, 2000) -- 设置加载完成时间
lvgl.bar_set_value(bar, 100, lvgl.ANIM_ON)-- 设置加载到的值,默认范围为0-100
log.info("scr_load",lvgl.scr_load(bar)) --显示
-- --方法2:设置范围为100-200,等待2s后开始加载,加载到150停止(中点)
-- lvgl.bar_set_range(bar, 100, 200) --设置范围
-- lvgl.bar_set_start_value(bar, 100, lvgl.ANIM_ON)-- 设置进度条起始值
-- sys.wait(2000)
-- lvgl.bar_set_anim_time(bar, 2000)-- 设置加载完成时间
-- lvgl.bar_set_value(bar, 150, lvgl.ANIM_ON)-- 设置加载到的值
-- log.info("scr_load",lvgl.scr_load(bar)) --显示
-- log.info("lvgl demo: bar")
-- sys.wait(1000)
-- lvgl.obj_clean(bar)
--lvgl.obj_del(bar) --删除
end
function slider()
--初始化
--{
slider = lvgl.slider_create(lvgl.scr_act(), nil) ---创建滑动条
lvgl.obj_set_size(slider, 128, 5) -- 设置尺寸
lvgl.obj_align(slider, nil, lvgl.ALIGN_CENTER, 0, 0)--设置居中
--}
-- --方法1:设置范围
-- lvgl.slider_set_range(slider, 100, 200) --设置范围,默认0-100
-- lvgl.slider_set_value(slider, 150, lvgl.ANIM_OFF)
-- log.info("scr_load",lvgl.scr_load(slider)) --显示
-- -- 方法2:3s滑动到中间
-- lvgl.slider_set_range(slider, 100, 200) --设置范围,默认0-100
-- lvgl.slider_set_anim_time(slider, 3000)-- 设置加载完成时间
-- lvgl.slider_set_value(slider, 150, lvgl.ANIM_ON)
-- log.info("scr_load",lvgl.scr_load(slider)) --显示
-- --方法3:设置回调函数显示滑动条数值 -- 未实现
-- slider_event_cb = function(obj, event)
-- log.info("enter event")
-- if event == lvgl.EVENT_VALUE_CHANGED then
-- local val = (lvgl.slider_get_value(obj) or "0").."%"
-- log.info("slider_get_value",string.toValue(str))
-- lvgl.label_set_text(slider_label, val)
-- lvgl.obj_align(slider_label, obj, lvgl.ALIGN_OUT_BOTTOM_MID, 0, 10)
-- log.info("scr_load",lvgl.scr_load(slider_label)) --显示
-- end
-- end
-- lvgl.obj_set_event_cb(slider, slider_event_cb) --设置事件监听
-- --创建标签,显示当前
-- slider_label = lvgl.label_create(lvgl.scr_act(), nil)
-- lvgl.label_set_text(slider_label, "0%")
-- lvgl.obj_align(slider_label, slider, lvgl.ALIGN_OUT_BOTTOM_MID, 0, 10)
-- log.info("scr_load",lvgl.scr_load(slider_label)) --显示
-- lvgl.slider_set_range(slider, 100, 200) --设置范围,默认0-100
-- lvgl.slider_set_anim_time(slider, 3000)-- 设置加载完成时间
-- lvgl.slider_set_value(slider, 150, lvgl.ANIM_ON)
-- log.info("scr_load",lvgl.scr_load(slider)) --显示
-- sys.wait(1000)
-- lvgl.slider_set_value(slider, 180, lvgl.ANIM_ON)
--存疑,定时滑动到中间,无法触发滑动事件变动?
-- -- --方法4:获取数据设置滑动条位置
-- range_slider_min= 100 -- slider最小值
-- range_slider_max =200 -- slider最大值
-- range_slider = range_slider_max - range_slider_min
-- -- 这里的temp值是用于获取传感器的数值动态显示的
-- value_temp = 10
-- value_range_min,value_range_max = 0,50
-- value_temp2perc = value_temp/(value_range_max - value_range_min)
-- value_perc2slider = value_temp2perc * range_slider + range_slider_min
-- lvgl.slider_set_range(slider, range_slider_min, range_slider_max) --设置范围,默认0-100
-- lvgl.slider_set_value(slider, value_perc2slider, lvgl.ANIM_OFF)
-- log.info("scr_load",lvgl.scr_load(slider)) --显示
-- sys.wait(2000)
-- lvgl.slider_set_value(slider, 180, lvgl.ANIM_OFF) --直接设置不需要再执行scr_loadl
--方法5:事件监听未实现,实现了设置变量数据
-- slider_event_cb = function(obj, event) -- error
-- log.info("slider event ")
-- if event == lvgl.EVENT_VALUE_CHANGED then
-- local val = (lvgl.slider_get_value(obj) or "0").."%"
-- lvgl.label_set_text(slider_label, val)
-- lvgl.obj_align(slider_label, obj, lvgl.ALIGN_OUT_BOTTOM_MID, 0, 10)
-- end
-- end
-- lvgl.obj_set_event_cb(slider, slider_event_cb)
slider_label = lvgl.label_create(lvgl.scr_act(), nil)
lvgl.label_set_text(slider_label, "0%")
lvgl.obj_align(slider_label, slider, lvgl.ALIGN_OUT_BOTTOM_MID, 0, 10)
range_slider_min= 100 -- slider最小值
range_slider_max =200 -- slider最大值
range_slider = range_slider_max - range_slider_min
-- 这里的temp值是用于获取传感器的数值动态显示的
value_temp = 10
value_range_min,value_range_max = 0,50
value_temp2perc = value_temp/(value_range_max - value_range_min)
value_perc2slider = value_temp2perc * range_slider + range_slider_min
lvgl.slider_set_range(slider, range_slider_min, range_slider_max) --设置范围,默认0-100
lvgl.slider_set_value(slider, value_perc2slider, lvgl.ANIM_OFF)
log.info("scr_load",lvgl.scr_load(slider)) --显示
sys.wait(2000)
lvgl.slider_set_value(slider, 180, lvgl.ANIM_OFF) --直接设置不需要再执行scr_loadl
-- lvgl.event_send
log.info("lvgl demo: slider")
sys.wait(1000)
-- lvgl.obj_clean(slider)
--lvgl.obj_del(slider) --删除,====error
end
symble = {
"\xef\x80\x81", "\xef\x80\x88", "\xef\x80\x8b", "\xef\x80\x8c",
"\xef\x80\x8d", "\xef\x80\x91", "\xef\x80\x93", "\xef\x80\x95",
"\xef\x80\x99", "\xef\x80\x9c", "\xef\x80\xa1", "\xef\x80\xa6",
"\xef\x80\xa7", "\xef\x80\xa8", "\xef\x80\xbe", "\xef\x8C\x84",
"\xef\x81\x88", "\xef\x81\x8b", "\xef\x81\x8c", "\xef\x81\x8d",
"\xef\x81\x91", "\xef\x81\x92", "\xef\x81\x93", "\xef\x81\x94",
"\xef\x81\xa7", "\xef\x81\xa8", "\xef\x81\xae", "\xef\x81\xb0",
"\xef\x81\xb1", "\xef\x81\xb4", "\xef\x81\xb7", "\xef\x81\xb8",
"\xef\x81\xb9", "\xef\x81\xbb", "\xef\x82\x93", "\xef\x82\x95",
"\xef\x83\x84", "\xef\x83\x85", "\xef\x83\x87", "\xef\x83\xa7",
"\xef\x83\xAA", "\xef\x83\xb3", "\xef\x84\x9c", "\xef\x84\xa4",
"\xef\x85\x9b", "\xef\x87\xab", "\xef\x89\x80", "\xef\x89\x81",
"\xef\x89\x82", "\xef\x89\x83", "\xef\x89\x84", "\xef\x8a\x87",
"\xef\x8a\x93", "\xef\x8B\xAD", "\xef\x95\x9A", "\xef\x9F\x82",
}
function img_symble()
-- 注意需要创建cont才能创建symble
-- 初始化容器cont
--{
local cont = lvgl.cont_create(lvgl.scr_act(), nil)
lvgl.obj_set_size(cont,128,160)
lvgl.obj_set_auto_realign(cont, true) --Auto realign when the size changes*/
lvgl.obj_align_origo(cont, nil, lvgl.ALIGN_CENTER, 0, 0) --This parametrs will be sued when realigned*/
-- lvgl.cont_set_fit(cont, lvgl.FIT_TIGHT) --此时cont依据内容拓展,容易左右超过界限
-- lvgl.cont_set_fit(cont, lvgl.FIT_MAX)
lvgl.cont_set_fit(cont, lvgl.FIT_NONE) --此时cont未设置自适应状态,则内容在cont中
-- lvgl.cont_set_layout(cont, lvgl.LAYOUT_COLUMN_MID)--字符布局居中
-- lvgl.cont_set_layout(cont, lvgl.LAYOUT_COLUMN_LEFT) --布局靠左
--}
log.info("scr_load",lvgl.scr_load(cont)) --显示。注意要显示的是cont而不是img
-- img = lvgl.img_create(cont, nil)
lvgl.cont_set_layout(cont, lvgl.LAYOUT_GRID)
for i=1, #symble do
img = lvgl.img_create(cont, nil)
lvgl.img_set_src(img, symble[i])
end
log.info("lvgl demo: img_symble")
sys.wait(3000)
-- lvgl.obj_clean(img)
--lvgl.obj_del(img) --删除
end
function img_png()
-- 初始化
--{
local cont = lvgl.cont_create(lvgl.scr_act(), nil)
lvgl.obj_set_size(cont,128,160)
lvgl.obj_set_auto_realign(cont, true) --Auto realign when the size changes*/
lvgl.obj_align_origo(cont, nil, lvgl.ALIGN_CENTER, 0, 0) --This parametrs will be sued when realigned*/
-- lvgl.cont_set_fit(cont, lvgl.FIT_TIGHT) --此时cont依据内容拓展,容易左右超过界限
-- lvgl.cont_set_fit(cont, lvgl.FIT_MAX)
lvgl.cont_set_fit(cont, lvgl.FIT_NONE) --此时cont未设置自适应状态,则内容在cont中
-- lvgl.cont_set_layout(cont, lvgl.LAYOUT_COLUMN_MID)--字符布局居中
-- lvgl.cont_set_layout(cont, lvgl.LAYOUT_COLUMN_LEFT) --布局靠左
--}
img = lvgl.img_create(cont, nil)-- 创建图片控件
lvgl.img_set_src(img, "/img/t2.png")-- 设置图片路径
lvgl.obj_align(img, nil, lvgl.ALIGN_CENTER, 0, 0)-- 图片居中
log.info("scr_load",lvgl.scr_load(cont)) --显示。注意要显示的是cont而不是img
sys.wait(1000)
lvgl.img_set_angle(img, 900)
end
function lvgl_img()
local scr = lvgl.obj_create()
local img = lvgl.img_create(scr,nil) --
lvgl.img_set_src(img, "/lua/luatos.png") --设置图片来源
lvgl.obj_align(img, lvgl.scr_act(), lvgl.ALIGN_CENTER, 0, 0) --图片居中
log.info("scr_load",lvgl.scr_load(cont))
log.info("lvgl demo: img_png")
end
--demo1
function img_png_demo()
-- local ui = lvgl.label_create(nil, nil)
-- lvgl.obj_set_size(ui,128,160)
-- local img1 = lvgl.img_create(ui, nil)
local img1 = lvgl.img_create(lvgl.scr_act(), nil)
lvgl.img_set_auto_size(img1, true)
lvgl.img_set_src(img1, "/img/test3.bmp")
-- lvgl.img_set_src(img2, _G.LV_SYMBOL_OK)--.."Accept"
lvgl.obj_align(img1, nil, lvgl.ALIGN_CENTER, 0, -20)
-- lvgl.obj_set_x(img1, 0)
-- lvgl.obj_set_y(img1, 0)
-- log.info("scr_load",lvgl.scr_load(ui)) --显示。注意要显示的是
log.info("scr_load",lvgl.scr_load(img1)) --显示。注意要显示的是
-- local img2 = lvgl.img_create(lvgl.scr_act(), nil)
-- lvgl.img_set_src(img2, LV_SYMBOL_OK.."Accept")
-- lvgl.obj_align(img2, img1, lvgl.ALIGN_OUT_BOTTOM_MID, 0, 20)
end
function cont()
-- 初始化容器cont
--{
local cont = lvgl.cont_create(lvgl.scr_act(), nil)
lvgl.obj_set_size(cont,128,160)
lvgl.obj_set_auto_realign(cont, true) --Auto realign when the size changes*/
lvgl.obj_align_origo(cont, nil, lvgl.ALIGN_CENTER, 0, 0) --This parametrs will be sued when realigned*/
-- lvgl.cont_set_fit(cont, lvgl.FIT_TIGHT) --此时cont依据内容拓展,容易左右超过界限
-- lvgl.cont_set_fit(cont, lvgl.FIT_MAX)
lvgl.cont_set_fit(cont, lvgl.FIT_NONE) --此时cont未设置自适应状态,则内容在cont中
-- lvgl.cont_set_layout(cont, lvgl.LAYOUT_COLUMN_MID)--字符布局居中
lvgl.cont_set_layout(cont, lvgl.LAYOUT_COLUMN_LEFT) --布局靠左
--}
--创建标签label
local label = lvgl.label_create(cont, nil)
lvgl.label_set_text(label, "Short text")
log.info("scr_load",lvgl.scr_load(cont)) --显示 容器
sys.wait(500)
label = lvgl.label_create(cont, nil)
lvgl.label_set_text(label, "It is a long text")
sys.wait(500)
label = lvgl.label_create(cont, nil)
lvgl.label_set_text(label, "Here is an even longer text")
end
注意事项
创建cont,用于存放三个bar,三个bar是基于cont创建的,所以显示只需要加载cont,其中的内容就会显示,不用再特意执行scr_load。
结果
【合宙-esp32c3】获取mpu6050数值通话lvgl的bar控件显示
小结
这里只是简单的获取了mpu6050数值以及实时显示,难度不高,主要是不熟悉lvgl花了很多时间。
后续再尝试在lcd屏幕上显示mpu的3D旋转效果。
预计实现参照:学习心得|基于卡尔曼滤波的MPU6050姿态解算