talk.lua 5.7 KB

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