HX711压力传感器学习一(STM32)

news2024/11/17 23:39:46

目录

原理图:​

引脚介绍:

HX711介绍工作原理:

程序讲解:

整套工程:

发送的代码工程,与博客的不一致,如果编译有报错请按照报错和博客进行修改

原理图:

 引脚介绍:

VCC和GND引脚分别为HX711芯片的电源输入端口。

VCC引脚是连接到5V或3.3V的正电源,GND引脚是连接到地的负电源。

DOUT是HX711芯片的数据输出端口,它输出经过A/D转换处理后的24位数据。

SCK是HX711芯片的时钟输入端口,用于控制A/D转换的时钟。

后两个用于接单片机的GPIO口

HX711介绍工作原理:

HX711传感器由一个二进制模数转换器(ADC)和一个放大器组成。ADC可以将模拟信号转换为数字信号,而放大器可以扩大信号的幅度,以便更精确地测量。在称重应用中,HX711传感器可以通过应变量来测量物体的质量。

应变量是由当物体受到压力时会发生应变的特殊材料制成的。将应变量粘贴到测量物体的表面,当物体受到压力并伸展时,应变量也会发生变化。压力越大,应变量的变化也越大。

HX711压力传感器的工作原理基于万用表电桥原理,利用压力传感器的阻值变化来实现重量的测量。

具体的工作流程如下

  1. 通过引脚A+和A-接入压力传感器。在未加载的情况下,两个引脚之间的电阻为R1。

  2. 在HX711芯片中,使用一个基准电压(通常为VCC/2)来作为压力传感器电桥电路的中心点。

  3. 当压力传感器开始承受载荷时,电桥电路会产生一个微小的电压差。

  4. 这个电压差通过A+和A-引脚输入到HX711芯片中,并经过内置的差分放大器放大。

  5. 放大之后的信号被送到24位的A/D转换器中进行数字化处理,并通过DOUT引脚输出。

  6. PD_SCK引脚则是用于通过时钟信号来同步转换器的输出数据。

  7. 最终,通过对输入信号的放大和数字化处理,HX711芯片可以输出重量数据。

程序讲解:

1.HX711初始化

void Init_HX711pin(void)//初始化
{
	GPIO_InitTypeDef GPIO_InitStructure;
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);	 //使能PF端口时钟

	//HX711_SCK
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;				 // 端口配置
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; 		 //推挽输出
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;		 //IO口速度为50MHz
	GPIO_Init(GPIOB, &GPIO_InitStructure);					 //根据设定参数初始化GPIOB
	
	//HX711_DOUT
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;//输入上拉
    GPIO_Init(GPIOB, &GPIO_InitStructure);  
	
	GPIO_SetBits(GPIOB,GPIO_Pin_0);					//初始化设置为0
}

2.读取HX711

u32 HX711_Read(void)	//增益128
{
	unsigned long count; 
	unsigned char i; 
  	HX711_DOUT=1; 
	delay_us(1);
  	HX711_SCK=0; 
  	count=0; 
  	while(HX711_DOUT); 
  	for(i=0;i<24;i++)
	{ 
	  	HX711_SCK=1; 
	  	count=count<<1; 
		delay_us(1);
		HX711_SCK=0; 
	  	if(HX711_DOUT)
			count++; 
		delay_us(1);
	} 
 	HX711_SCK=1; 
    count=count^0x800000;//第25个脉冲下降沿来时,转换数据
	delay_us(1);
	HX711_SCK=0;  
	return(count);
}

解释讲解:

函数中定义了三个变量:count、i和一个延时值。其中,count是一个无符号长整型变量,用于存储从HX711获取的数据。i是一个无符号字符型变量,用于循环计数。delay_us(1)表示延时1微秒,用于确保时序的准确性。

然后,函数通过设置HX711_DOUT和HX711_SCK的电平,使HX711传感器进入读取状态。

接下来,函数使用while语句来等待DOUT的第一个脉冲到来。当DOUT为高电平时,表示HX711传感器还没有准备好,此时需要等待。当DOUT为低电平时,表示HX711传感器已经准备好,可以开始读取数据了。

然后,函数使用一个for循环来读取HX711传感器的24个数据位。在每个时钟周期中,函数将SCK设为高电平,然后将count左移一位。如果此时DOUT为高电平,则表示在该时钟周期内,HX711传感器向count的当前位中写入了1,此时需要将count的最低位设为1。如果此时DOUT为低电平,则表示在该时钟周期内,HX711传感器向count的当前位中写入了0,此时可以不用进行操作。最后,函数将SCK设为低电平,并延时一个周期。

读取完24个数据位后,此时count变量中存储着24位的数据。此时需要将count的最高位设为1,以便扩展到32位。这可以通过将count异或0x800000来实现。

最后,函数将SCK设为高电平,并延时一个周期,然后将SCK设为低电平。该函数返回count变量作为结果,即为从HX711传感器读取到的数据。

增益数值不同意味着循环的次数不同【增益128-循环24次;增益32-循环25次;增益64循环26次】

 3.称重

void Get_Weight(void)
{
	HX711_Buffer = HX711_Read();
	if(HX711_Buffer > Weight_Maopi)			
	{
		Weight_Shiwu = HX711_Buffer;
		Weight_Shiwu = Weight_Shiwu - Weight_Maopi;				//获取实物的AD采样数值。
	
		Weight_Shiwu = (s32)((float)Weight_Shiwu/GapValue)-478; 	//计算实物的实际重量
																		//因为不同的传感器特性曲线不一样,因此,每一个传感器需要矫正这里的GapValue这个除数。
																		//当发现测试出来的重量偏大时,增加该数值。
																		//如果测试出来的重量偏小时,减小改数值。
	}
}

至于为什么要在最后的减去478,因为我在测试的时候发现原始数据是478,要去皮就是减478

温馨提示:压力传感器上面不能有东西,否则初始状态以有东西为0的初始态。举个例子:水瓶放到传感器上,启动单片机,这样传感器以有水瓶的状态为初始状态,若我把水拿开,则显示是负数

整套工程:

HX711.C

/************************************************************************************
						
*************************************************************************************/
#include "HX711.h"
#include "delay.h"

u32 HX711_Buffer;
u32 Weight_Maopi;
s32 Weight_Shiwu;
u8 Flag_Error = 0;

float P=1;
float P_;  //对应公式中的p'
float X=0;
float X_;  //X'
float K=0;
float Q=0.01;//噪声
//float R=0.2;  //R如果很大,更相信预测值,那么传感器反应就会迟钝,反之相反
float R=0.5;
float distance=0;
float distance1=0;
float KLM(float Z)
{
  X_=X+0;
  P_=P+Q;
  K=P_/(P_+R);
  X=X_+K*(Z-X_);
  P=P_-K*P_;
  return X;
}


//校准参数
//因为不同的传感器特性曲线不是很一致,因此,每一个传感器需要矫正这里这个参数才能使测量值很准确。
//当发现测试出来的重量偏大时,增加该数值。
//如果测试出来的重量偏小时,减小改数值。
//该值可以为小数
#define GapValue 106.5


void Init_HX711pin(void)//初始化
{
	GPIO_InitTypeDef GPIO_InitStructure;
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);	 //使能PF端口时钟

	//HX711_SCK
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;				 // 端口配置
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; 		 //推挽输出
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;		 //IO口速度为50MHz
	GPIO_Init(GPIOB, &GPIO_InitStructure);					 //根据设定参数初始化GPIOB
	
	//HX711_DOUT
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;//输入上拉
    GPIO_Init(GPIOB, &GPIO_InitStructure);  
	
	GPIO_SetBits(GPIOB,GPIO_Pin_0);					//初始化设置为0
}



//****************************************************
//读取HX711
//****************************************************
u32 HX711_Read(void)	//增益128
{
	unsigned long count; 
	unsigned char i; 
  	HX711_DOUT=1; 
	delay_us(1);
  	HX711_SCK=0; 
  	count=0; 
  	while(HX711_DOUT); 
  	for(i=0;i<24;i++)
	{ 
	  	HX711_SCK=1; 
	  	count=count<<1; 
		delay_us(1);
		HX711_SCK=0; 
	  	if(HX711_DOUT)
			count++; 
		delay_us(1);
	} 
 	HX711_SCK=1; 
    count=count^0x800000;//第25个脉冲下降沿来时,转换数据
	delay_us(1);
	HX711_SCK=0;  
	return(count);
}

//****************************************************
//获取毛皮重量
//****************************************************
void Get_Maopi(void)
{
	Weight_Maopi = HX711_Read();	
} 

//****************************************************
//称重
//****************************************************
void Get_Weight(void)
{
	HX711_Buffer = HX711_Read();
	if(HX711_Buffer > Weight_Maopi)			
	{
		Weight_Shiwu = HX711_Buffer;
		Weight_Shiwu = Weight_Shiwu - Weight_Maopi;				//获取实物的AD采样数值。
	
		Weight_Shiwu = (s32)((float)Weight_Shiwu/GapValue)-478; 	//计算实物的实际重量
																		//因为不同的传感器特性曲线不一样,因此,每一个传感器需要矫正这里的GapValue这个除数。
																		//当发现测试出来的重量偏大时,增加该数值。
																		//如果测试出来的重量偏小时,减小改数值。
		Weight_Shiwu=KLM(Weight_Shiwu);
	}
}

文中用到了卡尔曼滤波减少了数值的波动

HX711.H

#ifndef __HX711_H
#define __HX711_H

#include "sys.h"

#define HX711_SCK PBout(0)// PB0
#define HX711_DOUT PBin(1)// PB1


extern void Init_HX711pin(void);
extern u32 HX711_Read(void);
extern void Get_Maopi(void);
extern void Get_Weight(void);

extern u32 HX711_Buffer;
extern u32 Weight_Maopi;
extern s32 Weight_Shiwu;
extern u8 Flag_Error;

#endif

main

/************************************************************************************
						
*************************************************************************************/
#include "stm32f10x.h"
#include "delay.h"
#include "HX711.h"
#include "usart.h"
#include "OLED.H"


int main(void)
{		
	Init_HX711pin();
	delay_init();
	
	NVIC_Configuration(); 	 //设置NVIC中断分组2:2位抢占优先级,2位响应优先级
	uart_init(9600);	 //串口初始化为9600
	
	Get_Maopi();				//称毛皮重量
	delay_ms(1000);
	delay_ms(1000);
	Get_Maopi();				//重新获取毛皮重量
	
	while(1)
	{
		Get_Weight();
		printf("净重量 = %d g\r\n",Weight_Shiwu); //打印 
		delay_ms(100);


	}
}

展示

需要工程文件的,麻烦您点赞、收藏、关注,留下邮箱即可

MSP432P401R版本:HX711压力传感器学习二(MSP432P401R版)_三马分享家的博客-CSDN博客

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1417920.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Leetcode刷题笔记题解(C++):1117. H2O 生成(多线程)

思路&#xff1a; 解法二&#xff1a;生产者-消费者解法 1.把 hydrogen 线程看作生产者&#xff0c;oxygen 线程看作消费者&#xff0c;缓冲队列大小为2。 2.hydrogen 把生成的氢放入队列&#xff1b;oxygen 线程每次从队列里消费两个氢元素。 3.生产者生产两个氢元素后会因为…

openGauss学习笔记-209 openGauss 数据库运维-常见故障定位案例-共享内存泄露问题

文章目录 openGauss学习笔记-209 openGauss 数据库运维-常见故障定位案例-共享内存泄露问题209.1 共享内存泄露问题209.1.1 问题现象209.1.2 原因分析209.1.3 处理方法 openGauss学习笔记-209 openGauss 数据库运维-常见故障定位案例-共享内存泄露问题 209.1 共享内存泄露问题…

精通Python第20篇—数据之美:用Pyecharts打造引人入胜的多维度仪表盘与图表联动

引言 在数据可视化领域&#xff0c;仪表盘图是一种直观而强大的工具&#xff0c;用于展示关键指标的实时状态。Pyecharts是一个基于Echarts的Python图表库&#xff0c;提供了丰富的图表类型&#xff0c;其中包括了仪表盘图。本文将介绍如何使用Pyecharts绘制多种炫酷的仪表盘图…

05.领域驱动设计:认识领域事件,解耦微服务的关键

目录 1、概述 2、领域事件 2.1 如何识别领域事件 1.微服务内的领域事件 2.微服务之间的领域事件 3、领域事件总体架构 3.1 事件构建和发布 3.2 事件数据持久化 3.3 事件总线 (EventBus) 3.4 消息中间件 3.5 事件接收和处理 4、案例 5、总结 1、概述 在事件风暴&a…

SpringBoot内置工具类

Collections java.util包下的Collections类&#xff0c;该类主要用于操作集合或者返回集合 一、排序 List<Integer> list new ArrayList<>();list.add(2);list.add(1);list.add(3);Collections.sort(list);//升序System.out.println(list);Collections.reverse(…

vue实践:构建高效的电子签名功能

前言 在现代数字化时代&#xff0c;电子签名成为了一种方便、高效且安全的签署文件的方式。本文将介绍电子签名的原理和实现方法&#xff0c;帮助你快速掌握这一重要的工具。 电子签名是什么&#xff1f; 电子签名是一种数字化的签名方式&#xff0c;用于验证和确认电子文档、…

GitLab16.8配置webhooks、Jenkins2.4配置GitLab插件实现持续集成、配置宝塔面板实现持续部署(其三)

看本篇文章的前提是已经部署完GItlab和Jenkins服务器&#xff0c;已经可以手动构建成功&#xff0c;并且经过了很多次实践&#xff0c;对这两款软件基本熟悉。 建议大家按以下顺序看 前端自动化&#xff08;其一&#xff09;部署gitlab 前端自动化&#xff08;其二&#xff0…

第五篇:express路由路径方式(字符串,字符串模式,和正则)

&#x1f3ac; 江城开朗的豌豆&#xff1a;个人主页 &#x1f525; 个人专栏 :《 VUE 》 《 javaScript 》 &#x1f4dd; 个人网站 :《 江城开朗的豌豆&#x1fadb; 》 ⛺️ 生活的理想&#xff0c;就是为了理想的生活 ! 目录 &#x1f4d8; 引言&#xff1a; &#x1f4…

MYSQL基本查询(CURD:创建、读取、更新、删除)

文章目录 前言一、Create1.全列插入2.指定列插入3.插入否则更新4.替换 二、Retrieve1.SELECT列2.WHERE条件3.结果排序4.筛选分页结果 三、Update四、Delete1.删除数据2.截断表 五、插入查询结果六、聚合函数 前言 操作关系型数据库的编程语言&#xff0c;定义了一套操作关系型…

用友U9 PatchFile.asmx 任意文件上传漏洞

免责声明&#xff1a;文章来源互联网收集整理&#xff0c;请勿利用文章内的相关技术从事非法测试&#xff0c;由于传播、利用此文所提供的信息或者工具而造成的任何直接或者间接的后果及损失&#xff0c;均由使用者本人负责&#xff0c;所产生的一切不良后果与文章作者无关。该…

CC攻击类型有几种?有什么有用的防御方法?

CC攻击&#xff08;Challenge Collapsar Attack&#xff09;是一种复杂的网络攻击&#xff0c;它利用了一种分布式拒绝服务攻击工具来发动攻击。这种攻击方式通常由黑客组织或恶意竞争者发起&#xff0c;旨在破坏目标网络或系统的正常运行。 CC攻击的核心在于使用大量的虚假请…

如何选择便捷安全的黄金交易平台?

黄金交易平台的介绍 黄金交易平台是一个提供方便、安全的方式进行黄金交易的网上平台。 投资者可以通过这些平台进行黄金的买卖&#xff0c;参与黄金市场的投资活动。 这些平台提供了一个简单易用的界面&#xff0c;让投资者可以方便地进行交易操作。 选择合适的黄金交易平台…

Kafka-服务端-GroupMetadataManager

GroupMetadataManager是GroupCoordinator中负责管理Consumer Group元数据以及其对应offset信息的组件。 GroupMetadataManager底层使用Offsets Topic,以消息的形式存储Consumer Group的GroupMetadata信息以及其消费的每个分区的offset,如图所示。 consumer_offsets的某Partiti…

LLM之Agent(九)| 通过API集成赋能Autogen Multi-Agent系统

随着大型语言模型的快速发展&#xff0c;构建基于LLM驱动的自治代理&#xff08;autonomous agents&#xff09;已经成为一个备受关注的话题。仅在过去一年中&#xff0c;就出现了许多基于这一理念的新技术和框架。 ​ 本文将探索微软开源的Agent框架&#xff1a;Autogen…

259:vue+openlayers: 显示海量多边形数据,10ms加载完成

第259个 点击查看专栏目录 本示例的目的是介绍演示如何在vue+openlayers项目中通过WebGLVectorLayerRenderer方式加载海量多边形数据。这里相当于将海量的数据放在同一个层的source中,然后通过webglTile的方式渲染出这一层。 本示例数据为5000个多边形,加载速度超级快。 直接…

D35XB80-ASEMI整流桥D35XB80参数、封装、尺寸

编辑&#xff1a;ll D35XB80-ASEMI整流桥D35XB80参数、封装、尺寸 型号&#xff1a;D35XB80 品牌&#xff1a;ASEMI 封装&#xff1a;GBJ-5 最大重复峰值反向电压&#xff1a;800V 最大正向平均整流电流(Vdss)&#xff1a;35A 功率(Pd)&#xff1a; 芯片个数&#xff1…

Web 开发 6:Redis 缓存(Flask项目使用Redis并同时部署到Docker详细流程 附项目源码)

大家好&#xff01;欢迎来到第六篇 Web 开发教程&#xff0c;今天我们将探讨一个非常重要的话题&#xff1a;Redis 缓存。作为一个互联网开发者&#xff0c;你一定知道在处理大量请求时&#xff0c;性能优化是至关重要的。而 Redis 缓存正是帮助我们提升系统性能的利器。Redis …

tcpdump 抓包无法落盘

文章目录 问题背景解决办法 问题背景 在嵌入式设备中(Linux系统)&#xff0c;为了分析两个网络节点的通讯问题&#xff0c;往往需要用到tcpdump&#xff0c;抓一个.pcap的包在PC端进行分析。博主在实际操作中发现&#xff0c;抓包无法实时落盘。 解决办法 # 下面的命令是写在…

MATLAB环境下一种贝叶斯稀疏盲反卷积算法

稀疏盲反卷积贝叶斯估计方法通常使用伯努利-高斯分布(BG)先验的稀疏序列建模&#xff0c;并利用马尔可夫链蒙特卡罗(MCMC)方法进行未知估计。然而&#xff0c;BG模型的离散性会有计算瓶颈。为了解决这个问题&#xff0c;提出一个替代方案&#xff0c;采用MCMC方法对稀疏序列进行…

Mac下查看、配置和使用环境变量

Mac下查看、配置和使用环境变量 一&#xff1a;Mac怎么查看环境变量命令 printenv一&#xff1a;这个命令会一次性列出所有环境变量的键值对&#xff0c;输出格式为&#xff1a; VAR1value1 VAR2value2 ...二&#xff1a; 也可以通过给这个命令加上环境变量名参数&#xff0…