talk.lua 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210
  1. --[[
  2. 演示airtalk基本功能
  3. 1. 按键操作
  4. 按一次boot,开始1对1对讲,再按一次boot,结束对讲
  5. 按一次powerkey,开始1对多对讲,再按一次powerkey或者boot,结束对讲
  6. ]]
  7. -- 引入必要模块
  8. local extalk = require "extalk"
  9. local exaudio = require "exaudio"
  10. -- 配置日志格式
  11. log.style(1)
  12. -- 常量定义
  13. local USER_TASK_NAME = "user_task"
  14. local MSG_KEY_PRESS = 12 -- 按键消息
  15. -- 全局状态变量
  16. local g_dev_list = nil -- 设备列表
  17. local g_speech_active = false -- 对讲状态标记
  18. -- 音频初始化参数
  19. local audio_setup_param = {
  20. model = "es8311", -- 音频编解码类型,可填入"es8311","es8211"
  21. i2c_id = 0, -- i2c_id,可填入0,1 并使用pins工具配置对应的管脚
  22. pa_ctrl = gpio.AUDIOPA_EN, -- 音频放大器电源控制管脚
  23. dac_ctrl = 20, -- 音频编解码芯片电源控制管脚
  24. }
  25. -- 联系人列表回调函数
  26. local function contact_list_callback(dev_list)
  27. g_dev_list = dev_list
  28. if dev_list and #dev_list > 0 then
  29. log.info("联系人列表更新:")
  30. for i = 1, #dev_list do
  31. log.info(string.format(" %d. ID: %s, 名称: %s",
  32. i, dev_list[i]["id"], dev_list[i]["name"] or "未知"))
  33. end
  34. else
  35. log.info("联系人列表为空")
  36. end
  37. end
  38. -- 对讲状态回调函数
  39. local function speech_state_callback(event_table)
  40. if not event_table then return end
  41. if event_table.state == extalk.START then
  42. log.info("对讲开始")
  43. g_speech_active = true
  44. elseif event_table.state == extalk.STOP then
  45. log.info("对讲结束")
  46. g_speech_active = false
  47. elseif event_table.state == extalk.UNRESPONSIVE then
  48. log.info("对端未响应")
  49. g_speech_active = false
  50. elseif event_table.state == extalk.ONE_ON_ONE then
  51. g_speech_active = true
  52. local dev_name = "未知设备"
  53. if g_dev_list then
  54. for i = 1, #g_dev_list do
  55. if g_dev_list[i]["id"] == event_table.id then
  56. dev_name = g_dev_list[i]["name"] or "未知设备"
  57. break
  58. end
  59. end
  60. end
  61. log.info(string.format("%s 来电", dev_name))
  62. elseif event_table.state == extalk.BROADCAST then
  63. g_speech_active = true
  64. local dev_name = "未知设备"
  65. if g_dev_list then
  66. for i = 1, #g_dev_list do
  67. if g_dev_list[i]["id"] == event_table.id then
  68. dev_name = g_dev_list[i]["name"] or "未知设备"
  69. break
  70. end
  71. end
  72. end
  73. log.info(string.format("%s 开始广播", dev_name))
  74. end
  75. end
  76. -- extalk配置参数
  77. local extalk_configs = {
  78. key = PRODUCT_KEY,
  79. heart_break_time = 120, -- 心跳间隔(单位秒)
  80. contact_list_cbfnc = contact_list_callback,
  81. state_cbfnc = speech_state_callback,
  82. }
  83. -- 按键回调函数 - Boot键
  84. local function boot_key_callback()
  85. log.info("boot_key_callback++++++")
  86. sys.sendMsg(USER_TASK_NAME, MSG_KEY_PRESS, false) -- false表示Boot键
  87. end
  88. -- 按键回调函数 - Power键
  89. local function power_key_callback()
  90. log.info("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. local function lower_enter() -- 如果需要进入低功耗,请在task 中调用此函数
  144. -- WiFi模组进入低功耗模式
  145. pm.power(pm.WORK_MODE, 1, 1)
  146. -- 同时4G进入低功耗模式
  147. pm.power(pm.WORK_MODE, 1)
  148. sys.wait(20)
  149. -- 暂停airlink通信,进一步降低功耗
  150. airlink.pause(1)
  151. end
  152. -- 用户主任务
  153. local function user_main_task()
  154. -- 初始化音频
  155. local audio_init_ok = exaudio.setup(audio_setup_param)
  156. if not audio_init_ok then
  157. log.error("音频初始化失败")
  158. return
  159. end
  160. log.info("音频初始化成功")
  161. -- 初始化extalk
  162. local extalk_init_ok = extalk.setup(extalk_configs)
  163. if not extalk_init_ok then
  164. log.error("extalk初始化失败")
  165. return
  166. end
  167. log.info("extalk初始化成功")
  168. -- lower_enter() -- 需要进入低功耗,请打开此函数
  169. -- 等待按键消息并处理
  170. while true do
  171. local msg = sys.waitMsg(USER_TASK_NAME, MSG_KEY_PRESS)
  172. if msg and msg[1] == MSG_KEY_PRESS then
  173. handle_key_press(msg[2]) -- msg[2]区分是Power键(true)还是Boot键(false)
  174. end
  175. end
  176. end
  177. -- 初始化按键
  178. init_buttons()
  179. -- 启动用户任务
  180. sys.taskInitEx(user_main_task, USER_TASK_NAME)