1. 项目背景与设计思路

大家好,今天我想分享一个基于STM32的智能电子秤项目。这个项目是我在实际工作中总结出来的经验,特别适合嵌入式开发新手和物联网爱好者。我记得第一次做电子秤的时候,踩过不少坑,比如传感器读数不稳定、蓝牙连接经常断开等问题。经过多次调试和改进,终于做出了一个稳定可用的版本。

智能电子秤不仅仅是简单的称重工具,它结合了嵌入式系统和物联网技术,可以实现重量显示、单价设置、去皮功能、总价计算,还能通过蓝牙将数据发送到手机APP。这种设计思路特别适合超市、菜市场、厨房等场景,既实用又有科技感。

选择STM32作为主控芯片是因为它的性价比很高。STM32F103C8T6这款芯片价格便宜,性能足够强大,内置的ADC和丰富的GPIO接口非常适合做电子秤。再加上HX711高精度称重模块,测量精度可以达到0.1克,完全满足日常使用需求。

2. 硬件设计与元器件选型

2.1 核心元器件清单

做这个项目需要准备一些基本的硬件模块。这些都是市面上常见的元件,价格不贵,容易买到。以下是必备的元器件列表:

元器件名称规格型号数量备注
主控芯片STM32F103C8T61最小系统板即可
称重模块HX711124位高精度ADC
显示屏幕0.96寸OLED1I2C接口,128x64分辨率
蓝牙模块JDY31-SPP1支持串口透传
按键模块4x4矩阵按键1用于输入和设置
蜂鸣器无源蜂鸣器1提供声音反馈
称重传感器应变式传感器15kg量程

2.2 硬件连接详解

硬件连接其实很简单,主要是各个模块与STM32的引脚对接。我建议先用杜邦线连接测试,稳定后再考虑做PCB板。下面是具体的连接方式:

HX711模块需要连接4个引脚:VCC接3.3V,GND接地,DT接PA0,SCK接PA1。OLED屏幕更简单,只有4个引脚:VCC和GND接电源,SDA接PB7,SCL接PB6。蓝牙模块的TX接STM32的RX(PA10),RX接TX(PA9)。矩阵按键接在PA0-PA3和PA4-PA7上。

在实际焊接时,有几点需要注意:电源线要足够粗,避免因电流不足导致读数不稳定;传感器信号线要远离电源线,防止干扰;所有接地引脚最好共地,减少噪声。

3. 软件架构与核心代码

3.1 程序框架设计

软件部分采用模块化设计,这样便于调试和维护。整个程序分为初始化、主循环和中断处理三大部分。初始化包括各个外设的配置,主循环负责状态检测和显示更新,中断处理主要用于按键扫描和重量采集。

我先说说初始化部分。上电后,首先初始化系统时钟,设置HSE为时钟源,配置系统时钟为72MHz。然后初始化GPIO,设置按键和传感器引脚为输入,屏幕和蜂鸣器引脚为输出。接着初始化OLED屏幕,显示欢迎界面。最后初始化HX711模块,进行自校准。

主循环中主要做三件事:读取重量值、检测按键输入、更新显示。重量读取每100ms一次,通过HX711_Read函数获取原始数据,然后换算成实际重量。按键检测使用矩阵扫描方式,识别按下的是哪个键。显示更新包括重量、单价、总价的实时显示。

3.2 关键代码解析

重量读取是最核心的部分。HX711模块输出的是24位原始数据,需要转换成实际重量。我先获取皮重(空载时的读数),然后用当前读数减去皮重,再乘以校准系数。校准系数需要实际测量得出,我的经验值是1.73左右。

float Get_Weight(float base_weight)
{
    long adc_value = HX711_Read();
    float weight = (adc_value - base_weight) * 1.73 / 1000;
    if(weight < 0.5) weight = 0; // 去除微小干扰
    return weight;
}

按键处理也很重要。我设置了四个功能键:设置、确认、去皮、清零。设置键用于输入单价,确认键保存设置,去皮键去除容器重量,清零键重置所有数据。按键消抖采用延时方式,简单有效。

蓝牙数据传输使用串口中断方式。当有重量更新时,自动通过蓝牙发送数据到手机端。数据格式为JSON字符串,包含重量、单价、总价等信息。手机APP接收到数据后解析并显示。

4. 传感器校准与数据处理

4.1 校准原理与方法

传感器校准是保证精度的关键步骤。HX711模块虽然精度很高,但每个传感器都有个体差异,需要单独校准。我采用两点校准法:先记录空载时的读数(皮重),再记录已知重量(如500克砝码)的读数,计算校准系数。

校准公式很简单:系数 = 已知重量 / (测量读数 - 皮重)。比如空载时读数为10000,放上500克砝码后读数为20000,那么系数就是500 / (20000-10000) = 0.05。实际使用时,用当前读数减去皮重,再乘以这个系数就得到实际重量。

为了提高精度,我通常取多个读数求平均值。每次测量时连续读取10次,去掉最大最小值后取平均。这样能有效减少随机误差。温度变化也会影响读数,所以在温度变化大的环境中,需要定期重新校准。

4.2 数据处理算法

原始数据需要经过滤波处理才能使用。我尝试过多种滤波算法,发现移动平均滤波最适合这个场景。设置一个数组存储最近10次读数,每次取平均值作为最终结果。这种算法简单有效,计算量小。

#define FILTER_SIZE 10
float weight_buffer[FILTER_SIZE];
int buffer_index = 0;

float Filter_Weight(float raw_weight)
{
    weight_buffer[buffer_index] = raw_weight;
    buffer_index = (buffer_index + 1) % FILTER_SIZE;
    
    float sum = 0;
    for(int i=0; i<FILTER_SIZE; i++){
        sum += weight_buffer[i];
    }
    return sum / FILTER_SIZE;
}

除了滤波,还要处理一些特殊情况。比如突然的重量变化可能是干扰,需要忽略;长时间重量不变可以进入省电模式;重量超过量程时要报警提示。这些逻辑都在主循环中实现。

5. 物联网功能实现

5.1 蓝牙通信配置

JDY31-SPP蓝牙模块使用很简单,只需要接VCC、GND、TX、RX四个引脚。模块默认波特率是9600,支持AT指令配置。我通常将模块名称改为"SmartScale",这样手机容易识别。

蓝牙数据传输采用串口透传模式,所有发送到串口的数据都会自动转发到蓝牙,反之亦然。数据格式我选择JSON,因为易于解析和扩展。每次重量更新时,发送类似{"weight":1250,"unit":"g"}的字符串。

手机端需要开发一个APP来接收数据。我使用Android Studio开发,主要功能包括蓝牙连接、数据接收、显示和存储。连接时先扫描周边设备,找到"SmartScale"后配对连接。建立连接后就可以接收数据了。

5.2 手机APP开发

APP界面设计很简单,主要显示当前重量、单价、总价,还有历史记录图表。重量实时更新,单价可以通过手机输入,总价自动计算。历史记录用折线图显示,方便查看变化趋势。

数据存储使用SQLite数据库,记录每次称重的时间、重量、单价等信息。可以按时间查询历史记录,支持导出为CSV文件。我还添加了重量报警功能,超过设定值会振动提醒。

为了提升用户体验,我增加了多语言支持(中英文切换)、主题切换(亮色/暗色模式)、单位切换(克/千克/磅)。这些功能虽然简单,但很实用。

6. 实际应用与优化建议

6.1 常见问题解决

在实际使用中,可能会遇到各种问题。最常见的是读数不稳定,重量跳变。这通常是电源噪声或机械振动导致的。解决方法包括:给电源加滤波电容、传感器加减震垫、软件增加滤波算法。

蓝牙连接不稳定也是个常见问题。距离稍远就断开连接,或者数据传输中断。可以尝试以下方法:确保蓝牙天线周围没有金属遮挡、降低数据传输频率、增加数据重发机制、在手机端做超时重连。

功耗优化也很重要。如果使用电池供电,需要尽可能降低功耗。我的做法是:无操作时进入睡眠模式、降低屏幕亮度、减少蓝牙广播频率、使用低功耗元器件。这样可以使待机时间延长到一周以上。

6.2 功能扩展建议

基础功能实现后,可以考虑一些扩展功能。比如添加温度传感器,自动补偿温度对测量的影响;增加RFID模块,自动识别商品并获取单价;连接云服务器,实现数据远程备份和共享。

另一个方向是提升用户体验。比如添加语音播报功能,读出重量和价格;支持多种支付方式,集成扫码支付;增加机器学习算法,自动识别物品类型。这些功能可以让电子秤更加智能化。

我还尝试过将多个电子秤组网,用于智能仓储管理。每个秤作为一个节点,通过WiFi连接到中央服务器,实时监控库存变化。这种方案在小型仓库中很实用,成本低且易于部署。

最后,开源项目的意义在于共享和改进。我已经将完整代码和设计文件开源,欢迎大家一起完善这个项目。在实际使用中遇到问题或者有好的建议,都可以在项目仓库中提出。共同改进才能做出更好的产品。

Logo

北京人形旗下天工造物具身智能开源社区,聚焦具身天工与慧思开物两大平台

更多推荐