当前位置: 首页 > news >正文

STM32F103C8T6称重传感器HX711模块压力传感器称重的使用方法和代码驱动

STM32F103C8T6称重传感器HX711模块压力传感器称重的使用方法和代码驱动

文档结尾有代码下载链接

🎯 实现效果

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

🌟 传感器用途

称重传感器的核心价值是“将重量信息数字化、可量化”,结合HX711和单片机后,能实现从“单纯称重”到“智能监测与控制”的延伸,覆盖民用、工业、智能硬件、医疗等多个领域。

1.民用消费场景

  • 家庭日常称重:家用电子体重秤(通过4个分布式传感器测量体重、体脂率,HX711负责同步采集各传感器信号)、厨房秤(称量食材克数,精度达1g,满足烘焙、辅食制作的精准配比需求)、宠物秤(监测宠物体重变化,辅助判断健康状况)。
  • 便携称重工具:行李秤(最大量程50kg,通过挂钩式传感器测量行李重量,避免航空托运超重)、钓鱼秤(称量渔获重量,带背光显示屏,适配户外使用)、珠宝秤(高精度达0.01g,采用小型应变式传感器,搭配HX711实现微量称重)。
  • 消费电子附件:智能水杯(内置微型传感器,监测饮水量变化,通过APP提醒补水)、快递打包秤(小型桌面秤,方便电商卖家快速称重计价)。

2. 工业生产场景

  • 生产线上的重量管控:食品饮料行业(瓶装饮料灌装后称重,检测是否漏灌、少灌,不合格产品自动剔除)、制药行业(药片/胶囊重量检测,确保每粒药量符合标准,避免药效不足或过量)、五金加工(零部件重量筛选,剔除材质不均的次品)。
  • 仓储物流与物料管理:仓库货架称重(在货架横梁安装传感器,实时监测货物重量,实现库存动态管理)、传送带物料流量监测(通过传感器连续称重传送带上的物料,换算单位时间内的输送量,优化生产节奏)、叉车称重(在叉车货叉上安装传感器,叉取货物时直接显示重量,无需额外过磅)。
  • 工业设备状态监测:机械臂抓取力检测(在机械臂末端安装小型传感器,通过抓取重量判断是否成功抓取物体,避免空抓或抓取过紧损坏工件)、机床切削负载监测(在机床主轴或工作台安装传感器,监测切削过程中的重量变化,间接判断切削力,防止过载损坏设备)。

3. 智能硬件与物联网场景

  • 智能家居与农业:智能花盆(传感器监测盆土+植物总重量,结合湿度传感器判断是否缺水,自动启动浇水装置)、智能垃圾桶(通过重量变化判断垃圾是否装满,满桶后推送提醒至用户手机)、温室大棚(监测作物生长过程中的重量变化,分析生长速率,优化水肥管理)。
  • 医疗健康设备:婴儿培养箱体重监测(内置高精度传感器,实时监测新生儿体重变化,数据同步至医护系统)、康复训练设备(如肌力训练器,通过传感器测量患者发力时的重量/压力,制定个性化康复方案)、输液重量监测(通过传感器监测输液袋重量,计算输液速度,快输完时报警提醒护士)。
  • 创意DIY与创客项目:自制自动喂料机(传感器检测料仓重量,低于阈值时启动电机补料)、智能快递柜称重模块(用户存件时自动称重,根据重量收取费用)、重量感应式台灯(放置物体在底座上时自动开灯,移开后关灯,实现无接触控制)。

🌟 传感器的介绍

称重传感器是将物体重量信号转换成可测量电信号的核心器件,也是 HX711 的前端信号来源,其设计和性能直接决定称重系统的精度。
1.主流类型与核心原理

  • 目前与 HX711 搭配最广的是电阻应变式称重传感器,原理可拆解为 3 步:
  • 传感器内部含 “应变片”(一种受力后电阻会变化的特殊材料),应变片粘贴在金属弹性体上。
  • 当物体压在传感器上时,弹性体发生微小形变,带动应变片同步形变,使其电阻值改变。
  • 应变片组成 “惠斯通电桥” 电路,电阻变化会转化为微弱的差分电压信号(通常仅几毫伏),该信号需经 HX711 放大、AD 转换后,才能被单片机读取。

2.关键技术参数

  • 量程:传感器能测量的最大重量,常见规格有 1kg、5kg、10kg、50kg 等,需根据实际称重需求选择。
  • 灵敏度:单位重量对应的输出电压,通常标注为 “mV/V”(如 2mV/V),表示给传感器加 1V 电源时,每承受 1kg 重量会输出 2mV 电压。
  • 精度:测量值与真实重量的偏差程度,民用场景(如电子秤)选 0.1% 精度即可,工业检测可能需 0.01% 高精度。

🎯 单片机连接硬件图

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

🌟 驱动思路

步骤 1:硬件初始化

  • 将 SCK 配置为输出引脚,DOUT 配置为输入引脚
  • SCK 引脚:推挽输出(GPIO_Mode_Out_PP),初始电平为低(HX711 规定:DOUT 为高时,SCK 必须为低)。
  • DOUT 引脚:浮空输入(GPIO_Mode_IN_FLOATING)或上拉输入(避免悬空干扰)。
  • 使能对应 GPIO 端口的时钟(通过 RCC 寄存器)。

步骤 2:传感器数据读取

  • HX711 的数据读取依赖严格的时序控制,核心流程:等待数据就绪→读取 24 位数据→发送通道 / 增益选择脉冲。
  • (1)等待数据就绪
    HX711 完成 AD 转换后,DOUT 会从高电平变为低电平(表示数据就绪)。需循环检测 DOUT 电平,直到变为低。
  • (2)读取 24 位数据(高位先出)
    通过 SCK 发送 24 个时钟脉冲,每发一个脉冲(高→低),从 DOUT 读取 1 位数据(24 位补码):
    第 1 个脉冲:读取最高位(bit23),第 24 个脉冲:读取最低位(bit0)。
    每次 SCK 从低→高时,HX711 准备好下一位数据;SCK 从高→低时,读取当前位。
  • (3)通道 / 增益选择(第 25-27 个脉冲)
    读取 24 位数据后,需额外发送 1-3 个 SCK 脉冲,选择下一次转换的通道和增益:
    25 个脉冲:通道 A,增益 128(最常用)。
    26 个脉冲:通道 B,增益 32。
    27 个脉冲:通道 A,增益 64。

步骤 3:数据处理与显示

  • HX711 输出的 24 位数据是补码形式,需转换为实际物理量(重量):
    补码转原码:24 位补码的最高位为符号位,若为 1(负数),需转换为正数(rawData ^= 0x800000)。
    滤波处理:称重数据易受噪声干扰,需通过中值滤波、滑动平均等算法平滑(如取 5 次数据的中值)。
    重量转换:通过校准系数将 AD 值转换为实际重量(单位:g),公式:重量 = (AD值 - 皮重AD值) × 校准系数。
    4.数据显示: 接提取出来的数据通过串口一打印以及OLED显示数据

🎯 单片机程序代码

main.c

#include "stm32f10x.h"  
#include "string.h"  
#include "stdio.h" 
#include "delay.h"   
#include "bsp_usart.h"
#include "oled.h"
#include "HX7111.h"int weight=0;
char OledBuff[52];
int main(void)
{NVIC_PriorityGroupConfig (NVIC_PriorityGroup_2);SysTick_Init(72);  //系统时钟初始化 usart1_init(115200);//串口1初始化printf("USART1 OK!\r\n");usart2_init(9600);//串口1初始化usart3_init(115200);//串口3初始化	OLED_Init();OLED_ShowString(36,0,"HX711");HX711_Init();OLED_ShowString(0,2,"去皮");HX711_CalibrateTare();delay_ms(100);OLED_ShowString(0,2,"去皮成功");delay_ms(100);OLED_ShowString(0,2,"        ");while(1){weight=HX711_GetWeight();sprintf(OledBuff,"重量:%d g    ",weight);OLED_ShowString(0,2,OledBuff);}
}

HX7111.c

#include "HX7111.h"
#include "delay.h"
#include "bsp_usart.h"// 静态变量 - 仅在本模块内有效,避免全局变量冲突
static uint32_t tareWeight = 0;              // 皮重值
static const uint32_t calibrationFactor = 25499;  // 校准系数
static uint32_t filterBuffer[MEDIAN_FILTER_LEN];  // 滤波缓冲区
static uint8_t filterIndex = 0;              // 滤波数据计数/*** @brief 配置HX711数据引脚为输出模式*/
static void HX711_SetDataOutput(void)
{GPIO_InitTypeDef GPIO_InitStructure;GPIO_InitStructure.GPIO_Pin = HX711_DATA_GPIO_PIN;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(HX711_DATA_GPIO_PORT, &GPIO_InitStructure);
}/*** @brief 配置HX711数据引脚为输入模式*/
static void HX711_SetDataInput(void)
{GPIO_InitTypeDef GPIO_InitStructure;GPIO_InitStructure.GPIO_Pin = HX711_DATA_GPIO_PIN;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;GPIO_Init(HX711_DATA_GPIO_PORT, &GPIO_InitStructure);
}/*** @brief HX711初始化函数*/
void HX711_Init(void)
{GPIO_InitTypeDef GPIO_InitStructure;// 使能GPIO时钟(仅需初始化一次)HX711_GPIO_APBxClkCmd(HX711_GPIO_CLK, ENABLE);// 配置SCK引脚为推挽输出GPIO_InitStructure.GPIO_Pin = HX711_SCK_GPIO_PIN;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(HX711_SCK_GPIO_PORT, &GPIO_InitStructure);// 初始化为输入模式HX711_SetDataInput();// 初始状态设置HX711_SCK_LOW;
}/*** @brief 读取HX711原始AD数据* @return 24位AD转换结果*/
uint32_t HX711_ReadRawData(void)
{uint8_t i;uint32_t rawData = 0;// 等待数据就绪HX711_SetDataOutput();HX711_DATA_HIGH;delay_us(HX711_DELAY_US);HX711_SCK_LOW;HX711_SetDataInput();// 等待DOUT变为低电平(数据就绪)while(HX711_DATA_READ);delay_us(HX711_DELAY_US);// 读取24位数据(高位先出)for(i = 0; i < 24; i++){HX711_SCK_HIGH;delay_us(HX711_DELAY_US);rawData <<= 1;                // 左移一位if(HX711_DATA_READ)           // 读取当前位rawData |= 0x01;HX711_SCK_LOW;delay_us(HX711_DELAY_US);}// 第25个时钟脉冲(选择通道A,增益128)HX711_SCK_HIGH;rawData ^= 0x800000;  // 转换为补码delay_us(HX711_DELAY_US);HX711_SCK_LOW;delay_us(HX711_DELAY_US);return rawData;
}/*** @brief 中值滤波处理* @param newData 新采集的数据* @return 滤波后的值(当缓冲区满时)*/
static uint32_t medianFilter(uint32_t newData)
{uint8_t i, j;uint32_t temp;// 存入新数据filterBuffer[filterIndex++] = newData;// 缓冲区未满时返回0if(filterIndex < MEDIAN_FILTER_LEN)return 0;// 缓冲区满,进行排序(插入排序)for(i = 0; i < MEDIAN_FILTER_LEN - 1; i++){for(j = i + 1; j < MEDIAN_FILTER_LEN; j++){if(filterBuffer[i] > filterBuffer[j]){temp = filterBuffer[i];filterBuffer[i] = filterBuffer[j];filterBuffer[j] = temp;}}}// 重置缓冲区索引filterIndex = 0;// 返回中值return filterBuffer[MEDIAN_POSITION];
}/*** @brief 校准皮重(获取空载重量)*/
void HX711_CalibrateTare(void)
{uint32_t rawData;uint32_t filteredData = 0;// 采集一组数据进行中值滤波filterIndex = 0;  // 重置滤波缓冲区while(filteredData == 0){rawData = HX711_ReadRawData();filteredData = medianFilter(rawData);}// 计算皮重(缩小100倍处理)tareWeight = (uint16_t)(filteredData * 0.01f);
}/*** @brief 获取当前重量(已扣除皮重)* @return 重量值(g)*/
uint32_t HX711_GetWeight(void)
{uint32_t rawData, processedData;uint32_t weight = 0;uint32_t filteredData = 0;// 读取原始数据并进行滤波while(filteredData == 0){rawData = HX711_ReadRawData();processedData = (uint16_t)(rawData * 0.01f);  // 数据预处理filteredData = medianFilter(processedData);}// 计算净重(扣除皮重)if(filteredData > tareWeight){// 应用校准系数转换为实际重量weight = (uint16_t)(((float)(filteredData - tareWeight) * calibrationFactor) * 0.00001f);}else{weight = 0;  // 小于皮重时视为0}// 打印重量信息(调试用)printf("重量: %d g\r\n", weight);delay_ms(500);return weight;
}

🎯 代码下载链接

https://download.csdn.net/download/qq_41954594/92130073

http://www.dtcms.com/a/492017.html

相关文章:

  • 迎访问备案网站管理系统成都房产网官网
  • 行业网站建设内容怎么做网站寄生虫
  • 我的世界做外国壁纸网站竞价培训班
  • 重庆网站推广大全wordpress 早起文章
  • 高压断路器故障诊断:基于注意力机制的少样本迁移学习(FSTL)方法详解
  • 湖南专业外贸建站公司手机版网站如何做
  • 建设网站有哪些公司wordpress的开发框架
  • Linux Shell 实验一:数据采集与脚本调试错误总结
  • RHCSA作业1
  • 邹城有做网站的吗网站建设坂田
  • 外贸自助建站上海市企业网站建设
  • python(入门)函数及lambda表达式
  • 衡水市网站建设seo推广软件下载
  • 提供邯郸移动网站建设高职专业建设管理网站
  • ros2常用命令
  • 网站建设维护要求济南做网站哪里好
  • 2个网站 同意内容 百度优化什么网站专门做二手物品
  • 【AI大模型学习路线】第三阶段之RAG与LangChain——第十九章(实战基于Advanced RAG的PDF问答)系统部署与测试?
  • 访答知识库#Pdf转word#人工智能#Al编辑器#访答RAG#企业知识库,个人知识库,本地知识库,访答编辑器,访答浏览器……
  • python可以做网站前端wordpress 实名
  • Flutter命名路由配置使用指南
  • Flutter+D3.js强强联合,打造高性能动态数据看板
  • Flutter布局 --- Container
  • 广州搬家公司外贸seo网站推广
  • 简单测试支持运行多种语言程序的工具run
  • 缓存策略:多级缓存设计,热点数据如何高效处理?
  • 兰州网站制作公司在哪里昌平网站制作
  • 中国银行门户网站旅行社网站建设方案论文
  • Java学习开发过程是一个解剖牛[特殊字符]的过程
  • 用deepseek做图表,分析相控阵天线的测试数据