基于HuskyLens与掌控板打造本地AI视觉自助收银机原型

1. 项目缘起:当AI视觉遇上开源硬件,我们能做什么?

最近在折腾一个挺有意思的项目,用HuskyLens AI视觉传感器和掌控板,做了一个自助超市收银机的原型。这听起来可能有点“玩具”的感觉,但实际做下来,你会发现它触及了现代零售、物联网和嵌入式AI几个领域的交叉点。HuskyLens这个传感器,本质上是一个集成了简单AI算法的摄像头模组,能直接输出识别结果,比如人脸、物体、颜色、标签、巡线,省去了我们在微控制器上跑复杂模型的麻烦。掌控板则是一个基于ESP32的开源硬件,集成了屏幕、按键、麦克风、Wi-Fi/蓝牙,非常适合做交互原型。

那么,把这两者结合起来做一个“收银机”,核心逻辑是什么?其实就是用HuskyLens去识别商品(比如通过颜色、物体或二维码标签),然后掌控板负责处理识别结果、计算价格、显示账单,并模拟支付流程。整个过程,我们不需要连接云端服务器,所有计算都在本地完成,响应快,也保护了隐私。这个项目非常适合想了解AIoT(人工智能物联网)入门、嵌入式系统交互设计,或者单纯想做个有趣小项目的朋友。无论你是学生、创客,还是对智能硬件感兴趣的开发者,都能从这个项目中获得从硬件连接到逻辑编程的完整体验。

2. 核心硬件选型与连接:为什么是HuskyLens和掌控板?

在做任何项目之前,硬件选型是第一步,也是最关键的一步。选对了,事半功倍;选错了,可能连第一步都迈不出去。我选择HuskyLens和掌控板这个组合,是基于几个非常实际的考量。

2.1 HuskyLens:将AI视觉能力“傻瓜化”

HuskyLens最大的优势在于“开箱即用”。传统的AI视觉方案,你需要一个摄像头模组(如OV2640),然后在微控制器(如ESP32-CAM)上部署TensorFlow Lite Micro之类的框架,自己准备数据集、训练模型、优化、部署。这个过程门槛高,周期长,对算力也有要求。HuskyLens则把这些都封装好了。它内置了Kendryte K210 AI芯片,预置了多种算法。你只需要在它的小屏幕上,通过按键选择识别模式(比如“物体识别”),然后让它“学习”一两个你要识别的物体样本,它就能在后续的摄像头画面中实时框出并告诉你这是什么。

对于我们的超市收银机项目,这意味着:

  1. 快速原型:我们不需要自己训练商品识别模型。可以用“颜色识别”模式区分不同颜色的水果(红苹果、绿苹果、黄香蕉),或者用“物体识别”模式学习几个具体的商品包装盒。
  2. 降低复杂度:HuskyLens通过UART(串口)或I2C接口输出结构化的识别结果,比如ID:1, x:120, y:80(ID代表学习时的样本编号,x,y是中心坐标)。掌控板只需要解析这些简单的数据,而不需要处理原始的图像流。
  3. 功耗与体积:相比带摄像头的开发板,HuskyLens集成度高,供电简单(5V),体积也相对紧凑。

注意:HuskyLens的识别能力是有限的。它适合识别特征明显、背景相对简单的物体。对于成百上千种高度相似的商品(比如不同口味的同品牌薯片),它的准确率会下降。但在我们的原型和教学场景中,这完全够用。

2.2 掌控板:一体化的交互与计算核心

为什么不用更常见的Arduino Uno或ESP32开发板?因为掌控板在“交互”上做了高度集成。

  1. 内置显示屏:一块1.3英寸的OLED屏幕,无需额外接线和驱动,直接可以显示商品名称、价格、总价等信息,这是收银机的核心输出设备。
  2. 丰富的输入设备:板载了多个触摸按键(金手指)和物理按键(A/B),我们可以轻松地设计“确认”、“取消”、“结账”等交互逻辑。
  3. 无线能力:集成ESP32,自带Wi-Fi和蓝牙。虽然我们这个基础版本是离线收银,但未来扩展线上支付、库存同步等功能非常方便。
  4. 编程友好:完美支持Mind+(基于Scratch3.0)和Python(MicroPython)编程。对于初学者,图形化编程可以快速搭建逻辑;对于进阶者,Python能实现更复杂的控制。

2.3 硬件连接:一张图搞定供电与通信

连接非常简单,核心是建立HuskyLens与掌控板之间的串口通信。

所需材料清单:

  • HuskyLens AI视觉传感器 x1
  • 掌控板(2.0版本) x1
  • Type-C数据线(为掌控板供电和编程) x1
  • 杜邦线(母对母) x4

接线步骤:

  1. 给HuskyLens供电:HuskyLens需要5V电压。掌控板上的3V3引脚是3.3V,不能直接使用。我们需要使用掌控板上的VCC引脚(输出5V)和GND引脚。
  2. 建立串口通信:我们使用软串口(Software Serial)来通信,以避免占用掌控板下载程序用的硬串口。通常选择两个通用的GPIO引脚。
  3. 具体连接方案:
掌控板引脚HuskyLens引脚线色(建议)作用
3V33V3灰色错误接法!勿用!HuskyLens需要5V。
VCC (5V)VCC (5V)红色正确!为HuskyLens提供5V电源。
GNDGND黑色或棕色共地,确保电压基准一致。
P13(GPIO13)RX黄色掌控板的TX(发送端)接HuskyLens的RX(接收端)。
P14(GPIO14)TX白色掌控板的RX(接收端)接HuskyLens的TX(发送端)。

提示:TX接RX,RX接TX,这是串口通信的标准接法,目的是让一方的发送端对准另一方的接收端。接反了无法通信。

连接完成后,用Type-C线将掌控板连接到电脑。此时,HuskyLens应该会亮起红灯,屏幕点亮。

3. 软件环境搭建与HuskyLens基础配置

硬件连好了,接下来是让它们“活”起来的软件部分。这里我强烈推荐使用**Mind+**这款国产图形化编程软件,它对掌控板和HuskyLens的支持非常友好,省去了配置开发环境、安装库文件等一系列繁琐步骤。

3.1 Mind+软件安装与设备连接

  1. 下载与安装:前往Mind+官网下载对应操作系统的版本并安装。
  2. 切换模式:打开Mind+,点击左上角,切换到“实时模式”(区别于上传模式的离线运行,实时模式可以边编程边看到效果,非常适合调试)。
  3. 连接掌控板
    • 用Type-C线连接掌控板和电脑。
    • 在Mind+右下角点击“连接设备”,在端口列表中,选择识别到的掌控板端口(如COM3/dev/cu.usbserial-XXXX)。
    • 点击连接,成功后右下角会显示“掌控板”已连接。
  4. 加载扩展:这是关键一步。我们需要告诉Mind+,这个项目要用到HuskyLens。
    • 点击左下角的“扩展”,在“主控板”分类下找到并添加“掌控板”。
    • 然后在“传感器”分类下找到“HuskyLens AI摄像头”,点击添加。添加成功后,左侧积木区会出现HuskyLens相关的指令块。

3.2 HuskyLens的首次配置与“学习”商品

在编程之前,我们需要先在HuskyLens设备本身上进行一些设置,让它准备好识别我们的“商品”。

  1. 选择识别算法:按HuskyLens侧面的“功能键”(FUNC),屏幕上会列出所有算法:人脸识别、物体追踪、物体识别、巡线、颜色识别、标签识别等。

    • 方案A(颜色识别):如果我们用不同颜色的积木块代表不同商品(红=苹果,绿=梨,蓝=饮料),就选择“颜色识别”。这是最简单快速的方案。
    • 方案B(物体识别):如果我们用真实的、外形有区别的小物件(比如一盒牛奶、一包饼干),就选择“物体识别”。这个模式需要“学习”样本。
    • 方案C(标签识别):如果我们打印一些二维码或AprilTag贴纸贴到商品上,就选择“标签识别”。这最接近真实超市的条形码方案。

    这里以物体识别为例进行后续说明。

  2. 学习第一个商品样本

    • 将HuskyLens对准第一个商品(比如一盒牛奶),确保它在屏幕中央的白色方框内。
    • 长按“学习键”(LEARN)约2秒,直到屏幕上的白色方框变成蓝色框,并显示“再按一次确认,长按退出”。此时HuskyLens已经抓取了一帧图像作为样本。
    • 短按一次“学习键”,屏幕上会显示“ID:1”。这意味着这个商品被学习为1号样本。你可以按“功能键”来切换显示ID编号。
  3. 学习更多商品:重复步骤2,学习其他商品(比如饼干、巧克力)。每次学习,HuskyLens会自动分配递增的ID(2, 3...)。

  4. 保存模型(可选但重要):HuskyLens断电后,学习的物体会丢失。为了下次不用重新学,可以长按“功能键”进入设置菜单,找到“保存模型”并确认。这样模型就保存在了传感器内部。

完成这些后,当你把学习过的商品再次放到镜头前,HuskyLens应该能自动框出它,并显示对应的ID。这就为我们的收银程序提供了最基础的输入信号。

4. 核心逻辑编程:从识别到结算的完整流程

有了硬件连接和传感器配置,最核心的部分来了——编程。我们将使用Mind+的图形化积木来搭建整个收银机的逻辑。虽然看起来像搭积木,但其背后的逻辑与用Python或C++编写是完全相通的。我会详细解释每一块积木的作用和背后的编程思想。

4.1 程序初始化与HuskyLens通信建立

任何程序都需要一个起点。在Mind+中,我们通常用“当绿色旗帜被点击”作为主程序的开始。

  1. 初始化串口:首先,我们必须初始化与HuskyLens通信的软串口。
    • 拖入串口初始化积木,设置TX引脚为13,RX引脚为14,波特率设置为9600。这个波特率需要与HuskyLens的出厂设置一致(通常是9600)。
    • 为什么是9600?波特率是通信速度。更高的波特率(如115200)传输更快,但可能不稳定。9600是低速但非常稳定的通用选择,对于传输简单的识别结果数据(几个字节)绰绰有余。
  2. 初始化HuskyLens协议:拖入HuskyLens初始化积木。这个积木内部会向HuskyLens发送一些初始化指令,确保两者使用同一种“语言”(协议)通信。
  3. 清空屏幕与变量:拖入清空屏幕积木,让OLED屏幕从空白开始。然后,创建几个变量来存储关键数据:
    • 商品ID:临时存储当前识别到的商品编号。
    • 商品名称:根据ID映射出的名称。
    • 商品单价:根据ID映射出的价格。
    • 购物清单:一个列表(数组),用于存储每次识别后加入的商品名称。
    • 总价:一个数字变量,累加每次加入商品的价格。

实操心得:在“当绿色旗帜被点击”下面进行所有的初始化操作是一个好习惯。这确保了每次重新运行程序,都是从干净的状态开始,避免了上次运行残留的数据干扰本次逻辑。

4.2 构建商品信息数据库

在真实收银系统中,商品名称和价格是从后台数据库查询的。在我们的原型里,需要自己建立一个简单的映射关系。最直接的方法就是用“如果...那么...”积木来实现查询。

我们可以创建一个自定义的“函数”(在Mind+里叫“自制积木”),命名为“查询商品信息”,它接收一个“商品ID”作为输入,然后设置对应的“商品名称”和“商品单价”。

在这个函数里,我们会这样写逻辑:

如果 商品ID = 1 那么 商品名称 = “牛奶” 商品单价 = 5.5 否则如果 商品ID = 2 那么 商品名称 = “饼干” 商品单价 = 3.0 否则如果 商品ID = 3 那么 商品名称 = “巧克力” 商品单价 = 8.0 否则 商品名称 = “未知商品” 商品单价 = 0

这样,当主程序拿到一个ID,调用这个函数,就能立刻知道它是什么、卖多少钱。

4.3 主循环:识别、处理、显示的永动机

收银机需要一直工作,等待商品被放到镜头前。这需要一个“永远循环”的结构。

  1. 获取识别结果:在循环内,首先拖入向HuskyLens请求数据积木,协议选择“物体识别”。这条指令会让掌控板通过串口向HuskyLens索要最新的识别数据。
  2. 解析数据:接着使用HuskyLens是否有读到数据?积木进行判断。如果为“是”,说明HuskyLens当前“看到”了它认识的东西。
    • 如果读到数据,就用HuskyLens读取物体识别数据,ID积木,将识别到的物体ID存入商品ID变量。
    • 然后,立即调用我们刚才创建的“查询商品信息”函数。
  3. 防重复触发机制(关键!):这里有一个巨大的坑。HuskyLens的识别是连续的,一个商品放在镜头前,程序每循环一次(可能每秒几十次)都会读到同一个ID,导致瞬间在购物清单里添加几十件同样的商品,总价爆炸。
    • 解决方案:引入一个状态变量,比如上次识别ID。在成功识别并处理一个商品后,将当前商品ID存入上次识别ID。然后在循环开头,判断如果HuskyLens是否有读到数据?为是,并且读到的商品ID不等于上次识别ID,才进行后续的“加入购物车”操作。处理完后,立即更新上次识别ID。当商品拿开,HuskyLens读不到数据了,就将上次识别ID重置为0或-1,等待下一个商品。
    • 这个逻辑模拟了真实收银机的“扫码枪”行为:扫一次,响一声,添加一件。而不是把商品放在扫码口不动,它就一直在那“哔哔哔”地添加。
  4. 加入购物车与计算:当确认是一次新的有效识别后:
    • 商品名称追加到购物清单列表中。
    • 商品单价累加到总价变量上。
  5. 更新屏幕显示:在OLED屏幕上清晰地显示信息。可以分区域显示:
    • 第一行:显示最新加入的商品,如+牛奶 5.5元
    • 中间区域:滚动显示购物清单列表的内容。
    • 底部:固定显示总计:XX.XX元
    • 使用OLED显示字符串积木,并注意用转行积木控制显示位置。

4.4 交互功能:结账与清零

一个完整的收银机不能只加不减,还需要结账和开始新订单的功能。

  1. 绑定按键事件:我们可以用掌控板的A键作为“结账”键,B键作为“清零/新订单”键。
  2. 结账逻辑:当A键被按下时,程序可以:
    • 在屏幕上显示“请支付 XX.XX元”的醒目提示。
    • 播放一段“嘀嘀”的提示音(使用掌控板的蜂鸣器)。
    • 可以模拟一个3秒倒计时,然后显示“支付成功,谢谢惠顾!”。
    • 注意:结账后不应自动清零,因为可能需要打印小票(我们这里模拟)。实际按需决定是否在结账后自动清零。
  3. 清零逻辑:当B键被按下时,程序需要:
    • 清空购物清单列表。
    • 总价变量设为0。
    • 清空屏幕,并显示“等待扫码...”的初始界面。
    • 同时,也要重置上次识别ID等状态变量,为新订单做好准备。

踩坑实录:按键检测的“消抖”。机械按键在按下时,信号并不是干净的从0到1,而是会在几毫秒内产生快速的抖动,导致程序误判为多次按下。在Mind+中,可以使用“当按键A被按下”事件积木,它内部通常做了消抖处理。但如果自己用循环检测引脚电平,就必须在代码中加入延时(如等待50毫秒)再判断一次,以确保是有效的按键动作。

5. 功能优化与扩展思考

一个能跑通的基础版本已经完成了。但要让这个项目更像样、更有学习价值,我们还需要进行一些优化和思考扩展的可能性。

5.1 提升识别鲁棒性与用户体验

  1. 多物体同时识别:HuskyLens支持一帧画面里识别多个物体。我们可以修改程序,不再只读取第一个物体的ID,而是用一个循环,通过HuskyLens物体识别数据,下一个?积木来遍历当前画面中的所有已识别物体。这样,即使你同时把牛奶和饼干放在镜头前,也能一次性都加入购物车,体验更流畅。
  2. 增加视觉与听觉反馈:识别成功时,除了屏幕显示,还可以让掌控板的RGB灯闪烁绿色;识别到未知商品时,闪烁红色并发出“嘀嘀”报警声。这能让人机交互更加直观。
  3. 屏幕显示优化:当购物清单很长时,OLED屏幕一屏显示不下。需要实现滚动显示功能。可以设定一个固定显示行数(如4行),当列表超过4个商品时,让列表的起始显示索引逐渐增加,实现自动向上滚动,就像超市收银机屏幕那样。

5.2 向“真实”收银系统迈进

我们的原型是离线的,所有商品价格都硬编码在程序里。如何让它更接近真实系统?

  1. 引入条码/二维码识别:这是最直接的升级。使用HuskyLens的“标签识别”模式,学习几个二维码(可以用手机生成,内容就是商品ID,如“001”)。商品上贴上对应的二维码。程序识别到二维码后,解析出ID,后续流程不变。这更符合真实超市场景。
  2. 搭建简单的网络数据库:利用掌控板的Wi-Fi功能。
    • 在同一个局域网内,用电脑或树莓派搭建一个最简单的HTTP服务器,上面放一个prices.json文件,内容如{"001": {"name": "牛奶", "price": 5.5}, "002": {...}}
    • 当掌控板识别到商品ID后,不是去本地函数查询,而是通过Wi-Fi发起一个HTTP GET请求,例如http://192.168.1.100/prices.json,获取到整个价格表,或者更精细地只请求该ID对应的信息。
    • 这样,修改价格只需要改服务器上的文件,无需重新给掌控板烧录程序。
  3. 模拟支付流程:可以结合掌控板的蓝牙功能,模拟与手机APP的通信。当点击“结账”时,掌控板通过蓝牙向手机发送总金额,手机APP弹出模拟支付界面,确认后,手机再通过蓝牙向掌控板发送“支付成功”指令,掌控板再显示成功信息。这就构成了一个完整的闭环体验。

5.3 项目复盘与核心收获

做完这个项目,再回头看,它不仅仅是一个“玩具”。它完整地串联了以下几个关键技术点:

  • 嵌入式感知:如何通过串口与智能传感器通信,获取物理世界的信息。
  • 状态机逻辑:如何设计程序逻辑来处理“等待->识别->添加->等待下一个”的循环,特别是防重复触发这种关键状态控制。
  • 人机交互:如何在资源受限(小屏幕、少量按键)的嵌入式设备上设计清晰、友好的用户界面和流程。
  • 系统思维:如何将硬件(传感器、主控板)、软件(识别算法、业务逻辑)、交互(显示、按键)整合成一个可工作的系统原型。

对于初学者来说,成功复现这个项目,你已经跨过了AIoT应用开发的第一道门槛。你会发现,很多复杂的商业应用(如智能货柜、自动分拣),其核心原型阶段的思路与此是相通的:感知->处理->执行->交互。

我个人在调试过程中,最大的教训就是状态管理。最初没有防重复触发机制,程序简直一团糟。这也让我深刻体会到,在事件驱动的嵌入式编程中,理清所有可能的状态和它们之间的转换条件,比写具体的功能代码更重要。画一个简单的状态转换图,往往能事半功倍。

最后,这个项目的所有代码和连接方式都是开源的、可复用的。你可以轻易地修改商品数据库、改变交互方式,甚至更换传感器(比如用RFID读卡器来识别商品),来创造属于你自己的“智能收银”或“物品管理”系统。动手去试,在解决问题的过程中学习,这才是创客精神的精髓。