Просмотр исходного кода

add:添加exvib1扩展库和基于8000核心板的使用demo

mw 6 месяцев назад
Родитель
Сommit
201eeef0d4

+ 56 - 0
module/Air8000/demo/exvib1/README.md

@@ -0,0 +1,56 @@
+## 演示功能概述
+使用Air8000核心板,搭配AirVIBRATING_1000震动小板,演示滚珠震动传感器的使用
+本示例主要是展示exvib1库的使用:
+
+1,震动事件回调:当检测到震动时,会触发回调函数,在回调函数中可以进行相应的处理,例如打印日志、控制其他设备等。
+
+2,震动事件计数:在回调函数中可以统计检测到的震动次数,例如用于记录用户操作次数、触发报警等。
+
+3,震动事件过滤:可以设置过滤参数,例如设置最小震动时间间隔,避免重复触发回调。
+
+## 演示硬件环境
+
+1、Air8000核心板一块
+
+2、TYPE-C USB数据线一根
+
+3、AirVIBRATING_1000震动小板一块
+
+4、Air8000核心板和数据线的硬件接线方式为
+
+- Air8000核心板通过TYPE-C USB口供电;(核心板的拨钮开关拨到USB供电)
+
+- TYPE-C USB数据线直接插到核心板的TYPE-C USB座子,另外一端连接电脑USB口;
+
+5、AirVIBRATING_1000震动小板和Air8000核心板的硬件接线方式为
+
+- 震动小板的VCC引脚连接核心板的VDD_EXT引脚;
+
+- 震动小板的GND引脚连接核心板的GND_EXT引脚;
+
+- 震动小板的INT_BL2529引脚连接核心板的GPIO20引脚;
+
+## 演示软件环境
+
+1、Luatools下载调试工具
+
+2、[Air8000 V2014版本固件](https://docs.openluat.com/air8000/luatos/firmware/)
+
+## 演示核心步骤
+
+1、搭建好硬件环境
+
+2、通过Luatools将demo与固件烧录到核心板中
+
+3、烧录好后,板子开机将会在Luatools上看到如下打印:
+
+```lua
+[2025-09-09 13:51:51.417][000000000.584] I/user.Vibration start on gpio 20
+[2025-09-09 13:51:56.331][000000005.954] I/user.VIB detected! pulses = 7
+[2025-09-09 13:51:56.811][000000006.444] I/user.VIB detected! pulses = 3
+[2025-09-09 13:52:00.039][000000009.664] I/user.VIB detected! pulses = 5
+[2025-09-09 13:52:01.226][000000010.854] I/user.VIB detected! pulses = 3
+[2025-09-09 13:52:02.640][000000012.274] I/user.VIB detected! pulses = 3
+[2025-09-09 13:52:03.793][000000013.424] I/user.VIB detected! pulses = 3
+[2025-09-09 13:52:04.858][000000014.484] I/user.VIB detected! pulses = 4
+```

+ 63 - 0
module/Air8000/demo/exvib1/main.lua

@@ -0,0 +1,63 @@
+
+--[[
+@module  main
+@summary LuatOS用户应用脚本文件入口,总体调度应用逻辑
+@version 1.0
+@date    2025.09.5
+@author  孟伟
+@usage
+本demo演示的功能为:
+使用Air8000开发板,搭配AirVIBRATING_1000震动小板,演示滚珠震动传感器的使用
+本示例主要是展示exvib1库的使用:
+]]
+
+--[[
+必须定义PROJECT和VERSION变量,Luatools工具会用到这两个变量,远程升级功能也会用到这两个变量
+PROJECT:项目名,ascii string类型
+        可以随便定义,只要不使用,就行
+VERSION:项目版本号,ascii string类型
+        如果使用合宙iot.openluat.com进行远程升级,必须按照"XXX.YYY.ZZZ"三段格式定义:
+            X、Y、Z各表示1位数字,三个X表示的数字可以相同,也可以不同,同理三个Y和三个Z表示的数字也是可以相同,可以不同
+            因为历史原因,YYY这三位数字必须存在,但是没有任何用处,可以一直写为000
+        如果不使用合宙iot.openluat.com进行远程升级,根据自己项目的需求,自定义格式即可
+]]
+PROJECT = "vibration_test_demo"
+VERSION = "001.000.000"
+
+--添加硬狗防止程序卡死
+if wdt then
+    wdt.init(9000)--初始化watchdog设置为9s
+    sys.timerLoopStart(wdt.feed, 3000)--3s喂一次狗
+end
+
+-- 如果内核固件支持errDump功能,此处进行配置,【强烈建议打开此处的注释】
+-- 因为此功能模块可以记录并且上传脚本在运行过程中出现的语法错误或者其他自定义的错误信息,可以初步分析一些设备运行异常的问题
+-- 以下代码是最基本的用法,更复杂的用法可以详细阅读API说明文档
+-- 启动errDump日志存储并且上传功能,600秒上传一次
+-- if errDump then
+--     errDump.config(true, 600)
+-- end
+
+
+-- 使用LuatOS开发的任何一个项目,都强烈建议使用远程升级FOTA功能
+-- 可以使用合宙的iot.openluat.com平台进行远程升级
+-- 也可以使用客户自己搭建的平台进行远程升级
+-- 远程升级的详细用法,可以参考fota的demo进行使用
+
+
+-- 启动一个循环定时器
+-- 每隔3秒钟打印一次总内存,实时的已使用内存,历史最高的已使用内存情况
+-- 方便分析内存使用是否有异常
+-- sys.timerLoopStart(function()
+--     log.info("mem.lua", rtos.meminfo())
+--     log.info("mem.sys", rtos.meminfo("sys"))
+-- end, 3000)
+
+
+require"vibration_test"
+
+
+-- 用户代码已结束---------------------------------------------
+-- 结尾总是这一句
+sys.run()
+-- sys.run()之后后面不要加任何语句!!!!!

+ 22 - 0
module/Air8000/demo/exvib1/vibration_test.lua

@@ -0,0 +1,22 @@
+--[[
+@module  vibration_test
+@summary exvib1扩展库使用demo
+@version 1.0
+@date    2025.09.5
+@author  孟伟
+@usage
+本demo演示的功能为:
+使用Air8000开发板,搭配AirVIBRATING_1000震动小板,演示滚珠震动传感器的使用
+本示例主要是展示exvib1库的使用:
+]]
+local exvib1= require "exvib1"-- 自定义配置启动
+
+-- 震动事件回调
+local function vibration_cb(pulse_cnt)
+    log.info("VIB", "detected! pulses =", pulse_cnt)
+end
+--演示最简单的使用方法,都使用默认配置
+exvib1.open({
+    gpio_pin = 20,
+    on_event = vibration_cb,
+    })

+ 154 - 0
script/libs/exvib1.lua

@@ -0,0 +1,154 @@
+--[[
+@summary exvib1扩展库
+@version 1.0
+@date    2025.09.07
+@author  孟伟
+@usage
+-- 应用场景
+此库适用于滚珠震动传感器BL_2529,主要目的是对振动中断进行过滤,识别有效震动
+对于一些震动传感器的中断管脚算法处理,也可以用做参考。
+
+-- 用法实例
+本扩展库对外提供了以下2个接口:
+1)启动震动检测功能 exvib1.open(opts)
+2)停止震动检测功能 exvib1.close()
+
+--示例
+local exvib1= require "exvib1"-- 自定义配置启动
+
+-- 震动事件回调
+local function vibration_cb(pulse_cnt)
+    log.info("VIB", "detected! pulses =", pulse_cnt)
+end
+--演示最简单的使用方法,都使用默认配置
+exvib1.open({
+    gpio_pin = 24,
+    on_event = vibration_cb,
+})
+
+
+以下为exchg扩展库四个函数的详细说明及代码实现:
+]]
+
+local exvib1 = {}
+
+-- 默认配置
+local cfg = {
+    gpio_pin        = nil, -- 传感器中断所接 GPIO
+    pull            = gpio.PULLUP,
+    trigger         = gpio.RISING,
+    debounce_irq    = 100,  -- gpio消抖时间,gpio.debounce 时间(ms)
+    time_window     = 1000, -- 检测窗口(ms)
+    pulse_threshold = 3,    -- 触发阈值
+    pulse_timeout   = 200,  -- 脉冲超时(ms)
+    poll_interval   = 10,   -- 状态机轮询(ms)
+    on_event        = nil,  -- 用户回调
+}
+
+-- 内部状态
+local st = {
+    pulse_cnt  = 0,
+    last_valid = 0,
+    detect_t0  = 0,
+    state      = "IDLE",
+}
+
+-- 重置内部状态,将状态机置为空闲状态并清零脉冲计数
+local function reset()
+    st.state = "IDLE"
+    st.pulse_cnt = 0
+end
+
+-- GPIO 中断处理函数,用于处理传感器的脉冲信号
+local function isr()
+    local now = mcu.ticks()
+    st.pulse_cnt = st.pulse_cnt + 1
+    st.last_valid = now
+    -- 如果当前状态为空闲状态
+    if st.state == "IDLE" then
+        -- 切换到检测状态
+        st.state = "DETECTING"
+        -- 记录检测开始时间
+        st.detect_t0 = now
+    end
+end
+
+-- 状态机处理函数,用于检测是否满足震动触发条件
+local function fsm()
+    -- 如果当前状态不是检测状态,则直接返回
+    if st.state ~= "DETECTING" then return end
+    local now = mcu.ticks()
+    -- 计算从检测开始到现在经过的时间
+    local elapsed = now - st.detect_t0
+    -- 判断是否脉冲空闲时间过长
+    local idle_too_long = (now - st.last_valid) >= cfg.pulse_timeout
+    -- 当检测窗口结束或者脉冲空闲时间过长时
+    if elapsed >= cfg.time_window or idle_too_long then
+        -- 检查脉冲计数是否达到触发阈值,并且用户回调函数存在
+        if st.pulse_cnt >= cfg.pulse_threshold and st.on_event then
+            -- 调用用户回调函数并传入脉冲计数值
+            st.on_event(st.pulse_cnt)
+        end
+        -- 重置内部状态
+        reset()
+    end
+end
+--[[
+启动震动检测功能
+@api exvib1.open(opts)
+@table opts 配置参数表,用于自定义震动检测功能的各项属性。
+@return nil 无返回值
+@usage
+-- 配置参数介绍
+--local otps = {
+--    gpio_pin        --"传感器中断所接 GPIO 引脚号,默认值为 nil",
+--    pull            --"上拉/下拉模式,可选 gpio.PULLUP 或 gpio.PULLDOWN,默认值为 gpio.PULLUP",
+--    trigger         --"触发方式,可选 gpio.RISING 或 gpio.FALLING,默认值为 gpio.RISING",
+--    debounce_irq    --"GPIO 消抖时间,单位为毫秒,默认值为 100",
+--    time_window     --"检测窗口时间,单位为毫秒,默认值为 1000",
+--    pulse_threshold --"触发阈值,即连续脉冲次数,默认值为 3",
+--    pulse_timeout   --"脉冲超时时间,单位为毫秒,默认值为 200",
+--    poll_interval   --"状态机轮询时间,单位为毫秒,默认值为 10",
+--    on_event        --"用户回调函数,用于处理检测到的震动事件,默认值为 nil",
+--}
+-- 震动事件回调
+local function vibration_cb(pulse_cnt)
+    log.info("VIB", "detected! pulses =", pulse_cnt)
+end
+exvib1.open({
+    gpio_pin = 24,
+    on_event = vibration_cb,
+})
+]]
+-- 启动震动检测功能
+function exvib1.open(opts)
+    -- 如果没有传入配置参数,则使用空表
+    opts = opts or {}
+    -- 用传入的配置参数更新默认配置
+    for k, v in pairs(opts) do cfg[k] = v end
+    -- 更新用户回调函数,如果传入了新的回调则使用新的,否则保持原有回调
+    st.on_event = opts.on_event or st.on_event
+    -- 配置 GPIO 消抖时间,设置中断处理函数、上拉模式和触发方式
+    gpio.debounce(cfg.gpio_pin, cfg.debounce_irq)
+    gpio.setup(cfg.gpio_pin, isr, cfg.pull, cfg.trigger)
+    -- 启动定时器循环调用状态机处理函数
+    sys.timerLoopStart(fsm, cfg.poll_interval)
+    log.info("Vibration", "start on gpio", cfg.gpio_pin)
+end
+
+--[[
+关闭震动检测功能
+@api exvib1.close()
+@return nil 无返回值
+@usage
+exvib1.close()  --关闭震动检测功能
+--]]
+function exvib1.close()
+    -- 关闭 GPIO 引脚
+    gpio.close(cfg.gpio_pin)
+    -- 停止定时器
+    sys.timerStop(fsm)
+    reset()
+end
+
+return exvib1