本帖最后由 云天 于 2026-8-8 16:59 编辑
【项目背景】 HUSKYLENS 2(二哈识图2)作为一款简单易用、玩法多样的AI视觉传感器,搭载了6TOPS算力的专用AI芯片,预置了人脸识别、目标检测、物体分类、姿态识别、实例分割等20余种开机即用的AI模型。而“小智AI”是HUSKYLENS 2推出的联网智能语音助手,只需安装WiFi模块并连接网络,即可通过语音与HUSKYLENS 2的小智智能体进行实时对话。 小智AI的核心亮点在于通过MCP(Model Context Protocol)协议,直接调用HUSKYLENS 2内置的多种AI模型和工具——包括人脸识别、物体识别、物体追踪、颜色识别、手势识别、姿态识别、车牌识别、OCR文字识别、自学习分类模型等。用户只需用语音发出指令,小智AI便会自动调用对应的模型进行识别和学习,无需手动切换功能或编写代码。 本文将对小智AI的各项核心功能进行系统测试,并分享几个有趣的创客项目创意。 【准备工作】
硬件清单
HUSKYLENS 2 AI视觉传感器 × 1 HUSKYLENS 2 WiFi模块 × 1 USB Type-C数据线 × 1 5V电源适配器或电脑USB接口
软件准备确保HUSKYLENS 2固件更新到最新版本 电脑或手机浏览器(用于访问小智控制平台) 可用的2.4GHz WiFi网络
HUSKYLENS 2核心规格
项目 | 参数 | | 处理器 | Kendryte K230 双核 1.6GHz | | 算力 | 6 TOPS | | 内存 | 1GB LPDDR4 | | 存储 | 8GB EMMC | | 屏幕 | 2.4寸 640×480 IPS触摸屏 | | 摄像头 | GC2093 200W像素 |
【小智AI配置与激活】
1. 安装WiFi模块并联网
使用USB数据线为HUSKYLENS 2供电,将WiFi模块插入对应接口。在系统设置中完成WiFi网络配置,连接至2.4GHz网络。 2. 启动小智AI
联网成功后,在菜单页面找到“小智AI”并点击进入,点击开关按钮启动。第一次使用时,屏幕会显示一串激活码,请记下此激活码。 3. 绑定设备
在电脑或手机浏览器中访问xiaozhi.me,进入小智控制平台。首次登录需输入手机号获取验证码。登录后,在控制台中输入HUSKYLENS 2屏幕上显示的激活码完成设备绑定。 提示:绑定只需操作一次,后续使用时会自动连接。
4. 唤醒小智AI
绑定成功后,使用唤醒词 “你好,小哈”(你好,小智) 即可唤醒HUSKYLENS 2的小智助手。 【核心功能测试】
1. 基础对话与问答
唤醒后可直接与小智AI进行语音对话。小智AI通过知识库与联网搜索能力,可以回答各类问题,例如“今天天气怎么样”、“告诉我今天的新闻”等。 测试体验:响应速度流畅,语音识别准确度较高,适合作为日常语音助手使用。 2. 切换视觉识别模型
这是小智AI最核心的功能之一。通过语音即可切换HUSKYLENS 2内置的各种AI视觉模型,例如: “切换到人脸识别” “切换到物体追踪” “切换到颜色识别” “切换到手势识别”
测试体验:语音指令识别后,屏幕会立即切换至对应功能界面,整个过程无需任何手动操作,真正实现了“动口不动手”。 3. 获取视觉识别结果
进入某个视觉识别功能后,可以询问小智AI当前画面内容,例如: “告诉我你看到了什么” “当前画面中有几个人” “识别到的是什么颜色”
小智AI会描述镜头捕捉到的内容,实现图片语义理解。 4.语音学习与命名
这是另一个极具实用性的功能。可以通过语音让HUSKYLENS 2学习当前画面中的目标对象并命名。 操作示例: 测试体验:学习过程自动完成,无需手动按键操作,极大降低了使用门槛。 5.查询识别结果
学习完毕后,可以让小智AI播报当前的识别结果。例如当画面中同时有已学习和未学习的人脸时,询问“告诉我当前人脸识别的结果”,小智AI会准确告知识别到的人脸数量及已学习人脸的名称。 6.多模型并联运行
小智AI支持同时加载多个模型并分配算力比例。例如: 这为复杂场景下的多任务视觉处理提供了可能。 【测试总结】
经过全面测试,小智AI的以下几点表现令人印象深刻:
测试项目 | 评价 | | 语音唤醒与识别 | ★★★★★ 响应迅速,识别准确 | | 模型切换 | ★★★★★ 无需手动操作,流畅切换 | | 视觉识别与语义理解 | ★★★★☆ 识别准确,描述自然 | | 语音学习功能 | ★★★★★ 极大简化了学习流程 | | 多模型并联 | ★★★★☆ 算力分配灵活 |
最大的亮点:将复杂的AI视觉操作变成了简单的语音对话。无论是切换模型、执行识别还是学习新目标,都只需要说一句话。这让HUSKYLENS 2从“需要编程的传感器”变成了“会听话的AI助手”。 需改进的点:有时会“自回声拾取”,猜测是因算力原因,简化了AEC算法,消回声能力大幅下降,导致拾取自身播放的内容。 【测试视频】
1.通过对话启动“物体识别”模型,识别出“遥控器”并进行介绍
2.AI手势控制LED灯,通过手势识别控制家居设备。
实现思路: - 使用手势识别检测功能
定义不同手势对应的控制指令 通过语音让小智AI进入手势识别模式 识别到特定手势后,通过小智MCP服务控制LED灯
扩展可能:可配合ESP32、掌控板等主控实现灯光、空调、窗帘等设备的无接触控制。 3.掌控板程序:
- #include <Arduino.h>
- #include <WiFi.h>
- #include <WebSocketMCP.h>
- #include <ArduinoJson.h>
- #include <Adafruit_NeoPixel.h> // 新增LED控制库
-
- /********** WiFi 配置 ***********/
- const char* WIFI_SSID = "你的WiFi名称";
- const char* WIFI_PASS = "你的WiFi密码";
-
- /********** MCP 服务器地址 ***********/
- const char* MCP_ENDPOINT = "wss://api.xiaozhi.me/mcp/?token=你的token";
-
- /********** LED 配置 ***********/
- #define LED_PIN 26 // 掌控板P8引脚 (GPIO26)
- #define LED_COUNT 24 // 灯珠数量
- #define LED_BRIGHTNESS 255 // 全局亮度上限(保持色彩鲜艳)
-
- Adafruit_NeoPixel strip(LED_COUNT, LED_PIN, NEO_GRB + NEO_KHZ800);
-
- /********** 调试串口 ***********/
- #define DEBUG_SERIAL Serial
- #define DEBUG_BAUD_RATE 115200
-
- /********** 全局变量 ***********/
- WebSocketMCP mcpClient;
-
- bool wifiConnected = false;
- bool mcpConnected = false;
-
- bool ledRunning = false;
- unsigned long ledStartTime = 0;
- float ledDuration = 0;
-
- int targetBrightness = 0; // 目标亮度 0~100
- int currentBrightness = 0; // 当前实际亮度(平滑渐变)
- unsigned long lastStepTime = 0;
- const int STEP_DELAY = 20; // 每20ms步进1%
-
- /********** 函数声明 ***********/
- void setupWifi();
- void onMcpConnectionChange(bool connected);
- void registerMcpTools();
- void setLEDBrightness(int percent);
- void stopLED();
- void updateLED();
-
- /********** setup ***********/
- void setup() {
- DEBUG_SERIAL.begin(DEBUG_BAUD_RATE);
- DEBUG_SERIAL.println("\n\n[ESP32-C3 MCP LED控制] 初始化...");
-
- // 初始化LED灯带
- strip.begin();
- strip.show(); // 全部熄灭
- strip.setBrightness(LED_BRIGHTNESS);
-
- // 连接 WiFi
- setupWifi();
-
- // 初始化 MCP
- if (mcpClient.begin(MCP_ENDPOINT, onMcpConnectionChange)) {
- DEBUG_SERIAL.println("[MCP] 初始化成功,尝试连接...");
- } else {
- DEBUG_SERIAL.println("[MCP] 初始化失败!");
- }
-
- DEBUG_SERIAL.println("\n使用说明:");
- DEBUG_SERIAL.println("- 控制亮度 0~100%");
- DEBUG_SERIAL.println("- 可设置运行时间(秒),到期自动熄灭");
- DEBUG_SERIAL.println("- 示例: {"brightness":80,"duration":5}");
- DEBUG_SERIAL.println();
- }
-
- /********** loop ***********/
- void loop() {
- mcpClient.loop();
- updateLED();
- }
-
- /********** WiFi 连接 ***********/
- void setupWifi() {
- DEBUG_SERIAL.print("[WiFi] 连接到 ");
- DEBUG_SERIAL.println(WIFI_SSID);
- WiFi.mode(WIFI_STA);
- WiFi.begin(WIFI_SSID, WIFI_PASS);
-
- int attempts = 0;
- while (WiFi.status() != WL_CONNECTED && attempts < 20) {
- delay(500);
- DEBUG_SERIAL.print(".");
- attempts++;
- }
-
- if (WiFi.status() == WL_CONNECTED) {
- wifiConnected = true;
- DEBUG_SERIAL.println();
- DEBUG_SERIAL.println("[WiFi] 连接成功! IP: " + WiFi.localIP().toString());
- } else {
- wifiConnected = false;
- DEBUG_SERIAL.println();
- DEBUG_SERIAL.println("[WiFi] 连接失败,将重试...");
- }
- }
-
- /********** MCP 连接回调 ***********/
- void onMcpConnectionChange(bool connected) {
- mcpConnected = connected;
- if (connected) {
- DEBUG_SERIAL.println("[MCP] 已连接,注册工具...");
- registerMcpTools();
- } else {
- DEBUG_SERIAL.println("[MCP] 断开连接");
- }
- }
-
- /********** 注册 MCP 工具 ***********/
- void registerMcpTools() {
- DEBUG_SERIAL.println("[MCP] 注册LED控制工具...");
-
- mcpClient.registerTool(
- "set_led",
- "控制24珠LED灯带亮度(0~100%)和运行时间(秒)",
- R"({
- "type": "object",
- "properties": {
- "brightness": {
- "type": "integer",
- "description": "亮度百分比 0~100",
- "minimum": 0,
- "maximum": 100
- },
- "duration": {
- "type": "number",
- "description": "运行时间(秒),0或省略表示一直运行"
- }
- },
- "required": ["brightness"]
- })",
- [](const String& args) -> WebSocketMCP::ToolResponse {
- DEBUG_SERIAL.println("[工具] set_led 被调用,参数: " + args);
-
- DynamicJsonDocument doc(256);
- DeserializationError error = deserializeJson(doc, args);
- if (error) {
- return WebSocketMCP::ToolResponse("{"success":false,"error":"JSON解析失败"}", true);
- }
-
- int brightness = doc["brightness"].as<int>();
- brightness = constrain(brightness, 0, 100);
-
- float duration = doc.containsKey("duration") ? doc["duration"].as<float>() : 0;
-
- targetBrightness = brightness;
-
- if (duration > 0) {
- ledRunning = true;
- ledStartTime = millis();
- ledDuration = duration;
- } else {
- ledRunning = false;
- }
-
- String result = "{"success":true,"brightness":" + String(brightness) +
- ","duration":" + String(duration) + "}";
- return WebSocketMCP::ToolResponse(result);
- }
- );
-
- DEBUG_SERIAL.println("[MCP] 工具注册完成 (共 " + String(mcpClient.getToolCount()) + " 个)");
- }
-
- /********** LED 底层控制 ***********/
- // 设置所有灯珠为白色,亮度百分比 (0~100)
- void setLEDBrightness(int percent) {
- uint8_t level = map(percent, 0, 100, 0, 255);
- level = constrain(level, 0, 255);
- uint32_t color = strip.Color(level, level, level); // 白色
- for (int i = 0; i < LED_COUNT; i++) {
- strip.setPixelColor(i, color);
- }
- strip.show();
- }
-
- // 停止并熄灭
- void stopLED() {
- targetBrightness = 0;
- currentBrightness = 0;
- setLEDBrightness(0);
- ledRunning = false;
- }
-
- // 平滑亮度更新(20ms步进)
- void updateLED() {
- // 平滑渐变
- if (ledRunning || targetBrightness != currentBrightness) {
- if (millis() - lastStepTime >= STEP_DELAY) {
- lastStepTime = millis();
- if (currentBrightness < targetBrightness) currentBrightness++;
- else if (currentBrightness > targetBrightness) currentBrightness--;
- setLEDBrightness(currentBrightness);
- }
- }
-
- // 定时停止
- if (ledRunning && millis() - ledStartTime >= (unsigned long)(ledDuration * 1000)) {
- stopLED();
- DEBUG_SERIAL.println("[LED] 定时结束,自动熄灭");
- }
- }
复制代码

HUSKYLENS 2的小智AI功能,通过MCP协议将强大的AI视觉能力与自然语言交互完美结合。它让复杂的AI视觉应用变得像聊天一样简单,无论是教育场景、创客项目还是智能产品原型开发,都提供了极大的便利。 以上仅供参考,欢迎大家在此基础上发挥想象,创造出更多有趣的应用!如果你也有基于HUSKYLENS 2小智AI的好玩项目,欢迎在评论区分享交流~
|