一、前言
1.1 项目介绍
【1】项目开发背景
随着卷烟零售终端数量的不断增加,烟草公司客户经理在市场走访、终端盘点和订单核对过程中,需要对客户店铺内的卷烟库存进行快速、准确的统计。传统的人工盘点方式主要依赖于目测或逐盒点数,这种方式不仅耗时耗力,而且容易出错,尤其在客户经营多种卷烟品牌的情况下,盘点效率更低,数据准确性难以保证。这种现状迫切需要一种高效、智能化的工具来提升盘点效率和准确性。
近年来,随着嵌入式系统与传感器技术的发展,基于STM32的智能测量与数据处理方案逐渐成熟,低功耗蓝牙通信与手机端应用程序的结合也为现场数据的实时传输和管理提供了可能。卷烟作为标准化程度较高的商品,其包装规格统一,单盒卷烟的宽度在同一品牌中基本保持一致,因此通过测量排放长度并结合盒宽换算盒数,成为一种可行且高效的解决方案。
本项目正是基于这种需求背景提出的,旨在设计一款基于STM32的智能数显卷烟盘点尺。该工具集成了红外光感测量技术、OLED数显显示、蓝牙无线传输和可充电电池供电等功能,可将测量结果实时显示并传输至手机APP。在手机端,应用程序能够自动关联品牌信息并记录数据,与客户订单进行对照,从而大幅提升盘点效率与准确性。通过本系统的应用,能够显著降低人工劳动强度,减少人为误差,为烟草行业的终端管理和信息化建设提供有效的技术支撑。



以下是使用 Mermaid 语法绘制的项目框架图,包含硬件模块、功能逻辑及数据流关系:
图表说明:
- 硬件模块:以STM32为核心,连接传感器、显示、蓝牙等外设。
- 软件功能:涵盖测量计算、显示、通信等核心逻辑。
- 数据流向:展示传感器信号采集→STM32处理→显示/蓝牙传输→手机APP反馈的闭环流程。
- 电源管理:电池电压通过ADC反馈至STM32,实现电量监控。
【2】设计实现的功能
(1)通过红外光感传感器测量卷烟排放的总长度。 (2)STM32对传感器脉冲信号进行计数和运算,按所选品牌的盒宽换算为卷烟盒数。 (3)在0.96寸SPI OLED显示屏上显示测量的长度。 (4)通过JDY-23低功耗蓝牙模块将测量长度数据实时发送至手机。 (5)在手机APP中接收数据,完成盒数的计算与记录,并自动关联对应品牌。 (6)系统采用锂电池供电,支持Type-C接口充电,同时具备电量检测与显示功能。 (7)蜂鸣器在测量确认时发出提示音,辅助用户操作反馈。
【3】项目硬件模块组成
(1)主控芯片:STM32F103RCT6(72MHz,256KB Flash,48KB RAM)。 (2)测量传感器:红外测距传感器(分辨率0.01mm,TTL脉冲输出)。 (3)显示模块:0.96寸SPI OLED显示屏(分辨率128×64)。 (4)通信模块:JDY-23 BLE低功耗蓝牙模块(UART接口,蓝牙5.0)。 (5)供电模块:3.7V 2000mAh锂电池 + TP4056充电管理模块 + AMS1117-3.3稳压电路。 (6)电源接口:Type-C USB接口(用于充电与调试)。 (7)蜂鸣器模块:有源蜂鸣器(高电平触发,测量确认提示音)。 (8)电量检测模块:电阻分压电路采集电池电压,由STM32 ADC检测。 (9)硬件结构:长方形ABS外壳,内置导轨固定测量传感器,主板采用洞洞板焊接,杜邦线辅助连接。
【4】设计意义
本项目的设计旨在解决传统卷烟盘点过程中效率低、误差率高的问题。以往人工盘点主要依靠逐盒点数或目测,不仅耗费大量时间,还容易因为疏忽或操作不规范导致数据不准确,进而影响客户订单的核对和库存管理。通过引入基于STM32的智能数显卷烟盘点尺,能够利用传感器对卷烟排放长度进行快速测量,并结合卷烟品牌的标准盒宽自动换算出盒数,从根本上提升盘点工作的速度和精度。
同时,项目通过蓝牙模块实现测量数据与手机APP的实时交互,使盘点数据能够快速记录和整理,避免人工抄录带来的二次错误。这种方式不仅优化了数据传输过程,也为客户经理在市场走访和终端管理中提供了可靠的技术支持,有助于实现卷烟库存信息的数字化管理。
此外,设备本身具备数显显示与便携化供电功能,保证了在不同场景下的可用性与便利性。整体设计充分结合了嵌入式技术、传感器技术和无线通信技术,体现了现代信息化手段在烟草行业应用中的实际价值,对推动零售终端管理的智能化和高效化具有重要意义。
【5】市面上同类产品研究现状
目前,卷烟盘点和库存管理主要依赖人工方式或条码扫描设备,真正专门针对卷烟盒数快速测量的智能化工具较少,市场上现有的相关产品主要可以分为以下几类:
条码扫描类设备。部分烟草公司在市场走访时配备了手持式扫码枪或PDA终端,通过逐盒或逐条扫描卷烟的条形码来统计数量。这类设备在数据采集上比较准确,并且能够直接与订单或后台数据库进行匹配。然而,该方法需要逐一扫描,操作时间长,效率较低,尤其在卷烟种类繁多、数量较大的零售终端,盘点工作往往十分耗时。
数显量具类产品 。在工业领域,已经存在广泛应用的光栅尺、磁栅尺和数显卡尺等测量工具,例如三丰(Mitutoyo)数显卡尺 和上量数显卡尺。这类产品能够实现高精度的长度测量,普遍采用光栅传感器作为核心部件,测量精度可达0.01mm,并且配有液晶或OLED屏幕显示测量结果。这类产品成熟稳定,但它们主要用于工业零件测量,并未结合卷烟规格进行盒数换算,也没有数据无线传输与卷烟库存管理的功能。
智能点数与称重设备 。在部分烟草零售管理环节中,已有企业尝试利用称重法来估算卷烟数量。例如通过电子秤称量一定数量的卷烟重量,再通过单盒重量换算盒数。这种方法虽然能在某些场景下使用,但受包装重量差异、环境因素影响较大,准确度不如基于标准盒宽的长度测量方式。
市面上的现有产品要么停留在人工点数和扫码的阶段,要么是通用的工业测量工具,缺乏针对卷烟盘点的专用设计。目前还没有一种既能高精度测量、又能结合卷烟规格自动换算盒数,并实现与移动终端实时交互的便携式工具。本项目的设计正好填补了这一市场空白,通过结合STM32控制、传感器测量和蓝牙无线通信,实现了一种真正适配卷烟盘点需求的智能数显测量工具,具有较强的实用价值和应用前景。
【6】摘要
本项目设计并实现了一种基于STM32的智能数显卷烟盘点尺。该设备采用红外光感传感器对排放的卷烟总长度进行精确测量,并利用STM32单片机对传感器脉冲信号进行处理与运算,根据所选品牌卷烟的标准盒宽自动换算为盒数。测量结果通过0.96寸OLED显示屏进行实时显示,同时借助JDY-23低功耗蓝牙模块将数据无线传输至手机APP。在手机端,应用程序能够接收并记录测量结果,自动关联至不同品牌信息并与订单数据进行匹配,实现卷烟库存的快速盘点与数字化管理。系统采用锂电池供电,支持Type-C接口充电,并集成电量检测与提示功能,保证设备在实际应用中的便携性与稳定性。研究表明,该设计能够有效提升卷烟盘点的效率与准确性,减少人工统计误差,具有较高的推广应用价值。
关键字: STM32;卷烟盘点;红外光感传感器;蓝牙通信;OLED显示;Qt应用
1.2 设计思路
本项目的核心设计思路是利用传感器实现卷烟排放长度的快速测量,并通过嵌入式处理器完成数据运算与传输,从而实现卷烟盒数的智能化盘点。考虑到卷烟盒宽度标准化的特点,可以通过测量排放总长度并除以单盒宽度来得到盒数,这种方法避免了逐盒点数的繁琐过程,提升了盘点效率。
在硬件层面,选用STM32F103RCT6作为主控芯片,负责采集红外光感传感器输出的脉冲信号,并进行数据处理与运算。测量结果由0.96寸OLED显示屏实时显示,方便用户在现场直观查看。为了实现与外部设备的交互,设计中集成了JDY-23低功耗蓝牙模块,通过UART接口与STM32通信,将测量数据实时传输至手机APP。供电部分采用3.7V锂电池,配合TP4056充电管理模块和AMS1117-3.3稳压电路,实现便携式供电与电量监测。
在软件层面,STM32端采用C语言编程,通过寄存器方式完成对传感器信号的计数、数据运算、显示刷新和蓝牙通信控制。手机端开发APP,能够接收来自蓝牙的数据,并结合事先存储的卷烟品牌信息,自动完成盒数计算和记录。APP还支持品牌切换与数据保存,为后续订单对比和库存管理提供便利。
整体设计思路强调硬件与软件的紧密结合,既保证了测量的高精度和实时性,又实现了与移动端的无缝交互,从而构建出一套高效、便捷、实用的卷烟盘点工具。
1.3 系统功能总结
功能类别 | 实现内容 | 承担模块/实现方式 |
---|---|---|
测量功能 | 对排放的卷烟总长度进行精确测量 | 红外光感传感器 + STM32计数运算 |
数据换算 | 根据所选品牌卷烟盒宽,自动换算为盒数 | STM32数据处理程序 |
显示功能 | 在0.96寸OLED上实时显示长度与盒数 | SPI OLED显示模块 |
通信功能 | 将测量数据实时传输至手机端 | JDY-23低功耗蓝牙模块(UART通信) |
手机端处理 | 接收并记录测量数据,自动匹配对应卷烟品牌信息 | 手机APP(Qt开发) |
电源管理 | 提供便携式电池供电,支持Type-C充电接口 | 3.7V锂电池 + TP4056充电模块 + AMS1117稳压 |
电量检测 | 采集电池电压并由STM32 ADC检测,显示电量状态 | 电阻分压电路 + STM32 ADC模块 |
操作提示 | 测量确认时发出提示音,辅助用户操作反馈 | 有源蜂鸣器 |
1.4 开发工具的选择
【1】设备端开发
硬件设备端的开发主要依赖于C语言,利用该语言直接操作硬件寄存器,确保系统运行的高效性和低延迟。C语言在嵌入式开发中具有广泛的应用,它能够直接访问硬件,满足对资源消耗和响应速度的严格要求。为了编写高效、稳定的代码,开发工具选择了Keil uVision 5作为主要的开发环境。Keil是一个专业的嵌入式开发工具,广泛应用于基于ARM架构的微控制器(如STM32)开发。Keil提供了完善的调试、编译和仿真支持,能够帮助在软件开发过程中高效地进行调试、单步执行以及断点设置,确保开发的稳定性和高效性。 STM32F103RCT6是项目中使用的主控芯片,它基于ARM Cortex-M3架构,拥有强大的计算能力和丰富的外设接口。在硬件编程中,寄存器级编程是常用的方式,这要求开发者对芯片的硬件寄存器有深入的理解。在Keil环境中,通过STM32的寄存器直接控制GPIO、ADC、I2C、SPI等硬件接口,以满足各个硬件模块(如传感器、执行器、显示屏等)与主控芯片的交互。使用寄存器编程能够提供更高效、精确的控制,避免了外部库的开销,同时也能深入调控硬件特性,提升系统性能。
【2】上位机开发
本项目的上位机开发基于Qt 5框架,使用**C++**作为主要编程语言。Qt是一个跨平台的应用开发框架,广泛用于开发GUI应用程序。Qt提供了丰富的GUI组件和工具,能够高效地实现图形界面的设计与开发。C++则作为Qt的底层语言,具有高效的性能和良好的控制力,非常适合用于处理设备与系统之间的数据交互、通信协议的实现和复杂的计算任务。在项目中,Qt被用于开发Windows平台的桌面应用程序以及Android平台的手机APP。Qt框架的跨平台特性使得开发者能够使用同一套代码在不同操作系统上进行构建和部署,大大提高了开发效率。
为了方便开发和调试,上位机的开发采用了Qt Creator 作为主要的集成开发环境(IDE)。Qt Creator是一款由Qt官方提供的开发工具,专为Qt应用程序开发设计,支持C++、QML和JavaScript等语言。Qt Creator提供了丰富的功能,如代码编辑、调试、构建、版本控制集成等,能够显著提升开发者的生产力。在本项目中,Qt Creator为开发者提供了自动化构建、界面设计工具(如Qt Designer)和调试工具(如QDebug和QML调试工具),使得开发过程更加高效和流畅。 上位机与硬件设备端的通信采用了基于TCP/IP协议的数据传输方式。为了实现这一功能,Qt提供了丰富的网络编程支持,尤其是QTcpSocket 和QTcpServer类,使得上位机能够轻松地与硬件设备建立TCP连接,进行数据收发。上位机通过WIFI连接ESP8266-WIFI模块,ESP8266模块创建TCP服务器,上位机应用则作为客户端连接到服务器,进行实时的数据传输与控制命令的下发。 为了满足不同用户的需求,本项目需要支持Windows平台的桌面应用和Android平台的移动APP。Qt的跨平台特性使得开发人员能够在一个代码库下完成多平台应用的开发和移植。开发者仅需要编写一次应用逻辑和用户界面,就可以通过Qt的跨平台构建工具生成Windows和Android两个平台的可执行文件。此外,Qt提供了丰富的文档和社区支持,帮助开发者解决平台差异和兼容性问题,确保应用在不同平台上都能稳定运行。
总体而言,上位机开发环境采用了Qt 5框架和C++语言,结合Qt Creator集成开发环境,提供了一个高效、稳定、跨平台的开发工具链。通过Qt强大的GUI设计、网络通信、多线程支持以及数据库管理功能,开发者能够轻松实现与硬件设备的交互、控制设备、处理传感器数据,并为用户提供直观、流畅的操作体验。
二、硬件选型
当前项目使用的相关软件工具、模块源码已经上传到网盘:ccnr8sukk85n.feishu.cn/wiki/QjY8we...
-
主控芯片:STM32F103RCT6
- 主频:72MHz
- Flash:256KB
- RAM:48KB
- 特点:高性能、低功耗、丰富的外设接口,适合嵌入式测量与控制应用。
-
测量传感器:红外测距传感器
- 分辨率:0.01mm
- 输出方式:TTL脉冲信号
- 特点:精度高、响应快、体积小,适合卷烟长度测量。
-
显示模块:0.96寸 SPI OLED显示屏
- 分辨率:128×64
- 特点:功耗低、显示清晰,可直观显示长度信息。
-
通信模块:JDY-23 BLE低功耗蓝牙模块
- 接口:UART
- 蓝牙版本:5.0
- 特点:低功耗、稳定可靠,实现与手机APP的实时数据传输。
-
供电模块:3.7V 2000mAh锂电池 + TP4056充电管理模块 + AMS1117-3.3稳压
- 功能:提供稳定电源,支持Type-C接口充电与电量监测。
-
提示模块:有源蜂鸣器
- 功能:测量确认提示音,辅助用户操作。
-
电量检测模块:电阻分压 + STM32 ADC采集
- 功能:实时监测电池电压,保证设备可靠运行。
-
硬件结构:长方形ABS外壳 + 导轨固定传感器 + 洞洞板焊接
- 功能:保证设备结构稳固、便携,同时便于硬件模块布局与连接。
三、Qt开发入门与环境搭建
当前项目的上位机是采用Qt开发的,这一章节主要是介绍Qt开发环境的安装,以及Qt开发环境入门的使用。如果你Qt没有任何基础,建议仔细看一遍。
3.1 Qt是什么?
Qt 是一个功能强大、跨平台的应用程序开发框架,主要用于创建图形用户界面(GUI)应用程序,但它不仅仅局限于GUI编程。它由挪威的奇趣科技(TrollTech)最初于1991年开发,并在后续的发展历程中经历了多次所有权变更,包括诺基亚和Digia等公司接手,现在Qt属于The Qt Company所有。
Qt 主要特点和优势包括:
(1)跨平台:Qt 支持多种操作系统,开发者可以使用同一份源代码在不同平台上编译运行,如Windows、Linux、macOS、Android以及各种嵌入式系统(如RTOS),实现"一次编写,到处编译"。
(2)C++ 开发:Qt 的核心是基于C++编程语言构建,提供了一套丰富的类库,通过面向对象的设计方式简化了开发过程。
(3)图形用户界面:Qt 提供了完整的GUI组件集,包含窗口、按钮、标签、文本框等各种标准控件,以及布局管理器、样式表等功能,使得开发者能够高效地创建美观且功能完善的桌面应用或移动应用界面。
(4)工具链完整:Qt 包含一系列集成开发环境(IDE)和辅助工具,例如Qt Creator是一个全能的跨平台IDE,Qt Designer用于可视化拖拽设计UI界面,Qt Linguist支持国际化资源文件的翻译,还有Qt Assistant和大量文档资源方便开发者的使用。
(5)非GUI功能丰富:除了GUI功能外,Qt 还提供了众多非图形化功能模块,如网络通信、数据库访问、XML处理、多媒体处理(音频视频)、文件I/O、线程与并发处理、OpenGL和3D图形渲染等。
(6)元对象系统:Qt 使用元对象系统(Meta-Object System, MOC)实现了信号与槽机制(Signals and Slots),这是一种高级事件处理机制,允许在不同对象之间安全地进行异步通信。
(7)可扩展性与灵活性:Qt 架构高度灵活,支持插件体系结构,开发者可以根据需要自定义组件并轻松地集成到Qt应用中。
Qt 以其强大的跨平台能力和全面的功能集合成为许多企业和个人开发者选择用来开发高性能、高稳定性的应用程序的重要工具之一,被广泛应用于各类桌面软件、嵌入式设备、移动应用以及服务器端组件等领域。
3.2 Qt版本介绍
在Qt发行版本中将要涉及两个版本:Qt商业授权和Qt开源授权。
(1)Qt商业授权是设计商业软件的开发环境,这些商业软件使用了传统的商业来发布,它包含了一些更新的功能、技术上的支持和大量的解决方案,开发了使用于行业的一些特定的组件,有一些特殊的功能只在商业用户中使用。
(2)Qt开源授权是用来开发开源的软件,它提供了一些免费的支持,并遵循QPL协议。
开放源代码是免费的软件,不牵涉用户的某些权益。任何人都有使用开源软件和参与它的修改的机会,这就意味着其他的人同样可获得你开发的代码。目前 Qt 的开源授权有两种,一种是 GPL 授权,另一种是 LGPL 授权。
3.3 Qt开发环境安装
Qt的中文官网: www.qt.io/zh-cn/
QT5.12.6的下载地址:download.qt.io/archive/qt/...
打开下载链接后选择下面的版本进行下载:
qt-opensource-windows-x86-5.12.6.exe 13-Nov-2019 07:28 3.7G Details
软件安装时断网安装,否则会提示输入账户。
如果下载不了,可以在网盘里找到安装包下载: 飞书文档记录的网盘地址:ccnr8sukk85n.feishu.cn/wiki/QjY8we...
安装的时候,第一个复选框里勾选一个mingw 32
编译器即可,其他的不管默认就行,直接点击下一步继续安装。

选择MinGW 32-bit 编译器:

3.4 开发第一个QT程序
在QT开发过程中,可以手动编写代码也可以使用UI设计师直接拖拽控件的方式编写界面和布局,在实际的开发过程中一般是两种方式结合使用,提高开发效率。
本小节用一个简单的 "Hello QT" 程序介绍一下使用QtCreator新建工程的步骤。
(1)打开QtCreator软件,选择New Project,新建一个工程。

(2)项目模板选择QT Widgets Application

(3)设置项目名称和存放路径
注意:QT项目路径和名称不能出现中文字符。

(4)编译工具套件选择
编译工具套件可以后面自己增加,比如增加Android的。套件是指 Qt 程序从编译链接到运行环境的全部工具和 Qt 类库的集合。

(5)设置生成的类信息
在类信息设置界面选择基类,目前有三种基类:QMainWindow,QWidget,QDialog。在基类里选择QMainWindow,类名和文件名会根据基类自动修改,一般不需要修改,默认即可。

(6)项目管理
在项目管理界面可以设置作为子项目,以及加入版本控制系统。这两个功能暂时用不到,都用默认的 ,然后点击 "完成"。

(7)创建完成

(8) 编辑代码
展开main.cpp文件,添加内容如下:
cpp
#include "mainwindow.h"
#include <QApplication>
#include <QDebug>
#include <QLabel>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
//MainWindow w;
//w.show();
QLabel *label =new QLabel("Hello Qt!");
label->setGeometry(400,100,100,20);
label->show();
return a.exec();
}
代码解析:
cpp
1) #include <QApplication>和 #include <QLabel>是QT的类声明头文件,对于每个QT类都有一个与该类同名的头文件,在这个头文件包含了对该类的定义。
2) main(int argc, char *argv[]) :main函数的标准写法。
3) QApplication a(argc, argv):创建一个QApplication对象,用于管理应用程序的资源,QApplication类的构造函数需要两个参数。
4) QLabel *label =new QLabel("Hello Qt!") :创建QLabel窗口部件,QLabel是一个Qt提供的窗口部件,可以用来显示一行文本。
5) label->setGeometry(400,100,100,20) : 设置控件显示的位置。
6) label->show():使Qlabel创建的窗口可见,就是显示设置的文本。
7) return a.exec():应用程序将控制权传递给QT,让程序进入消息循环。等待可能的菜单,工具条,鼠标等的输入,进行响应。

(9)行程序
运行程序可以点击左下角的三角形符号或者按下快捷键Ctrl+R。

3.5 调试输出
QT中使用QDebug类输出调试信息。主要用于调试代码,类似于std::cout的替代品,支持QT的数据类型。使用前需要包含头文件。
调试输出的分类
qDebug | 调试信息提示 |
---|---|
qWarning | 一般的警告提示 |
qCritical | 严重错误提示 |
qFatal | 致命错误提示 |
示例代码:
cpp
qDebug("调试信息输出");
qWarning("一般警告信息输出");
qCritical("严重错误输出");
qFatal("致命错误输出");
qDebug输出的信息会打印到QT软件下边的输出面板。
在上节的HelloQt工程上加上调试输出代码,增加的main.cpp代码如下:
cpp
#include "mainwindow.h"
#include <QApplication>
#include <QDebug>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
//MainWindow w;
//w.show();
qDebug()<<"QT调试信息输出";
int data_int=8888;
qDebug()<<data_int;
float data_float=123.888;
qDebug()<<data_float;
return a.exec();
}
运行程序,观察输出的调试信息:

3.6 QT Creator常用的快捷键
掌握一些适用的快捷键,可以提高程序开发的效率。
(1)F1 键,快速切换光标选中的函数或者类的帮助信息,按一次半屏显示,按下两次全屏显示。
(2)F2 键,快速切换到光标选中的函数或者类的源码定义处。
(3)F4键,快速在源文件和头文件之间切换。
(4)Ctrl(按住)+ Tab,快速切换已打开的文件
(5)Ctrl+ I ,缩进光标选中行代码(自动与上层代码对齐)。
(6)Ctrl + / ,快速注释或者取消注释光标选中行。
(7)快速修改全局变量名
鼠标光标选中变量名,按下Ctrl+Shift+R,当变量名称出现红色框表示已经激活全局修改功能。修改一处,整个工程对应变量名称全部会修改。修改完毕之后,光标移开,再按下Ctrl+Shift+R保存修改。

(8)快速修改全局函数名
快捷方式与变量修改一样按下Ctrl+Shift+R,一处修改整个工程对应的函数名称也会跟着改。选中函数后,按下Ctrl+Shift+R后整个工程的对应的函数名会高亮,并且在软件下方弹出修改框。

3.7 QT帮助文档
Qt 帮助文档太多,难以全部翻译成中文,即使翻译了一部分,翻译花的时间太多,翻译更新的时效性也难以保证,最终还是得看英文帮助,QtCreator 集成了帮助系统,查找非常方便。
打开QtCreator,选择菜单栏的最左边的帮助选项,界面如下:

(1)查看Qlabel控件的帮助信息:

3.8 UI设计师使用
上节的Hello QT程序使用纯C++代码编写,这一节使用QT界面设计模式实现与上一节Hello QT程序
一样的功能。仿照着上节新创建一个工程。双击打开mainwindow.ui
文件,进入到UI设计界面。
(1)拖一个Label控件到编辑区,双击Label控件可以修改文本内容。

(2)运行程序可以点击左下角的三角形符号或者按下快捷键Ctrl+R。

(3)UI设计师界面功能介绍

3.9 按钮控件组
QT Creator UI设计师界面的按钮组截图如下:

以下是对按钮组控件的一些功能介绍:
(1)Push Button按压按钮:最普通的按钮,按(点击)按钮命令计算机执行一些动作,或者回答问题,比如windows开始菜单里的重启,注销,关机等按钮。
(2)Tool Button工具按钮:工具按钮通常是一个集合,一般集成在工具栏里。比如打开,保存,复制,粘贴,剪切等常用的操作。
(3)Radio Button单选按钮:单选按钮通常是两个以上的形式出现在一块,按钮之间有互斥关系,每次只能选中一个。比如:一个人的性别只能选择一个,不能同时是男性又是女性。
(4)Check Box复选框:复选框与单选按钮概念相反,复选框通常表示多个可以同时存在的选项,比如一个人可以同时拥有多个爱好,比如读书、看电影、爬山、游泳等。
(5)Command Link Button命令链接按钮:一般用来打开的窗口或者网页链接。
(6)Dialog Button Box标准按钮盒:标准按钮盒通常用于对话框程序;比如:常见的确认对话框有 "确定""取消"等标准按钮,Qt 将这些典型的按钮做成标准按钮盒,并将相应的信号加以封装,方便程序员使用。
3.10 布局控件组
开发一个图形界面应用程序,界面的布局影响到界面的美观。前面的程序中都是使用UI界面拖控件,如果有多个按钮,会出现大小难调整、位置难对齐等问题。Qt 提供的"布局管理"就很好的解决了控件摆放的问题。
以下是UI设计师界面的布局相关控件组:

功能介绍:
(1)Vertical Layout:垂直布局
(2)Horizontal Layout:水平布局
(3)Grid Layout:网格布局
(4)Form Layout:窗体中布局
(5)Horizontal Spacers:水平空格,在布局中用来占位。
(6)Vertical Spacer:垂直空格,在布局中用来占位。

3.11 基本布局控件
在UI设计界面添加一个布局控件,然后将需要布局的其他控件放入布局控件中即可完成布局,布局控件可以互相嵌套使用。(本节只介绍基本布局控件的使用)
以下是4种布局控件的效果:

3.12 UI设计师的布局功能
在UI设计界面的左上角有一排快捷的布局选项,使用时选中两个以上的控件,点击其中一种布局方式就可以切换布局。
以下为布局的简单示例图:

(1)为布局的选项。
(2)控件层次图,可以看到控件的布局摆放层次。
如果想要控制某个控件的固定大小,不随着布局改变大小,可以限定最大最小尺寸。选中控件鼠标右键-->大小限定->设置大小。

水平布局与垂直布局:


水平布局将控件按照水平方式摆放,垂直布局将控件按照垂直方式摆放。鼠标拖动红色布局框上的黑色方点,可以调整布局框的大小。随着布局框的尺寸变化,包含的控件高度不会变化,宽度会随着布局框变化。选中其中一个控件然后鼠标右键>点击大小限定,可以限定控件的最大和最小尺寸。
分裂器水平布局与垂直布局:


分裂器方式布局,包含控件的高度和宽度都会随着布局框的拉伸而改变。选中其中一个控件然后鼠标右键>点击大小限定,可以限定控件的最大和最小尺寸。
窗体中布局与栅格布局:

栅格(网格)布局器的基本单元是单元格,而窗体中布局(表单)的基本单元是行。随着布局框的尺寸变化,包含的控件高度不会变化,宽度会随着布局框变化。
设置主窗体布局方式:
设置主窗体的布局方式后,包含在主窗体内的控件会随着窗体的拉伸自动调整大小。


四、上位机开发
4.1 Qt开发环境安装
Qt的中文官网: www.qt.io/zh-cn/
QT5.12.6的下载地址:download.qt.io/archive/qt/...
打开下载链接后选择下面的版本进行下载:

如果下载不了,可以在网盘里找到安装包下载: 飞书文档记录的网盘地址:ccnr8sukk85n.feishu.cn/wiki/QjY8we...
软件安装时断网安装,否则会提示输入账户。
安装的时候,第一个复选框里的编译器可以全选,直接点击下一步继续安装。

选择编译器: (一定要看清楚了)

4.2 新建上位机工程
前面2讲解了需要用的API接口,接下来就使用Qt设计上位机,设计界面,完成整体上位机的逻辑设计。
【1】新建工程

【2】设置项目的名称。

【3】选择编译系统

【4】选择默认继承的类

【5】选择编译器

【6】点击完成

【7】工程创建完成

4.3 切换编译器
在左下角是可以切换编译器的。 可以选择用什么样的编译器编译程序。
目前新建工程的时候选择了2种编译器。 一种是mingw32
这个编译Windows下运行的程序。 一种是Android
编译器,可以生成Android
手机APP。
不过要注意:Android的编译器需要配置一些环境才可以正常使用,这个大家可以网上找找教程配置一下就行了。
windows的编译器就没有这么麻烦,安装好Qt就可以编译使用。
下面我这里就选择的 mingw32
这个编译器,编译Windows下运行的程序。

4.4 编译测试功能
创建完毕之后,编译测试一下功能是否OK。
点击左下角的绿色三角形按钮
。

正常运行就可以看到弹出一个白色的框框。这就表示工程环境没有问题了。 接下来就可以放心的设计界面了。

4.5 设计UI界面与工程配置
【1】打开UI文件

打开默认的界面如下:

【2】开始设计界面
根据自己需求设计界面。
4.6 设计代码
4.5 编译Windows上位机
点击软件左下角的绿色三角形按钮进行编译运行。

4.6 配置Android环境
如果想编译Android手机APP,必须要先自己配置好自己的Android环境。(搭建环境的过程可以自行百度搜索学习)
然后才可以进行下面的步骤。
【1】选择Android编译器
选择编译器。

切换编译器。

【2】创建Android配置文件



创建完成。

【3】配置Android图标与名称
根据自己的需求配置 Android图标与名称。

【3】编译Android上位机
Qt本身是跨平台的,直接选择Android的编译器,就可以将程序编译到Android平台。
然后点击构建。

成功之后,在目录下可以看到生成的apk
文件,也就是Android手机的安装包,电脑端使用QQ
发送给手机QQ,手机登录QQ接收,就能直接安装。
生成的apk
的目录在哪里呢? 编译完成之后,在控制台会输出APK文件的路径。
知道目录在哪里之后,在Windows的文件资源管理器里,找到路径,具体看下图,找到生成的apk文件。

cpp
File: D:/QtProject/build-333_QtProject-Android_for_arm64_v8a_Clang_Qt_5_12_6_for_Android_ARM64_v8a-Release/android-build//build/outputs/apk/debug/android-build-debug.apk
五、STM32代码设计
当前项目使用的相关软件工具、模块源码已经上传到网盘:ccnr8sukk85n.feishu.cn/wiki/QjY8we...
5.1 硬件连线说明
本系统硬件模块采用STM32F103RCT6作为核心控制器,各模块通过GPIO、ADC、UART和SPI接口与单片机连接,具体说明如下:
1. 红外测距传感器
- 接口说明:VCC、GND、OUT(TTL脉冲信号)
- 连线方式 :
- VCC → 3.3V 电源
- GND → GND
- OUT → STM32 GPIO输入口(例如PA0)
- 功能说明:传感器输出的脉冲信号被STM32计数,用于计算卷烟排放总长度。
2. OLED显示屏(0.96寸 SPI)
- 接口说明:VCC、GND、SCL、SDA(或CLK、MOSI、DC、CS、RES)
- 连线方式 :
- VCC → 3.3V
- GND → GND
- SCL/CLK → STM32 SPI时钟口(例如PA5)
- SDA/MOSI → STM32 SPI数据口(例如PA7)
- DC → STM32 GPIO输出口(例如PA8,用于数据/命令选择)
- CS → STM32 GPIO输出口(例如PA4,片选)
- RES → STM32 GPIO输出口(例如PA3,复位)
- 功能说明:显示测量的长度数据和提示信息,STM32通过SPI协议控制显示内容。
3. JDY-23 蓝牙模块
- 接口说明:VCC、GND、TXD、RXD
- 连线方式 :
- VCC → 3.3V
- GND → GND
- TXD → STM32 UART接收口 RX(例如PA10)
- RXD → STM32 UART发送口 TX(例如PA9)
- 功能说明:通过UART接口进行数据传输,将测量数据实时发送至手机APP。
4. 锂电池供电及充电模块
- 接口说明:电池正负极接TP4056充电模块,输出端接AMS1117-3.3稳压模块
- 连线方式 :
- 电池正极 → TP4056 B+
- 电池负极 → TP4056 B-
- TP4056 OUT+ → AMS1117 3.3V输入 → STM32 VCC
- TP4056 OUT- → STM32 GND
- 功能说明:为系统提供稳定3.3V电源,并可通过Type-C接口充电。
5. 电量检测模块
- 接口说明:电阻分压输出 → STM32 ADC输入口
- 连线方式 :
- 电池正极 → 电阻分压 → STM32 ADC口(例如PA1)
- 电阻分压接地 → GND
- 功能说明:STM32通过ADC采集电压信号,计算电池剩余电量并显示。
6. 按键模块
- 接口说明:按键一端接STM32 GPIO,另一端接GND
- 连线方式 :
- 按键1 → STM32 GPIO输入(PA2,品牌切换)
- 按键2 → STM32 GPIO输入(PA3,测量清零)
- 按键3 → STM32 GPIO输入(PA4,功能菜单)
- 功能说明:用户通过按键选择品牌、清零或操作功能菜单,STM32检测按键触发状态。
7. 蜂鸣器模块
- 接口说明:VCC、GND、信号端
- 连线方式 :
- VCC → 3.3V
- GND → GND
- 信号端 → STM32 GPIO输出口(例如PB0)
- 功能说明:STM32输出高电平信号触发蜂鸣器,用于测量确认或提示操作状态。
8. 硬件布局
- 主板:洞洞板焊接,各模块通过杜邦线连接
- 结构:长方形ABS外壳内置导轨固定红外测距传感器,保证传感器与卷烟排放对齐
- 电源线 、信号线 、通信线布线整齐,确保抗干扰和便携性
5.2 传感器代码
下面是 STM32F103RCT6 的红外测距传感器完整驱动示例代码,采用寄存器方式编程,通过 GPIO 捕获脉冲信号并计算卷烟排放长度。
头文件和 C 文件,并可直接在 Keil5 中使用。
sensor.h
c
#ifndef __SENSOR_H
#define __SENSOR_H
#include "stm32f10x.h"
#define SENSOR_GPIO_PORT GPIOA
#define SENSOR_GPIO_PIN GPIO_Pin_0
#define SENSOR_GPIO_CLK RCC_APB2Periph_GPIOA
// 每个脉冲对应的单位长度(mm),根据传感器精度设置
#define PULSE_LENGTH_MM 0.01
void Sensor_GPIO_Init(void);
void Sensor_EXTI_Init(void);
uint32_t Get_Length(void);
void Reset_Length(void);
extern volatile uint32_t pulse_count;
#endif
sensor.c
c
#include "sensor.h"
volatile uint32_t pulse_count = 0; // 记录脉冲数
/**
* @brief 初始化传感器GPIO口
*/
void Sensor_GPIO_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(SENSOR_GPIO_CLK, ENABLE);
GPIO_InitStructure.GPIO_Pin = SENSOR_GPIO_PIN;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD; // 下拉输入
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(SENSOR_GPIO_PORT, &GPIO_InitStructure);
}
/**
* @brief 配置外部中断,用于捕获传感器脉冲
*/
void Sensor_EXTI_Init(void)
{
EXTI_InitTypeDef EXTI_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
GPIO_InitTypeDef GPIO_InitStructure;
// GPIO口复用
Sensor_GPIO_Init();
// 连接到外部中断线
GPIO_EXTILineConfig(GPIO_PortSourceGPIOA, GPIO_PinSource0);
EXTI_InitStructure.EXTI_Line = EXTI_Line0;
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising; // 上升沿触发
EXTI_InitStructure.EXTI_LineCmd = ENABLE;
EXTI_Init(&EXTI_InitStructure);
NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
}
/**
* @brief 外部中断服务函数
*/
void EXTI0_IRQHandler(void)
{
if(EXTI_GetITStatus(EXTI_Line0) != RESET)
{
pulse_count++; // 每个脉冲计数+1
EXTI_ClearITPendingBit(EXTI_Line0);
}
}
/**
* @brief 获取测量长度(单位:盒数或毫米)
*/
uint32_t Get_Length(void)
{
// 脉冲数 × 每脉冲长度 = 总长度(mm)
return (uint32_t)(pulse_count * PULSE_LENGTH_MM);
}
/**
* @brief 重置脉冲计数
*/
void Reset_Length(void)
{
pulse_count = 0;
}
5.3 项目核心代码
main.c 示例调用
c
#include "stm32f10x.h"
#include "sensor.h"
#include "oled.h" // OLED显示屏驱动
#include "usart.h" // 蓝牙模块串口驱动
int main(void)
{
uint32_t length_mm;
SystemInit();
Sensor_EXTI_Init(); // 初始化传感器中断
OLED_Init(); // OLED初始化
USART1_Init(9600); // 串口1用于蓝牙通信
while(1)
{
length_mm = Get_Length(); // 获取长度
// 显示在OLED上
OLED_Clear();
OLED_ShowString(0, 0, "Length(mm):");
OLED_ShowNum(0, 2, length_mm, 6);
// 通过蓝牙发送数据
char buffer[20];
sprintf(buffer, "%lu\n", length_mm);
USART1_SendString(buffer);
// 延时100ms更新
Delay_ms(100);
}
}
该代码实现了:
- 红外传感器脉冲捕获
- 脉冲计数转换为长度
- OLED显示长度
- 通过串口发送数据到蓝牙模块
5.4 程序下载
也有视频教程:
讲解如何编译代码,下载STM32程序: www.bilibili.com/video/BV1Cw...
打STM32的keil工程,编译代码、然后,使用USB线将开发板的左边的USB口(串口1)与电脑的USB连接,打开程序下载软件下载程序。
具体下载过程看下面图:

打开程序下载软件:[软件就在资料包里的软件工具目录下]

5.5 程序正常运行效果
设备运行过程中会通过串口打印调试信息,我们可以通过串口打印了解程序是否正常。
程序下载之后,可以打开串口调试助手查看程序运行的状态信息。[软件就在资料包里的软件工具目录下]

5.6 取模软件的使用
显示屏上会显示中文,字母,数字等数据,可以使用下面的取模软件进行取模设置。
软件就在资料包里的软件工具目录下

打开软件之后:

六、总结
本项目设计并实现了基于STM32的智能数显卷烟盘点尺,成功将长度测量、盒数换算、实时显示和无线数据传输功能集成于一体。通过红外光感传感器实现对卷烟排放长度的高精度测量,STM32单片机对测量数据进行快速处理,并按不同品牌的标准盒宽自动换算为盒数。测量结果可在OLED显示屏上实时显示,同时通过蓝牙模块发送至手机APP,实现数据的即时记录与品牌匹配。
系统采用锂电池供电,支持Type-C充电接口,并具备电量检测与操作提示功能,保证了设备在实际应用中的便携性和可靠性。项目的软件部分包括STM32固件程序与手机APP,二者紧密协作,实现了从数据采集到信息管理的完整闭环。
通过该设计,可以显著提升卷烟终端盘点的效率和准确性,减少人工操作误差,为烟草零售管理提供了一种高效、智能的技术手段。整体方案结构合理、功能完善,具有较高的实用价值和推广应用前景。