[PSOC Edge] 【英飞凌 Edgi Talk评测】英飞凌 Edgi Talk小智AI语音比对发送数据案例

[复制链接]
1511|4
peterLaw 发表于 2026-5-13 20:53 | 显示全部楼层 |阅读模式
, AC, , ,
本帖最后由 peterLaw 于 2026-5-14 08:52 编辑

#申请原创#   @21小跑堂     #技术资源#
上一篇文章说的是小智的程序下载以及新手入门教学应用  https://bbs.21ic.com/icview-3515453-1-1.html ,那么这一章就针对小智进行相关数据通信控制关节的案例方案实施。
由于关节通讯是使用的485通讯,参考Edgi Talk开发板原理图发现没有相关的485接口,本案例就使用串口替代485接口进行相关数据通信。
实际原理框图如下:

基本实施过程如下:
1、小智通过WIFI联网,长时间保持连接确保开发板与网络连接的稳定
2、通过与小智对话发送特定指令,比如告诉小智“串口发送数据”,小智接收到指令后进行使用串口发送对应的数据
3、当然串口应该发送对应的16进制格式的数据码,为方便验证过程本文仅仅通过发送串口显示窗口显示“串口数据发送成功”的反馈。
4、本文设置"串口发送数据"、"485发送数据"、"CAN发送数据"、 "IO发送数据"等几种语音指令告诉小智,通过语音比对分别发送"串口发送数据成功"、"485发送数据成功"、"CAN发送数据成功"、"IO发送数据成功"等反馈数据。
小智的主线程在
  1. rt_thread_create("xz_ui", ui_thread_entry, RT_NULL,
  2.                            UI_THREAD_STACK, UI_THREAD_PRIORITY, UI_THREAD_TICK);

小智的主要语音数据联网处理是在Message_handle()函数中,所以本方案也在此函数中进行相关语音处理比对。
设定需求的语音字符如下:

小智会将语音转换成文字,只要进行相关字符串的比对就可以实现所需的功能,具体如下:

串口界面如下:


下面展示通过串口数据接收到的小智发送数据如下:




当然这个案例还有一些需要优化的就应该把小智回答的给去掉,不让他回答只进行串口数据发送,后期会进一步优化程序。
实际连续1天联网测试均正常, Edgi Talk开发板还是很稳定的,方案验证非常成功,在后期相关联网平板控制相关关节、控制器等硬件没有问题,可以稳定连接实现。
我后期也会基于此开发板进行更多的案例分享。
详细视频可以参考B站视频


本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?注册

×
 楼主| peterLaw 发表于 2026-5-14 08:49 | 显示全部楼层
核心代码比对程序如下:


  1. void Message_handle(const uint8_t *data, uint16_t len)
  2. {
  3.     char * str1;
  4.     char * str2 = "串口发送数据。";
  5.     char * str3 = "485发送数据。";
  6.     char * str4 = "CAN发送数据。";
  7.     char * str5 = "IO发送数据。";



  8.     cJSON *root = cJSON_Parse((const char *)data);
  9.     if (!root)
  10.     {
  11.         LOG_E("Error before: [%s]\n", cJSON_GetErrorPtr());
  12.         return;
  13.     }

  14.     char *type = my_json_string(root, "type");

  15.     if (strcmp(type, "hello") == 0)
  16.     {
  17.         char *session_id = cJSON_GetObjectItem(root, "session_id")->valuestring;
  18.         cJSON *audio_param = cJSON_GetObjectItem(root, "audio_params");
  19.         g_app.ws.sample_rate = cJSON_GetObjectItem(audio_param, "sample_rate")->valueint;
  20.         g_app.ws.frame_duration = cJSON_GetObjectItem(audio_param, "frame_duration")->valueint;
  21.         strncpy(g_app.ws.session_id, session_id, 9);
  22.         rt_bool_t in_listening = (g_app.state == kDeviceStateListening) || xz_mic_is_enabled();
  23.         if (!in_listening && g_app.state != kDeviceStateSpeaking)
  24.         {
  25.             g_app.state = kDeviceStateIdle;
  26.         }
  27.         xz_ws_audio_init();

  28.         /* Initialize only on first connection */
  29.         if (!g_app.iot_initialized)
  30.         {
  31.             LOG_I("Initializing IoT devices for first time\n");
  32.             extern void iot_initialize(void);
  33.             iot_initialize();
  34.             g_app.iot_initialized = 1;
  35.         }
  36.         else
  37.         {
  38.             LOG_D("IoT already initialized, skipping repeated initialization\n");
  39.         }

  40.         /* Resend device info after each reconnect */
  41.         send_iot_descriptors();
  42.         send_iot_states();
  43.         rt_bool_t pending_listen = g_app.pending_listen_start;
  44.         if (!pending_listen && !in_listening)
  45.         {
  46.             xiaozhi_ui_chat_status("   待命中");
  47.             xiaozhi_ui_chat_output(" ");
  48.             xiaozhi_ui_update_emoji("neutral");
  49.             LOG_I("Waiting...\n");
  50.         }
  51.         else
  52.         {
  53.             LOG_I("Pending wake-up detected on hello, preparing to listen\n");
  54.         }

  55.         /* Initialize wake word detection once */
  56.         if (!g_app.wakeword_initialized_session)
  57.         {
  58.             LOG_I("Initializing wake word detection...");
  59.             if (xz_wakeword_init() == 0)
  60.             {
  61.                 g_app.wakeword_initialized_session = 1;

  62.                 /* Start detection only if no pending listen */
  63.                 if (!pending_listen && !in_listening)
  64.                 {
  65.                     if (xz_wakeword_start() == 0)
  66.                     {
  67.                         LOG_D("Wake word detection started successfully");
  68.                     }
  69.                     else
  70.                     {
  71.                         LOG_E("Failed to start wake word detection");
  72.                     }
  73.                 }
  74.             }
  75.             else
  76.             {
  77.                 LOG_E("Failed to initialize wake word detection");
  78.             }
  79.         }
  80.         else
  81.         {
  82.             if (pending_listen)
  83.             {
  84.                 if (xz_wakeword_is_enabled())
  85.                 {
  86.                     LOG_D("Stopping wake word detection before pending listen start");
  87.                     xz_wakeword_stop();
  88.                 }
  89.             }
  90.             else
  91.             {
  92.                 /* Just ensure wake word is running */
  93.                 if (!xz_wakeword_is_enabled() && !in_listening)
  94.                 {
  95.                     LOG_D("Restarting wake word detection");
  96.                     xz_wakeword_start();
  97.                 }
  98.             }
  99.         }

  100.         if (pending_listen)
  101.         {
  102.             if (g_app.state == kDeviceStateListening || g_app.state == kDeviceStateSpeaking)
  103.             {
  104.                 g_app.pending_listen_start = RT_FALSE;
  105.                 g_app.pending_play_wake_sound = RT_FALSE;
  106.                 return;
  107.             }

  108.             g_app.pending_listen_start = RT_FALSE;

  109.             if (g_app.pending_play_wake_sound)
  110.             {
  111.                 xz_play_wake_sound();
  112.             }
  113.             g_app.pending_play_wake_sound = RT_FALSE;

  114.             if (xz_wakeword_is_enabled())
  115.             {
  116.                 xz_wakeword_stop();
  117.             }

  118.             g_app.state = kDeviceStateListening;
  119.             xz_mic(1);
  120.             if (ws_send_listen_start(&g_app.ws.clnt, g_app.ws.session_id, kListeningModeAutoStop))
  121.             {
  122.                 xiaozhi_ui_chat_status("   聆听中");
  123.                 xiaozhi_ui_chat_output("聆听中...");
  124.             }
  125.             else
  126.             {
  127.                 LOG_W("Listen start failed after hello, falling back to idle");
  128.                 g_app.state = kDeviceStateIdle;
  129.                 xz_mic(0);
  130.                 xiaozhi_ui_chat_status("   就绪");
  131.                 xiaozhi_ui_chat_output("就绪");
  132.                 if (!xz_wakeword_is_enabled())
  133.                 {
  134.                     xz_wakeword_start();
  135.                 }
  136.             }
  137.         }
  138.     }
  139.     else if (strcmp(type, "goodbye") == 0)
  140.     {
  141.         /* Ensure mic is closed when entering sleep */
  142.         xz_mic(0);
  143.         xiaozhi_ui_chat_status("   休眠中");
  144.         xiaozhi_ui_chat_output("等待唤醒");
  145.         xiaozhi_ui_update_emoji("sleepy");
  146.         g_app.state = kDeviceStateUnknown;
  147.         LOG_I("session ended\n");

  148.         /* Reset the initialization flag for next session */
  149.         g_app.wakeword_initialized_session = 0;
  150.         /* Keep wake word detection running in sleep mode for wake-up */
  151.         if (!xz_wakeword_is_enabled())
  152.         {
  153.             LOG_I("Starting wake word detection for sleep mode");
  154.             xz_wakeword_start();
  155.         }
  156.     }
  157.     else if (strcmp(type, "tts") == 0)
  158.     {
  159.         char *state = my_json_string(root, "state");
  160.         if (strcmp(state, "start") == 0)
  161.         {
  162.             if (g_app.state == kDeviceStateIdle || g_app.state == kDeviceStateListening)
  163.             {
  164.                 /* Ensure mic off before TTS starts */
  165.                 if (g_app.state == kDeviceStateListening)
  166.                 {
  167.                     xz_mic(0);
  168.                 }

  169.                 g_app.state = kDeviceStateSpeaking;
  170.                 xiaozhi_ui_chat_status("   说话中");
  171.                 xz_speaker(1);
  172.                 LOG_D("State transitioned to Speaking, microphone stopped\n");

  173.                 /* Start fallback timeout in case sentence_end never arrives */
  174.                 if (g_app.multi_turn_conversation_enabled && g_app.tts_sentence_end_timer)
  175.                 {
  176.                     rt_timer_stop(g_app.tts_sentence_end_timer);
  177.                     rt_err_t start_ret = rt_timer_start(g_app.tts_sentence_end_timer);
  178.                     if (start_ret == RT_EOK)
  179.                     {
  180.                         LOG_D("Started TTS sentence end timer on TTS start (%d ms)", TTS_SENTENCE_TIMEOUT_MS);
  181.                     }
  182.                     else
  183.                     {
  184.                         LOG_W("Failed to start TTS sentence end timer on TTS start, start_ret=%d", start_ret);
  185.                     }
  186.                 }
  187.             }
  188.             else
  189.             {
  190.                 LOG_D("Already in Speaking state, ignoring duplicate start\n");
  191.             }
  192.         }
  193.         else if (strcmp(state, "stop") == 0)
  194.         {
  195.             /* Stop the sentence end timer if it's running */
  196.             if (g_app.tts_sentence_end_timer)
  197.             {
  198.                 rt_timer_stop(g_app.tts_sentence_end_timer);
  199.                 LOG_D("Stopped TTS sentence end timer on TTS stop");
  200.             }

  201.             g_app.state = kDeviceStateIdle;
  202.             xz_speaker(0);

  203.             /* Ensure microphone is closed when conversation ends */
  204.             if (xz_mic_is_enabled())
  205.             {
  206.                 xz_mic(0);
  207.             }

  208.             /* Microphone recording should have been stopped already */
  209.             LOG_D("TTS stopped: mic enabled=%d, wakeword enabled=%d",
  210.                   xz_mic_is_enabled(), xz_wakeword_is_enabled());

  211.             xiaozhi_ui_chat_status("   就绪");
  212.             xiaozhi_ui_chat_output("就绪");
  213.             LOG_D("TTS stopped, state reset to Idle\n");

  214. #ifdef LX_LITEGFX_VGLITE_ENABLE
  215.             qday_show_emoji_by_rtt_info(12);
  216. #endif
  217.             /* Check if multi-turn conversation is enabled */
  218.             if (g_app.multi_turn_conversation_enabled)
  219.             {
  220.                 /* Multi-turn conversation: start delay timer to restart listening after audio finishes */
  221.                 if (tts_stop_delay_timer)
  222.                 {
  223.                     LOG_D("Starting TTS stop delay timer (%d ms)", TTS_STOP_DELAY_MS);
  224.                     rt_timer_start(tts_stop_delay_timer);
  225.                 }
  226.                 else
  227.                 {
  228.                     LOG_W("Delay timer not available, restarting listening immediately");
  229.                     /* Fallback: restart immediately */
  230.                     g_app.state = kDeviceStateListening;
  231.                     xz_mic(1);
  232.                     if (ws_send_listen_start(&g_app.ws.clnt, g_app.ws.session_id, kListeningModeAutoStop))
  233.                     {
  234.                         xiaozhi_ui_chat_status("   聆听中");
  235.                         xiaozhi_ui_chat_output("聆听中...");
  236.                     }
  237.                     else
  238.                     {
  239.                         LOG_W("Listen start failed in TTS stop handler");
  240.                         g_app.state = kDeviceStateIdle;
  241.                         xz_mic(0);
  242.                         xiaozhi_ui_chat_status("   就绪");
  243.                         xiaozhi_ui_chat_output("就绪");
  244.                     }
  245.                 }
  246.             }
  247.             else
  248.             {
  249.                 /* Single-turn conversation: restart wake word detection after conversation ends */
  250.                 if (!xz_wakeword_is_enabled())
  251.                 {
  252.                     LOG_I("Restarting wake word detection after conversation ends");
  253.                     if (xz_wakeword_start() == 0)
  254.                     {
  255.                         LOG_I("Wake word detection re-enabled successfully after conversation");
  256.                     }
  257.                     else
  258.                     {
  259.                         LOG_E("Failed to re-enable wake word detection after conversation");
  260.                     }
  261.                 }
  262.             }
  263.         }
  264.         else if (strcmp(state, "sentence_start") == 0)
  265.         {
  266. //           LOG_I("tts:%s", my_json_string(root, "text"));
  267. //           xiaozhi_ui_chat_output(my_json_string(root, "text"));
  268.         }
  269.         else if (strcmp(state, "sentence_end") == 0)
  270.         {
  271.             /* sentence_end indicates the end of a sentence */
  272.             LOG_D("TTS sentence ended");

  273.             /* For multi-turn conversation, start a timeout timer to restart listening after sentence end */
  274.             if (g_app.multi_turn_conversation_enabled && g_app.state == kDeviceStateSpeaking)
  275.             {
  276.                 /* Use the pre-created timer: stop then start to reset timeout */
  277.                 if (g_app.tts_sentence_end_timer)
  278.                 {
  279.                     rt_err_t stop_ret = rt_timer_stop(g_app.tts_sentence_end_timer);
  280.                     if (stop_ret != RT_EOK)
  281.                     {
  282.                         LOG_W("rt_timer_stop returned %d when resetting TTS timer", stop_ret);
  283.                     }
  284.                     rt_err_t start_ret = rt_timer_start(g_app.tts_sentence_end_timer);
  285.                     if (start_ret == RT_EOK)
  286.                     {
  287.                         LOG_D("Started TTS sentence end timer (%d ms), stop_ret=%d start_ret=%d", TTS_SENTENCE_TIMEOUT_MS, stop_ret, start_ret);
  288.                     }
  289.                     else
  290.                     {
  291.                         LOG_E("Failed to start existing TTS sentence end timer, start_ret=%d", start_ret);
  292.                     }
  293.                 }
  294.                 else
  295.                 {
  296.                     /* Fallback: try to create and start the timer if it wasn't created earlier */
  297.                     g_app.tts_sentence_end_timer = rt_timer_create("tts_end_timer",
  298.                                                                    tts_sentence_end_timeout,
  299.                                                                    RT_NULL,
  300.                                                                    rt_tick_from_millisecond(TTS_SENTENCE_TIMEOUT_MS),
  301.                                                                    RT_TIMER_FLAG_ONE_SHOT);
  302.                     if (g_app.tts_sentence_end_timer && rt_timer_start(g_app.tts_sentence_end_timer) == RT_EOK)
  303.                     {
  304.                         LOG_D("Created and started fallback TTS sentence end timer (%d ms)", TTS_SENTENCE_TIMEOUT_MS);
  305.                     }
  306.                     else
  307.                     {
  308.                         LOG_E("Failed to create/start fallback TTS sentence end timer");
  309.                     }
  310.                 }
  311.             }
  312.         }
  313.         else
  314.         {
  315.             LOG_E("Unknown tts state: %s\n", state);
  316.         }
  317.     }
  318.     else if (strcmp(type, "llm") == 0)
  319.     {
  320.         LOG_I("llm emotion: %s", cJSON_GetObjectItem(root, "emotion")->valuestring);
  321.         xiaozhi_ui_update_emoji(
  322.             cJSON_GetObjectItem(root, "emotion")->valuestring);
  323.     }
  324.     else if (strcmp(type, "stt") == 0)
  325.     {
  326.         LOG_I("stt:%s", cJSON_GetObjectItem(root, "text")->valuestring);

  327.         str1 = cJSON_GetObjectItem(root, "text")->valuestring;

  328.         if (strcasecmp(str1, str2) == 0) {
  329.             LOG_I("串口发送数据成功");
  330.         }
  331.         if (strcasecmp(str1, str3) == 0) {
  332.             LOG_I("485发送数据成功");
  333.         }
  334.         if (strcasecmp(str1, str4) == 0) {
  335.             LOG_I("CAN发送数据成功");
  336.         }
  337.         if (strcasecmp(str1, str5) == 0) {
  338.             LOG_I("IO发送数据成功");
  339.         }

  340.     }
  341.     else if (strcmp(type, "iot") == 0)
  342.     {
  343.         LOG_D("iot command");
  344.         cJSON *commands = cJSON_GetObjectItem(root, "commands");
  345.         for (int i = 0; i < cJSON_GetArraySize(commands); i++)
  346.         {
  347.             cJSON *cmd = cJSON_GetArrayItem(commands, i);
  348.             char *cmd_str = cJSON_PrintUnformatted(cmd);
  349.             if (cmd_str)
  350.             {
  351.                 iot_invoke((uint8_t *)cmd_str, strlen(cmd_str));
  352.                 send_iot_states();
  353.                 cJSON_free(cmd_str);
  354.             }
  355.         }
  356.     }
  357.     else if (strcmp(type, "mcp") == 0)
  358.     {
  359.         LOG_D("mcp command");
  360.         cJSON *payload = cJSON_GetObjectItem(root, "payload");
  361.         if (payload && cJSON_IsObject(payload))
  362.         {
  363.             // extern void McpServer_ParseMessage(const char *message);
  364.             char *payload_str = cJSON_PrintUnformatted(payload);
  365.             if (payload_str)
  366.             {
  367.                 McpServer_ParseMessage(payload_str);
  368.                 cJSON_free(payload_str);
  369.             }
  370.         }
  371.     }
  372.     else if (strcmp(type, "error") == 0)
  373.     {
  374.         cJSON *message = cJSON_GetObjectItem(root, "message");
  375.         if (message && cJSON_IsString(message))
  376.         {
  377.             LOG_E("Server error: %s\n", message->valuestring);
  378.         }
  379.         else
  380.         {
  381.             LOG_E("Server returned error\n");
  382.         }
  383.     }
  384.     else
  385.     {
  386.         LOG_E("Unknown type: %s\n", type);
  387.     }
  388.     cJSON_Delete(root);
  389. }


cooldog123pp 发表于 2026-5-21 10:44 | 显示全部楼层
还是想问一下,小智的话是英飞凌提供的智能接口吗??
gaojie1316 发表于 2026-5-21 23:42 | 显示全部楼层
cooldog123pp 发表于 2026-6-15 16:05 | 显示全部楼层
楼主,问一下,还是想问一下,小智的话是英飞凌提供的智能接口吗??
您需要登录后才可以回帖 登录 | 注册

本版积分规则

34

主题

483

帖子

0

粉丝
快速回复 在线客服 返回列表 返回顶部
0