exvib1 - exvib1 震动传感器扩展库
作者:孟伟
一、概述
应用场景
此库适用于搭配合宙配件板 AirVIBRATING_1000 或者滚珠震动传感器 BL_2529,核心功能是对传感器 GPIO 中断产生的脉冲信号进行滤波和智能识别,从而判断出有效的震动事件。该库的实现思路也可作为其他类似震动传感器中断处理的参考。
核心功能
1、GPIO 中断检测:通过配置的 GPIO 引脚检测震动传感器产生的脉冲信号。
2、双重消抖机制:
IO 中断硬件消抖 (gpio.debounce())。
时间窗口检测:在指定的时间窗口 (time_window) 内统计有效的脉冲数量。
3、阈值触发:当统计的脉冲数超过设定的阈值 (pulse_threshold) 时,触发用户自定义的回调函数。
4、脉冲超时机制:在检测状态下,如果超过 pulse_timeout 时间没有新的脉冲产生,则提前结束当前检测周期并判断是否触发回调,提高响应速度。
状态机工作流程
1、IDLE 状态:等待第一个有效脉冲。
2、DETECTING 状态:进入检测窗口,统计脉冲数量。
3、触发条件:
时间窗口结束。
脉冲空闲时间超过设定的脉冲超时时间。
4、结果判断:脉冲数 ≥ 阈值则调用用户回调函数。
二、核心示例
1、核心示例是指:使用本库文件提供的核心API,开发的基础业务逻辑的演示代码;
2、核心示例的作用是:帮助开发者快速理解如何使用本库,所以核心示例的逻辑都比较简单;
3、更加完整和详细的demo,请参考 LuatOS仓库 中的demo/exvib1
--加载exvib1扩展库
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,
})
三、常量详解
核心库常量,顾名思义是由合宙LuatOS内核固件中定义的、不可重新赋值或修改的固定值,在脚本代码中不需要声明,可直接调用;
exvib1扩展库没有常量。
四、函数详解
exvib1.open(opts)
功能
启动震动检测功能。根据提供的配置参数初始化 GPIO 中断、设置消抖、启动状态机定时器,开始监听传感器信号。
参数
opts
参数含义:震动检测功能的配置参数表;
数据类型:table;
是否必选:是;
参数格式:
{
-- 参数含义:传感器中断信号所连接的 GPIO 引脚编号;
-- 数据类型:number
-- 是否必选:是;
-- 参数示例:24
gpio_pin = ,
-- 参数含义:GPIO 引脚的上拉/下拉模式;
-- 数据类型:number (使用 gpio.PULLUP 或 gpio.PULLDOWN)
-- 是否必选:否;
-- 默认值:gpio.PULLUP
-- 参数示例:gpio.PULLUP
pull = ,
-- 参数含义:GPIO 中断触发方式;
-- 数据类型:number (使用 gpio.RISING 或 gpio.FALLING 或 gpio.BOTH
-- 是否必选:否;
-- 默认值:gpio.RISING
-- 参数示例:gpio.RISING
trigger = ,
-- 参数含义:GPIO 中断硬件消抖时间,单位毫秒(ms);
-- 数据类型:number
-- 是否必选:否;
-- 默认值:100
-- 参数示例:100
debounce_irq = ,
-- 参数含义:检测脉冲的有效时间窗口,单位毫秒(ms)。在此时间窗口内统计脉冲数;
-- 数据类型:number
-- 是否必选:否;
-- 默认值:1000
-- 参数示例:1000
time_window = ,
-- 参数含义:触发回调函数的脉冲数量阈值;
-- 数据类型:number
-- 是否必选:否;
-- 默认值:3
-- 参数示例:3
pulse_threshold = ,
-- 参数含义:脉冲超时时间,单位毫秒(ms)。在 DETECTING 状态下,超过此时间无新脉冲则提前结束本次检测;
-- 数据类型:number
-- 是否必选:否;
-- 默认值:200
-- 参数示例:200
pulse_timeout = ,
-- 参数含义:状态机轮询检查的时间间隔,单位毫秒(ms);
-- 数据类型:number
-- 是否必选:否;
-- 默认值:10
-- 参数示例:10
poll_interval = ,
-- 参数含义:用户定义的回调函数。当有效震动被检测到时,会调用此函数;
-- 数据类型:function
-- 是否必选:是;
-- 参数示例:function(pulse_cnt) log.info("VIB", pulse_cnt) end
on_event = ,
}
无返回值
示例
本示例章节仅列举一些常用功能的核心代码片段
更加完整和详细的demo,请参考 https://gitee.com/openLuat/LuatOS/tree/master/module/Air8000/demo/exvib1
--加载exvib1扩展库
local exvib1= require "exvib1"
-- 震动事件回调
--最简单的,测试时候用的,只打印下触发次数
local function vibration_cb(pulse_cnt)
log.info("VIB", "detected! pulses =", pulse_cnt)
end
--触发震动后把对应的消息通过网络协议发布出去
--[[
local function vibration_cb_mqtt(pulse_cnt)
log.info("VIB", "detected! pulses =", pulse_cnt)
-- 发布 MQTT 报警
local msg = {type="quake", level=pulse_cnt, ts=os.time()}
mqttc:publish("/alert/quake", json.encode(msg), 1)
end
]]
--震动预警类,发生震动时打开摄像头/gnss/发送消息
--[[
local function vibration_cb(pulse_cnt)
log.info("VIB", "detected! pulses =", pulse_cnt)
-- 例如打开gnss
local function mode1_cb(tag)
log.info("TAGmode1_cb+++++++++", tag)
log.info("nmea", "rmc", json.encode(exgnss.rmc(2)))
end
exgnss.open(exgnss.TIMER, { tag = "MODE1", val = 60, cb = mode1_cb })
--例如打开摄像头拍照
--打开摄像头供电
gpio.set(pin, 1)
sys.wait(500)
-- 等摄像头稳定local id = os.date("%Y%m%d%H%M%S")
camera.capture(0, "/capture.jpg", 80)
-- 延迟 30 s 再关摄像头
sys.timerStart(function()
gpio.set(18, 0)
end, 30000)
-- 例如发送短信
--sms.send("+86138xxxxxxxx", "Vehicle shock detected! " .. lng ..lat)
end
]]--
-- 如果触发频繁,可以加冷却期
--[[
local cool = false
local function vibration_cb(pulse_cnt)
log.info("VIB", "detected! pulses =", pulse_cnt)
if cool then return end
cool = true
-- ... 业务逻辑 ...
sys.timerStart(function()
cool = false
end, 60000) -- 冷却 60 send
end
]]
--回调里只做最小工作,把耗时逻辑丢到独立任务
--[[
local vib_msg = {}
local function vibration_cb(pulse_cnt)
log.info("VIB", "detected! pulses =", pulse_cnt)
sys.publish("VIB_EVT", pulse_cnt) -- 非阻塞通知
end
-- 在另一个文件
sys.subscribe("VIB_EVT", function(msg)
log.info("VIB_EVT", msg) -- 例如写 SD、HTTP 上传
-- 其他业务逻辑,例如写 SD、HTTP 上传
end)
]]
--演示最简单的使用方法,都使用默认配置
exvib1.open({
-- 震动传感器中断管脚连接的 GPIO 引脚
gpio_pin = 24,
-- 配置回调函数
on_event = vibration_cb,
})
--不同场景下的参数配置可参考下面的示例
--[[
--高灵敏度,响应快,误触可能高
exvib1.open({
gpio_pin = 24,
on_event = vibration_cb,
time_window = 300, -- 检测窗口(ms)
pulse_threshold = 1, -- 触发阈值
pulse_timeout = 100, -- 脉冲超时(ms)
})
--默认配置,较高灵敏度
exvib1.open({
gpio_pin = 24,
on_event = vibration_cb,
time_window = 1000, -- 检测窗口(ms)
pulse_threshold = 3, -- 触发阈值
pulse_timeout = 200, -- 脉冲超时(ms)
})
--中等灵敏度,
exvib1.open({
gpio_pin = 24,
on_event = vibration_cb,
time_window = 2000, -- 检测窗口(ms)
pulse_threshold = 3, -- 触发阈值
pulse_timeout = 300, -- 脉冲超时(ms)
})
--低灵敏度,减少误报
exvib1.open({
gpio_pin = 24,
on_event = vibration_cb,
time_window = 3000, -- 检测窗口(ms)
pulse_threshold = 10, -- 触发阈值
pulse_timeout = 500, -- 脉冲超时(ms)
})
]]
exvib1.close()
功能
关闭震动检测功能。释放 GPIO 引脚资源,停止状态机定时器,并将内部状态重置为空闲状态。
参数
无参数
返回值
无返回值
示例
-- 关闭震动检测
exvib1.close()
五、产品支持说明
支持LuatOS开发的所有产品都支持exvib1扩展库,不过需要搭配合宙配件板AirVIBRATING_1000,或者也可作为其他类似震动传感器中断处理的参考。