main.lua 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213
  1. --[[
  2. 演示airtalk基本功能
  3. 按一次boot,开始1对1对讲,再按一次boot,结束对讲
  4. 按一次powerkey,开始1对多对讲,再按一次powerkey或者boot,结束对讲
  5. ]]
  6. PROJECT = "airtalk_demo"
  7. VERSION = "1.0.2"
  8. PRODUCT_KEY = "29uptfBkJMwFC7x7QeW10UPO3LecPYFu" -- 到 iot.openluat.com 创建项目,获取正确的项目id
  9. -- 引入必要模块
  10. local extalk = require "extalk"
  11. local exaudio = require "exaudio"
  12. -- 配置日志格式
  13. log.style(1)
  14. -- 常量定义
  15. local USER_TASK_NAME = "user_task"
  16. local MSG_KEY_PRESS = 12 -- 按键消息
  17. -- 全局状态变量
  18. local g_dev_list = nil -- 设备列表
  19. local g_speech_active = false -- 对讲状态标记
  20. -- 音频初始化参数
  21. local audio_setup_param = {
  22. model = "es8311", -- 音频编解码类型,可填入"es8311","es8211"
  23. i2c_id = 0, -- i2c_id,可填入0,1 并使用pins工具配置对应的管脚
  24. pa_ctrl = gpio.AUDIOPA_EN, -- 音频放大器电源控制管脚
  25. dac_ctrl = 20, -- 音频编解码芯片电源控制管脚
  26. }
  27. -- 联系人列表回调函数
  28. local function contact_list_callback(dev_list)
  29. g_dev_list = dev_list
  30. if dev_list and #dev_list > 0 then
  31. log.info("联系人列表更新:")
  32. for i = 1, #dev_list do
  33. log.info(string.format(" %d. ID: %s, 名称: %s",
  34. i, dev_list[i]["id"], dev_list[i]["name"] or "未知"))
  35. end
  36. else
  37. log.info("联系人列表为空")
  38. end
  39. end
  40. -- 对讲状态回调函数
  41. local function speech_state_callback(event_table)
  42. if not event_table then return end
  43. if event_table.state == extalk.START then
  44. log.info("对讲开始,可以说话了")
  45. g_speech_active = true
  46. elseif event_table.state == extalk.STOP then
  47. log.info("对讲结束")
  48. g_speech_active = false
  49. elseif event_table.state == extalk.UNRESPONSIVE then
  50. log.info("对端未响应")
  51. g_speech_active = false
  52. elseif event_table.state == extalk.ONE_ON_ONE then
  53. g_speech_active = true
  54. local dev_name = "未知设备"
  55. if g_dev_list then
  56. for i = 1, #g_dev_list do
  57. if g_dev_list[i]["id"] == event_table.id then
  58. dev_name = g_dev_list[i]["name"] or "未知设备"
  59. break
  60. end
  61. end
  62. end
  63. log.info(string.format("%s 来电", dev_name))
  64. elseif event_table.state == extalk.BROADCAST then
  65. g_speech_active = true
  66. local dev_name = "未知设备"
  67. if g_dev_list then
  68. for i = 1, #g_dev_list do
  69. if g_dev_list[i]["id"] == event_table.id then
  70. dev_name = g_dev_list[i]["name"] or "未知设备"
  71. break
  72. end
  73. end
  74. end
  75. log.info(string.format("%s 开始广播", dev_name))
  76. end
  77. end
  78. -- extalk配置参数
  79. local extalk_configs = {
  80. key = PRODUCT_KEY,
  81. heart_break_time = 120, -- 心跳间隔(单位秒)
  82. contact_list_cbfnc = contact_list_callback,
  83. state_cbfnc = speech_state_callback,
  84. }
  85. -- 按键回调函数 - Boot键
  86. local function boot_key_callback()
  87. sys.sendMsg(USER_TASK_NAME, MSG_KEY_PRESS, false) -- false表示Boot键
  88. end
  89. -- 按键回调函数 - Power键
  90. local function power_key_callback()
  91. sys.sendMsg(USER_TASK_NAME, MSG_KEY_PRESS, true) -- true表示Power键
  92. end
  93. -- 初始化按键
  94. local function init_buttons()
  95. -- 配置Boot键 (GPIO0)
  96. gpio.setup(0, boot_key_callback, gpio.PULLDOWN, gpio.RISING)
  97. gpio.debounce(0, 200, 1) -- 200ms去抖
  98. -- 配置Power键
  99. gpio.setup(gpio.PWR_KEY, power_key_callback, gpio.PULLUP, gpio.FALLING)
  100. gpio.debounce(gpio.PWR_KEY, 200, 1) -- 200ms去抖
  101. end
  102. -- 查找第一个可用的对端设备ID
  103. local function find_first_remote_device()
  104. if not g_dev_list or #g_dev_list == 0 then
  105. log.warn("没有找到可用的设备")
  106. return nil
  107. end
  108. local local_id = mobile.imei()
  109. for i = 1, #g_dev_list do
  110. local dev_id = g_dev_list[i]["id"]
  111. if dev_id and dev_id ~= local_id then
  112. return dev_id
  113. end
  114. end
  115. log.warn("没有找到其他可用设备")
  116. return nil
  117. end
  118. -- 处理按键消息
  119. local function handle_key_press(is_power_key)
  120. if g_speech_active then
  121. -- 当前正在对讲,按任何键都结束对讲
  122. log.info("结束当前对讲")
  123. extalk.stop()
  124. g_speech_active = false
  125. else
  126. -- 当前未在对讲,根据按键类型开始不同对讲
  127. if is_power_key then
  128. -- Power键:开始一对多广播
  129. log.info("开始一对多广播")
  130. extalk.start() -- 不带参数表示广播
  131. else
  132. -- Boot键:开始一对一对讲
  133. log.info("开始一对一对讲")
  134. local remote_id = find_first_remote_device()
  135. if remote_id then
  136. extalk.start(remote_id)
  137. else
  138. log.error("无法开始一对一对讲,没有找到可用设备")
  139. end
  140. end
  141. end
  142. end
  143. -- 用户主任务
  144. local function user_main_task()
  145. -- 初始化音频
  146. local audio_init_ok = exaudio.setup(audio_setup_param)
  147. if not audio_init_ok then
  148. log.error("音频初始化失败")
  149. return
  150. end
  151. log.info("音频初始化成功")
  152. -- 初始化extalk
  153. local extalk_init_ok = extalk.setup(extalk_configs)
  154. if not extalk_init_ok then
  155. log.error("extalk初始化失败")
  156. return
  157. end
  158. log.info("extalk初始化成功")
  159. -- 等待按键消息并处理
  160. while true do
  161. local msg = sys.waitMsg(USER_TASK_NAME, MSG_KEY_PRESS)
  162. if msg and msg[1] == MSG_KEY_PRESS then
  163. handle_key_press(msg[2]) -- msg[2]区分是Power键(true)还是Boot键(false)
  164. end
  165. end
  166. end
  167. -- 初始化按键
  168. init_buttons()
  169. -- 启动用户任务
  170. sys.taskInitEx(user_main_task, USER_TASK_NAME)
  171. -- 内存监控任务
  172. sys.taskInit(function()
  173. while true do
  174. sys.wait(60000) -- 每分钟检查一次
  175. log.info("系统状态监控:")
  176. log.info(" 时间:", os.time())
  177. log.info(" Lua内存:", rtos.meminfo("lua"))
  178. log.info(" 系统内存:", rtos.meminfo("sys"))
  179. log.info(" PSRAM内存:", rtos.meminfo("psram"))
  180. end
  181. end)
  182. -- 启动系统
  183. sys.run()