Răsfoiți Sursa

add: 添加Air8000 AirKEY_1000 demo

shenyuanyuan 3 luni în urmă
părinte
comite
b39093d6ca

+ 52 - 0
module/Air8000/demo/accessory_board/AirKEY_1000/AirKEY_1000.lua

@@ -0,0 +1,52 @@
+--本文件中的主机是指Air8000核心板
+--AirKEY_1000是合宙设计生产的一款8路独立按键的配件板
+
+local AirKEY_1000 = {}
+
+
+--配置主机和AirKEY_1000之间的控制参数;
+
+--key_id:number类型;
+--        AirKEY_1000的按键ID;
+--        取值范围:1到8;
+--        必须传入,不允许为空;
+--gpio_id:number类型;
+--         主机使用的中断引脚GPIO ID;
+--         AirKEY_1000上的一个按键引脚,和主机上的一个GPIO中断引脚相连;
+--         AirKEY_1000上的按键按下或者弹起,主机上的GPIO中断引脚输入电平发生变化,从而产生中断;
+--int_mode:number类型;
+--          表示主机GPIO中断触发类型;
+--          取值范围:gpio.RISING表示上升沿触发,gpio.FALLING表示下降沿触发;
+--          如果没有传入此参数,则默认为gpio.FALLING;
+--int_cbfunc:function类型;
+--          表示中断处理函数,函数的定义格式如下:
+--                           function cb_func(level, gpio_id)
+--                               --level:表示触发中断后,某一时刻引脚的电平,1为高电平,0为低电平,并不一定是触发中断时的电平
+--                               --gpio_id:表示触发中断的主机中断引脚的GPIO ID;
+--                           end
+--          中断函数中不要直接执行耗时较长的动作,例如写fskv,写文件,延时等,可以publish消息给其他协程或者给订阅消息的处理函数去执行耗时动作
+--          必须传入,不允许为空;
+
+--返回值:成功返回true,失败返回false
+function AirKEY_1000.setup(key_id, gpio_id, int_mode, int_cbfunc) 
+    --开启防抖,模式0-冷却,中断后马上上报,但200ms内只上报一次
+    gpio.debounce(gpio_id, 200)
+
+    if not (int_mode==gpio.RISING or int_mode==gpio.FALLING) then
+        log.error("AirKEY_1000.setup error", "invalid int_mode", int_mode)
+        return false
+    end
+
+    if type(int_cbfunc)~="function" then
+        log.error("AirKEY_1000.setup error", "invalid int_cbfunc", type(int_cbfunc))
+        return false
+    end
+
+    -- gpio.setup(gpio_id, int_cbfunc, int_mode==gpio.RISING and gpio.PULLDOWN or gpio.PULLUP, int_mode)
+    gpio.setup(gpio_id, int_cbfunc, gpio.PULLUP, int_mode)
+
+    return true
+end
+
+
+return AirKEY_1000

+ 138 - 0
module/Air8000/demo/accessory_board/AirKEY_1000/key_app.lua

@@ -0,0 +1,138 @@
+--[[
+本功能模块演示的内容为:
+使用Air8000核心板的GPIO中断检测AirKEY_1000配件板上8个独立按键的按下或者弹起状态
+AirKEY_1000是合宙设计生产的一款8路独立按键的配件板
+]]
+
+
+--加载AirKEY_1000驱动文件
+local air_key = require "AirKEY_1000"
+
+--AirKEY_1000上8个按键对应的Air8000的GPIO ID
+local KEY1_GPIO_ID = 28
+local KEY2_GPIO_ID = 26
+local KEY3_GPIO_ID = 27
+local KEY4_GPIO_ID = 16
+local KEY5_GPIO_ID = 1
+local KEY6_GPIO_ID = 2
+local KEY7_GPIO_ID = 35
+local KEY8_GPIO_ID = 34
+
+
+--按键1的中断处理函数
+--int_level:number类型,表示触发中断后,某一时刻引脚的电平,1为高电平,0为低电平,并不一定是触发中断时的电平
+--gpio_id:number类型,air_key.setup函数配置按键1时,对应的Air8000上的GPIO ID
+--在中断处理函数中,不要直接执行耗时较长的动作,例如写fskv,写文件,延时等
+--可以publish消息给其他协程或者给订阅消息的处理函数去执行耗时动作
+local function key1_int_cbfunc(int_level, gpio_id)
+    log.info("key1_int_cbfunc pressup", gpio_id, int_level)
+
+    --如果需要执行耗时较长的动作,不要在这里直接执行
+    --而是使用以下代码,publish一个消息出去,给其他协程或者给订阅消息的处理函数去执行耗时动作
+    sys.publish("KEY1_PRESSUP_IND")
+end
+
+--按键2的中断处理函数
+--int_level:number类型,表示触发中断后,某一时刻引脚的电平,1为高电平,0为低电平,并不一定是触发中断时的电平
+--gpio_id:number类型,air_key.setup函数配置按键2时,对应的Air8000上的GPIO ID
+--在中断处理函数中,不要直接执行耗时较长的动作,例如写fskv,写文件,延时等
+--可以publish消息给其他协程或者给订阅消息的处理函数去执行耗时动作
+local function key2_int_cbfunc(int_level, gpio_id)
+    log.info("key2_int_cbfunc pressup", gpio_id, int_level)
+
+    --如果需要执行耗时较长的动作,不要在这里直接执行
+    --而是使用以下代码,publish一个消息出去,给其他协程或者给订阅消息的处理函数去执行耗时动作
+    sys.publish("KEY2_PRESSUP_IND")
+end
+
+--按键3的中断处理函数
+--int_level:number类型,表示触发中断后,某一时刻引脚的电平,1为高电平,0为低电平,并不一定是触发中断时的电平
+--gpio_id:number类型,air_key.setup函数配置按键3时,对应的Air8000上的GPIO ID
+--在中断处理函数中,不要直接执行耗时较长的动作,例如写fskv,写文件,延时等
+--可以publish消息给其他协程或者给订阅消息的处理函数去执行耗时动作
+local function key3_int_cbfunc(int_level, gpio_id)
+    log.info("key3_int_cbfunc pressup", gpio_id, int_level)
+
+    --如果需要执行耗时较长的动作,不要在这里直接执行
+    --而是使用以下代码,publish一个消息出去,给其他协程或者给订阅消息的处理函数去执行耗时动作
+    sys.publish("KEY3_PRESSUP_IND")
+end
+
+--按键4的中断处理函数
+--int_level:number类型,表示触发中断后,某一时刻引脚的电平,1为高电平,0为低电平,并不一定是触发中断时的电平
+--gpio_id:number类型,air_key.setup函数配置按键4时,对应的Air8000上的GPIO ID
+--在中断处理函数中,不要直接执行耗时较长的动作,例如写fskv,写文件,延时等
+--可以publish消息给其他协程或者给订阅消息的处理函数去执行耗时动作
+local function key4_int_cbfunc(int_level, gpio_id)
+    log.info("key4_int_cbfunc pressup", gpio_id, int_level)
+
+    --如果需要执行耗时较长的动作,不要在这里直接执行
+    --而是使用以下代码,publish一个消息出去,给其他协程或者给订阅消息的处理函数去执行耗时动作
+    sys.publish("KEY4_PRESSUP_IND")
+end
+
+
+--按键5、6、7、8的中断处理函数
+--int_level:number类型,表示触发中断后,某一时刻引脚的电平,1为高电平,0为低电平,并不一定是触发中断时的电平
+--gpio_id:number类型,air_key.setup函数配置按键5、6、7、8时,对应的Air8000上的GPIO ID
+--在中断处理函数中,不要直接执行耗时较长的动作,例如写fskv,写文件,延时等
+--可以publish消息给其他协程或者给订阅消息的处理函数去执行耗时动作
+local function key5678_int_cbfunc(int_level, gpio_id)
+    log.info("key5678_int_cbfunc", gpio_id, int_level)
+
+    --如果需要执行耗时较长的动作,不要在这里直接执行
+    --而是使用以下代码,publish一个消息出去,给其他协程或者给订阅消息的处理函数去执行耗时动作
+    if gpio_id==KEY5_GPIO_ID then
+        log.info("key5 pressdown")
+        sys.publish("KEY5_PRESSDOWN_IND")
+    elseif gpio_id==KEY6_GPIO_ID then
+        log.info("key6 pressdown")
+        sys.publish("KEY6_PRESSDOWN_IND")
+    elseif gpio_id==KEY7_GPIO_ID then
+        log.info("key7 pressdown")
+        sys.publish("KEY7_PRESSDOWN_IND")
+    elseif gpio_id==KEY8_GPIO_ID then
+        log.info("key8 pressdown")
+        sys.publish("KEY8_PRESSDOWN_IND")
+    end    
+end
+
+
+
+--本demo中,Air8000核心板和AirKEY_1000配件板的接线方式如下
+--Air8000核心板             AirKEY_1000配件板
+--     CAN_RXD/GPIO28-----------------K1
+--     CAN_TXD/GPIO26-----------------K2
+--     CAN_STB/GPIO27-----------------K3
+--     GPIO16-----------------K4
+--     GPIO1-----------------K5
+--     GPIO2-----------------K6
+--     LCD_CS/GPIO35-----------------K7
+--     LCD_CLK/GPIO34-----------------K8
+--       GND-----------------G
+
+
+
+--AirKEY_1000上的1、2、3、4,四个按键的引脚
+--分别和Air8000的KEY1_GPIO_ID、KEY2_GPIO_ID、KEY3_GPIO_ID、KEY4_GPIO_ID四个引脚相连
+--GPIO配置为上升沿触发中断,可以实时检测到按键弹起的动作
+--按键弹起时,会执行对应的中断处理函数key1_int_cbfunc、key2_int_cbfunc、key3_int_cbfunc、key4_int_cbfunc
+--在中断处理函数中,不要直接执行耗时较长的动作,例如写fskv,写文件,延时等
+--可以publish消息给其他协程或者给订阅消息的处理函数去执行耗时动作
+air_key.setup(1, KEY1_GPIO_ID, gpio.RISING, key1_int_cbfunc)
+air_key.setup(2, KEY2_GPIO_ID, gpio.RISING, key2_int_cbfunc)
+air_key.setup(3, KEY3_GPIO_ID, gpio.RISING, key3_int_cbfunc)
+air_key.setup(4, KEY4_GPIO_ID, gpio.RISING, key4_int_cbfunc)
+
+--AirKEY_1000上的5、6、7、8,四个按键的引脚
+--分别和Air8000的KEY5_GPIO_ID、KEY6_GPIO_ID、KEY7_GPIO_ID、KEY8_GPIO_ID四个引脚相连
+--GPIO配置为下降沿触发中断,可以实时检测到按键按下的动作
+--按键按下时,会执行对应的中断处理函数key5678_int_cbfunc
+--这四个按键共用了同一个中断处理函数,可以通过函数传入的GPIO ID来区分是哪一个按键被按下
+--在中断处理函数中,不要直接执行耗时较长的动作,例如写fskv,写文件,延时等
+--可以publish消息给其他协程或者给订阅消息的处理函数去执行耗时动作
+air_key.setup(5, KEY5_GPIO_ID, gpio.FALLING, key5678_int_cbfunc)
+air_key.setup(6, KEY6_GPIO_ID, gpio.FALLING, key5678_int_cbfunc)
+air_key.setup(7, KEY7_GPIO_ID, gpio.FALLING, key5678_int_cbfunc)
+air_key.setup(8, KEY8_GPIO_ID, gpio.FALLING, key5678_int_cbfunc)
+

+ 63 - 0
module/Air8000/demo/accessory_board/AirKEY_1000/main.lua

@@ -0,0 +1,63 @@
+--[[
+必须定义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进行远程升级,根据自己项目的需求,自定义格式即可
+
+AirKEY_1000是合宙设计生产的一款支持8个独立按键的配件板;
+本demo演示的核心功能为:
+Air780EHV核心板+AirKEY_1000配件板,使用Air780EHV核心板的GPIO中断检测AirKEY_1000配件板上8个独立按键的按下或者弹起状态;
+更多说明参考本目录下的readme.md文件
+]]
+PROJECT = "AirKEY_1000"
+VERSION = "001.000.000"
+
+
+-- 在日志中打印项目名和项目版本号
+log.info("main", PROJECT, VERSION)
+
+-- 如果内核固件支持wdt看门狗功能,此处对看门狗进行初始化和定时喂狗处理
+-- 如果脚本程序死循环卡死,就会无法及时喂狗,最终会自动重启
+if wdt then
+    --配置喂狗超时时间为9秒钟
+    wdt.init(9000)
+    --启动一个循环定时器,每隔3秒钟喂一次狗
+    sys.timerLoopStart(wdt.feed, 3000)
+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)
+
+ -- 加载KEY应用模块
+ require "key_app"
+
+
+-- 用户代码已结束---------------------------------------------
+-- 结尾总是这一句
+sys.run()
+-- sys.run()之后不要加任何语句!!!!!因为添加的任何语句都不会被执行

+ 119 - 0
module/Air8000/demo/accessory_board/AirKEY_1000/readme.md

@@ -0,0 +1,119 @@
+## 功能模块介绍
+
+1、main.lua:主程序入口;
+
+2、key_app.lua:使用核心板的GPIO中断检测AirKEY_1000配件板上8个独立按键的按下或者弹起状态;
+
+3、AirKEY_1000.lua:配置主机和AirKEY_1000之间的控制参数;
+
+## 用户消息介绍
+
+1、"KEY1_PRESSUP_IND":按键消息,publish该消息给其他协程或者给订阅消息的处理函数去执行耗时动作;
+
+2、"KEY2_PRESSUP_IND":按键消息,publish该消息给其他协程或者给订阅消息的处理函数去执行耗时动作;
+
+3、"KEY3_PRESSUP_IND":按键消息,publish该消息给其他协程或者给订阅消息的处理函数去执行耗时动作;
+
+4、"KEY4_PRESSUP_IND":按键消息,publish该消息给其他协程或者给订阅消息的处理函数去执行耗时动作;
+
+5、"KEY5_PRESSUP_IND":按键消息,publish该消息给其他协程或者给订阅消息的处理函数去执行耗时动作;
+
+6、"KEY5_PRESSUP_IND":按键消息,publish该消息给其他协程或者给订阅消息的处理函数去执行耗时动作;
+
+7、"KEY7_PRESSUP_IND":按键消息,publish该消息给其他协程或者给订阅消息的处理函数去执行耗时动作;
+
+8、"KEY8_PRESSUP_IND":按键消息,publish该消息给其他协程或者给订阅消息的处理函数去执行耗时动作;
+
+## 演示功能概述
+
+AirKEY_1000是合宙设计生产的一款支持8个独立按键的配件板;
+
+本demo演示的核心功能为:
+
+Air8000核心板+AirKEY_1000配件板,使用Air8000核心板的GPIO中断检测AirKEY_1000配件板上8个独立按键的按下或者弹起状态;
+
+
+## 核心板+配件板资料
+
+[Air8000核心板+配件板相关资料](https://docs.openluat.com/Air8000/product/shouce/)
+
+
+## 演示硬件环境
+
+![](https://docs.openluat.com/accessory/AirKEY_1000/image/Air8000_connection.jpg)
+
+![](https://docs.openluat.com/accessory/AirSHT30_1000/image/8000.png)
+
+1、Air8000核心板
+
+2、AirKEY_1000配件板
+
+3、母对母的杜邦线9根
+
+4、Air8000核心板和AirKEY_1000配件板的硬件接线方式为
+
+- Air8000核心板通过TYPE-C USB口连接TYPE-C USB 数据线,数据线的另外一端连接电脑的USB口;
+- 核心板正面的 供电/充电 拨动开关 拨到供电一端;
+- 核心板背面的 USB ON/USB OFF 拨动开关 拨到USB ON一端;
+
+| Air8000核心板 |  AirKEY_1000配件板 |
+| ------------ | ------------------ |
+|    CAN_RXD/GPIO28    |         K1         |
+|    CAN_TXD/GPIO26    |         K2         |
+|    CAN_STB/GPIO27    |         K3         |
+|    GPIO16    |         K4         |
+|    GPIO1    |         K5         |
+|    GPIO2    |         K6         |
+|    LCD_CS/GPIO35    |         K7         |
+|    LCD_CLK/GPIO34    |         K8         |
+|     GND     |         G          |
+
+
+## 演示软件环境
+
+1、[Luatools下载调试工具](https://docs.openluat.com/air780epm/common/Luatools/)
+
+2、[Air8000 最新版本的内核固件](https://docs.openluat.com/air8000/luatos/firmware/)
+
+
+## 演示操作步骤
+
+1、搭建好演示硬件环境
+
+2、不需要修改demo脚本代码
+
+3、Luatools烧录内核固件和demo脚本代码
+
+4、烧录成功后,自动开机运行
+
+   (1) 按键1弹起时,Luatools的运行日志输出 key1_int_cbfunc pressup,表示按键1测试正常;
+
+   (2) 按键2弹起时,Luatools的运行日志输出 key2_int_cbfunc pressup,表示按键2测试正常;
+
+   (3) 按键3弹起时,Luatools的运行日志输出 key3_int_cbfunc pressup,表示按键3测试正常;
+
+   (4) 按键4弹起时,Luatools的运行日志输出 key4_int_cbfunc pressup,表示按键4测试正常;
+
+   (5) 按键5按下时,Luatools的运行日志输出 key5 pressdown,表示按键5测试正常;
+
+   (6) 按键6按下时,Luatools的运行日志输出 key6 pressdown,表示按键6测试正常;
+
+   (7) 按键7按下时,Luatools的运行日志输出 key7 pressdown,表示按键7测试正常;
+
+   (8) 按键8按下时,Luatools的运行日志输出 key8 pressdown,表示按键8测试正常;
+
+```
+[2025-10-20 10:39:08.283][000000006.310] I/user.key1_int_cbfunc pressup 28 1
+[2025-10-20 10:39:09.351][000000007.382] I/user.key2_int_cbfunc pressup 26 1
+[2025-10-20 10:39:10.818][000000008.855] I/user.key3_int_cbfunc pressup 27 1
+[2025-10-20 10:39:11.705][000000009.736] I/user.key4_int_cbfunc pressup 16 1
+[2025-10-20 10:39:12.900][000000010.930] I/user.key5678_int_cbfunc 1 0
+[2025-10-20 10:39:12.906][000000010.931] I/user.key5 pressdown
+[2025-10-20 10:39:13.989][000000012.026] I/user.key5678_int_cbfunc 2 0
+[2025-10-20 10:39:13.998][000000012.027] I/user.key6 pressdown
+[2025-10-20 10:39:15.457][000000013.491] I/user.key5678_int_cbfunc 35 0
+[2025-10-20 10:39:15.462][000000013.492] I/user.key7 pressdown
+[2025-10-20 10:39:16.790][000000014.829] I/user.key5678_int_cbfunc 34 0
+[2025-10-20 10:39:16.792][000000014.830] I/user.key8 pressdown
+```
+

+ 1 - 1
module/Air8000/demo/gpio/GPIO中断(触发)模式/main.lua

@@ -15,7 +15,7 @@ end
 
 -- 配置gpio27为中断模式,上升沿(gpio.RISING)和下降沿(gpio.FALLING)均触发(gpio.BOTH)
 -- 请根据实际需求更改gpio编号和触发模式
-local gpio_pin = 27
+local gpio_pin = 153
 gpio.debounce(gpio_pin, 100)
 gpio.setup(gpio_pin, function()
     log.info("gpio", gpio_pin, "被触发")