爱编程的斯蒂芬 2026-03-05 11:47 采纳率: 33.3%
浏览 10

问题:AiPi-PalChatV1通过UART-MCP控制梁山派(GD32)LED失败,云端无工具调用记录

问题描述:
硬件:安信可科技WB2系列(基于BL602芯片)的AiPi-PalChatV1模组(烧录支持uart-mcp的固件bin:AiPi-PalChatV1_uart-mcp_WWXH_v3.0_20260106.bin) + 梁山派GD32F450(运行emMCP例程),串口连接。
现象:

  1. 当我对模组说“开灯”、“打开LED1”、“打开所有灯”等指令时,模组会语音回复类似“灯已打开”、“LED1已点亮”的内容,但开发板上的LED没有任何反应。
  2. 登录小智平台查看聊天历史,发现这些指令的回复都是普通的文本内容,没有任何工具调用的JSON记录(而之前说“放歌”时,平台有search_music等工具的调用记录)。
  3. WiFi连接成功的JSON指令(如{"role":"AI board","msgType":"status","data":"1.WiFi connect OK"})能被STM32正确接收并通过strstr匹配点亮LED,说明串口通信链路是通的。
  4. 当我说“开灯”等指令时,模组发送MCU这些json数据:"role":"AI board","msgType":"MCP Text"(后面省略),这说明云端将语音识别为普通文本对话,而不是一个需要调用工具的指令

关键证据:
✅ WiFi连接成功的JSON(如"1.WiFi connect OK")能被STM32收到并点亮LED,证明串口通信和硬件控制正常。
❌ 小智平台聊天历史中,“开灯”指令只有普通文本回复,无任何工具调用记录(而“放歌”指令有search_music等工具记录)。

核心疑问:
为什么云端没有将“开灯”识别为工具调用?
STM32端已用emMCP注册了“开发板LED”工具,如何确认工具列表是否成功上报到云端?
是否需要在小智平台手动为工具添加触发说法?如果需要在哪操作?平台界面看不到工具列表。
或者要AiPi-PalChatV1模组这边的程序也得二次开发?

求指点,感谢!

主函数和工具调用:

static void LED_ToolsRequestHandler(void *arg)
{
  cJSON *param = (cJSON *)arg;
  cJSON *led1 = cJSON_GetObjectItem(param, "led1");
  // cJSON *led2 = cJSON_GetObjectItem(param, "led2");
  // cJSON *led3 = cJSON_GetObjectItem(param, "led3");
  // cJSON *led4 = cJSON_GetObjectItem(param, "led4");
  // cJSON *led_all = cJSON_GetObjectItem(param, "led_all");

  if (led1 != NULL)
  {
    HAL_GPIO_WritePin(LED1_GPIO_Port, LED1_Pin, led1->valueint ? GPIO_PIN_SET : GPIO_PIN_RESET);
  // }
  // if (led2 != NULL)
  // {
  //   HAL_GPIO_WritePin(LED2_GPIO_Port, LED2_Pin, led2->valueint ? GPIO_PIN_SET : GPIO_PIN_RESET);
  // }
  // if (led3 != NULL)
  // {
  //   HAL_GPIO_WritePin(LED3_GPIO_Port, LED3_Pin, led3->valueint ? GPIO_PIN_SET : GPIO_PIN_RESET);
  // }
  // if (led4 != NULL)
  // {
  //   HAL_GPIO_WritePin(LED4_GPIO_Port, LED4_Pin, led4->valueint ? GPIO_PIN_SET : GPIO_PIN_RESET);
  // }
  // if (led_all != NULL)
  // {
    HAL_GPIO_WritePin(LED1_GPIO_Port, LED1_Pin, led_all->valueint ? GPIO_PIN_SET : GPIO_PIN_RESET);
    HAL_GPIO_WritePin(LED2_GPIO_Port, LED2_Pin, led_all->valueint ? GPIO_PIN_SET : GPIO_PIN_RESET);
    HAL_GPIO_WritePin(LED3_GPIO_Port, LED3_Pin, led_all->valueint ? GPIO_PIN_SET : GPIO_PIN_RESET);
    HAL_GPIO_WritePin(LED4_GPIO_Port, LED4_Pin, led_all->valueint ? GPIO_PIN_SET : GPIO_PIN_RESET);
  }
  emMCP_ResponseValue(emMCP_CTRL_OK);
}
/* USER CODE END 0 */

/**
 * @brief  The application entry point.
 * @retval int
 */
int main(void)
{

  /* USER CODE BEGIN 1 */

  /* USER CODE END 1 */

  /* MCU Configuration--------------------------------------------------------*/

  /* Reset of all peripherals, Initializes the Flash interface and the Systick.
   */
  HAL_Init();

  /* USER CODE BEGIN Init */

  /* USER CODE END Init */

  /* Configure the system clock */
  SystemClock_Config();

  /* USER CODE BEGIN SysInit */
  SystemInit();
  /* USER CODE END SysInit */

  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_DMA_Init();
  MX_USART1_UART_Init();
  MX_USART2_UART_Init();
  /* USER CODE BEGIN 2 */
  HAL_UARTEx_ReceiveToIdle_DMA(&huart2, rxBuffer, RXBUFFER_SIZE_MAX);
  __HAL_DMA_DISABLE_IT(huart2.hdmarx, DMA_IT_HT);
  emMCP_Init(&emMCP); // Initialize MCP

  LED_Tools.name = "开发板LED";
  LED_Tools.description = "用于控制开发板的4颗LED灯";
  LED_Tools.inputSchema.properties[0].name = "led1";
  LED_Tools.inputSchema.properties[0].description = "控制LED1的亮灭,false为灭,true为亮";
  LED_Tools.inputSchema.properties[0].type = MCP_SERVER_TOOL_TYPE_BOOLEAN;
  // LED_Tools.inputSchema.properties[1].name = "led2";
  // LED_Tools.inputSchema.properties[1].description = "控制LED2的亮灭,false为灭,true为亮";
  // LED_Tools.inputSchema.properties[1].type = MCP_SERVER_TOOL_TYPE_BOOLEAN;
  // LED_Tools.inputSchema.properties[2].name = "led3";
  // LED_Tools.inputSchema.properties[2].description = "控制LED3的亮灭,false为灭,true为亮";
  // LED_Tools.inputSchema.properties[2].type = MCP_SERVER_TOOL_TYPE_BOOLEAN;
  // LED_Tools.inputSchema.properties[3].name = "led4";
  // LED_Tools.inputSchema.properties[3].description = "控制LED4的亮灭,false为灭,true为亮";
  // LED_Tools.inputSchema.properties[3].type = MCP_SERVER_TOOL_TYPE_BOOLEAN;
  // LED_Tools.inputSchema.properties[4].name = "led_all";
  // LED_Tools.inputSchema.properties[4].description = "控制所有LED的亮灭,false为灭,true为亮";
  // LED_Tools.inputSchema.properties[4].type = MCP_SERVER_TOOL_TYPE_BOOLEAN;
  LED_Tools.setRequestHandler = LED_ToolsRequestHandler;
  emMCP_AddToolToToolList(&LED_Tools);
  emMCP_RegistrationTools();
  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
    /* USER CODE END WHILE */
    emMCP_TickHandle(10);
    /* USER CODE BEGIN 3 */
  }
  /* USER CODE END 3 */
}

回调函数:

void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *huart, uint16_t Size)
{
  if (huart == &huart2)
  {
     // 复制数据到临时缓冲区(注意大小,避免溢出)
    char temp[256];
    uint16_t copy_len = (Size < sizeof(temp)-1) ? Size : sizeof(temp)-1;
   
   
    memcpy(temp, rxBuffer, copy_len);
    temp[copy_len] = '\0';  // 添加字符串结束符

   // 检查是否包含联网成功的标志
   if (strstr(temp, "role\":\"AI board\",\"msgType\":\"status\",\"data\":\"1.WiFi connect OK\"") != NULL)
   {
     HAL_GPIO_WritePin(LED3_GPIO_Port, LED3_Pin, GPIO_PIN_SET);
     HAL_GPIO_WritePin(LED4_GPIO_Port, LED4_Pin, GPIO_PIN_SET);
     
   } 
      
    uartPortRecvData((char *)rxBuffer, Size);
    HAL_UARTEx_ReceiveToIdle_DMA(&huart2, rxBuffer, RXBUFFER_SIZE_MAX);
    __HAL_DMA_DISABLE_IT(huart2.hdmarx, DMA_IT_HT);
  }
}

历史对话:

img

  • 写回答

2条回答 默认 最新

  • 檀越@新空间 2026-03-05 12:02
    关注

    中午好🌞🌞🌞
    本答案参考通义千问

    根据你提供的详细问题描述,我们可以逐步分析并解决“AiPi-PalChatV1通过UART-MCP控制梁山派(GD32)LED失败”的问题。以下是重点问题的分析与解决方案


    一、问题核心分析

    关键证据

    • WiFi连接成功的JSON指令(如 "1.WiFi connect OK")能被STM32收到并点亮LED,说明:

      • 串口通信正常
      • STM32接收和处理数据功能正常
    • “开灯”等指令在小智平台聊天历史中无工具调用记录,而“放歌”有 search_music 等工具调用记录,说明:

      • 云端未将“开灯”识别为工具调用请求
      • 可能未正确注册或触发对应的工具

    二、核心疑问解答

    1. 为什么云端没有将“开灯”识别为工具调用?

    原因可能包括:

    • 工具未正确注册到云端
    • 语音指令未被识别为工具调用语句
    • 工具名称或触发词未在云端配置中匹配

    2. 如何确认工具列表是否成功上报到云端?

    步骤如下:

    1. 查看模组日志
      在 AiPi-PalChatV1 模组中开启调试日志,观察是否在启动时发送了工具列表信息。

      // 示例:检查模组是否上报了工具列表
      #ifdef DEBUG
      printf("MCP: Sending tool list to cloud...\n");
      #endif
      
    2. 查看云端数据
      登录小智平台后台,查看是否有 tool_list 或类似字段的上报内容。

    3. 使用云平台API接口(如有权限):
      调用 API 接口获取设备上报的工具列表信息。


    3. 是否需要在小智平台手动为工具添加触发说法?

    是的,需要手动配置

    操作路径(假设是小智平台):

    1. 登录小智平台管理后台。
    2. 找到设备管理页面。
    3. 进入 “语音交互设置”“意图识别配置”
    4. 在“工具调用”或“意图库”中添加自定义工具,例如:
      • 工具名:开发板LED
      • 触发词:开灯, 打开LED1, 打开所有灯
    5. 保存配置并重新测试。

    ⚠️ 如果平台界面看不到工具列表,可能是权限不足或平台版本限制,建议联系平台客服或查阅文档。


    4. 是否需要对 AiPi-PalChatV1 模组进行二次开发?

    是的,可能需要

    原因:
    • 若工具未被自动识别或未在云端配置,可能需要:
      • 修改模组固件代码,显式注册工具名称和触发词
      • 或者在云端配置后,确保模组能正确上报工具信息
    修改示例(伪代码):
    // 注册工具
    mcp_tool_register("开发板LED", "open_led", "开灯,打开LED1,打开所有灯");
    
    // 发送工具列表到云端
    mcp_send_tool_list();
    

    三、解决方案步骤

    解决方案有序列表如下:

    1. 确认串口通信链路正常

      • 已验证 WiFi 连接指令可正常接收,说明串口通信正常。
    2. 检查模组是否成功上报工具列表到云端

      • 查看模组日志,确认是否发送了工具列表。
      • 登录小智平台后台,查看是否有工具列表信息。
    3. 在小智平台手动配置工具和触发词

      • 进入设备管理 -> 语音交互设置 -> 添加工具(如 开发板LED
      • 设置触发词:开灯, 打开LED1, 打开所有灯
    4. 修改模组固件代码,显式注册工具

      • 如果平台不支持自动识别,需在模组代码中注册工具名称和触发词。
      // 示例代码(伪代码)
      mcp_tool_register("开发板LED", "open_led", "开灯,打开LED1,打开所有灯");
      mcp_send_tool_list(); // 上报工具列表
      
    5. 重新测试语音指令

      • 再次说 “开灯”、“打开LED1”,观察是否出现工具调用记录。
    6. 检查云端工具调用记录

      • 登录小智平台,查看聊天历史是否有 open_led 等工具调用记录。

    四、总结

    | 问题 | 解决方案 | |------|----------| | 云端未识别“开灯”为工具调用 | 在小智平台手动配置工具和触发词 | | 工具未上报到云端 | 检查模组日志,确保 mcp_send_tool_list() 被调用 | | 是否需要二次开发 | 需要,若平台不支持自动识别,则需修改模组代码注册工具 |


    五、附加建议

    • 查看官方文档:确认 AiPi-PalChatV1 的 emMCP 例程是否支持工具注册功能。
    • 联系技术支持:如果平台操作复杂或无法找到配置入口,建议联系小智平台或安信可技术团队。
    • 使用调试工具:如 Wireshark 抓包,查看模组与云端之间的通信内容,确认是否发送了工具调用请求。

    如需进一步帮助,请提供:

    • AiPi-PalChatV1 的具体固件版本
    • 小智平台的具体版本号
    • 你目前使用的 emMCP 例程代码片段(如工具注册部分)

    我可以帮你进一步分析和修改代码。

    评论

报告相同问题?

问题事件

  • 修改了问题 3月6日
  • 修改了问题 3月6日
  • 修改了问题 3月5日
  • 修改了问题 3月5日
  • 展开全部