HX711 的原理和数值换算(以Excel表格为工具)

简短不看版:

文件名:HX711计算.xlsx

下载链接:阿里云盘:https://www.alipan.com/s/A5UPp8Doi5z

输入步骤0中已知数据即可自动计算.

 

步骤 0 :获取已知数据

首先,需要得到几个已知条件:

1. 首先是HX711电路的两个电阻的阻值 R1, R2:目的是算出激励电压。

2. 然后是你手上拉力传感器的量程A(kg),拉力传感器的灵敏度(mV/V)

3. 其他HX711编程确定的参数(一般默认),如放大倍数为128倍,数值精度为24位。

下面以

  • HX711电路R1=15kΩ,R2=20kΩ; 
  • 500 kg量程,1.2mV/V的拉力传感器
  • 放大倍数:128倍,数值精度:24位

的已知条件进行如下计算:

 

步骤 1 :如何计算传感器激励电压

HX711 可以在产生 VAVDD 和 AGND 电压,即 711 模块上的 E+ 和 E- 电压。该电压通过 VAVDD=VBG(R1 +R2 )/R2 计算。VBG 为模块儿基准电压 1.25v,R1 = 15K ,R2 = 20K。 因此得出 VAVDD = 2.917V

(为了降低功耗,该电压只在采样时刻才有输出, 因此用万用表读取的值可能低于 4.3v ,因为万用表测量的是有效值。 )

 

步骤 2 :如何计算 AD 输出最大值

在 2.917 V 的供电电压下 500Kg 的传感器最大输出电压是 2.917v*1.2mv/V = 3.5 mV
经过 128 倍放大后,最大电压为 3.5 mV*128 = 448mV
经过 AD 转换后输出的24bit数字值最大为:(448mV/ 2.917V ) *(2^ 24)≈2576980

步骤 3 :程序中数据如何转换

程序中通过HX711_Buffer = HX711_Read(); 获取当前采样的 AD 值,最大 2576890,(注:257万,已知uint16_t 数值最大为65535, 因此不能用16位储存该数字)

存放在 uint32_t 型变量 HX711_Buffer 中,因 uint32_t 型变量计算速率和存放空间占用资源太多,固除以100 ,缩放为 uint16_t 型,便于后续计算。

Weight_Shiwu = HX711_Buffer/100;

Weight_Shiwu 最大为 25769 。

 

步骤 4 :如何将 AD 值反向转换为重力值。

假设重力为 x Kg ( x<500Kg ) , 测量出来的 AD 值为 y

对于满量程 500Kg,单片机得到最终的数字为25769,那么对于 x kg,其对应的数字就是 (x/500)*25769 = x * 51.54

所以 y = 51.54 x

因此得出 x = (y /51.54) Kg  = (y / 51.54)*1000 g

所以得出程序中计算公式

Weight_Shiwu = (unsigned int)((float)(Weight_Shiwu/51.54)*1000+0.05); //+0.05 是为了四舍五入百分位
特别注意:
因为不同的传感器斜率特性曲线不一样,因此,每一个传感器需要矫正这里的 51.54 这个除数。当发现测出来的重量偏大时,增加该数值。如果测试出来的重量偏小时,减小改数值。因传感器线性斜率不同而定。每个传感器都要校准。如果传感器测量值偏大,则需改大该数值,若传感器测量值偏小,则需改小该数值。

 

 

参考代码:以Arduino为例

/////以下为函数声明  
extern unsigned long HX711_Read(void);
extern long Get_Weight();
///变量定义
float Weight = 0;
int HX711_SCK =2;   ///     作为输出口
int HX711_DT= 3;    ///     作为输入口
long HX711_Buffer = 0;
long Weight_Maopi = 0, Weight_Shiwu = 0;
 #define GapValue 405       ///该值需校准 每个传感器都有所不同

void setup()
{  
 //初始化HX711的两个io口       
pinMode(HX711_SCK, OUTPUT);  ///SCK 为输出口 ---输出脉冲
pinMode(HX711_DT, INPUT); ///  DT为输入口  ---读取数据

 Serial.begin(9600);
 Serial.print("Welcome to use!\n");
 delay(3000);    ///延时3秒  
 //获取毛皮重量
 Weight_Maopi = HX711_Read(); 
}
 void loop()    ///  一直循环{}内容  ----- 同while(1){xxx}
{
 Weight = Get_Weight();  //计算放在传感器上的重物重量
 Serial.print(float(Weight/1000),3);  //串口显示重量,3意为保留三位小数
 Serial.print(" kg\n"); //显示单位
 Serial.print("\n");  //显示单位
 delay(2000);  //延时2s 两秒读取一次传感器所受压力
}
 //称重函数
long Get_Weight()
{
 HX711_Buffer = HX711_Read();    ///读取此时的传感器输出值
 Weight_Shiwu = HX711_Buffer;     ///将传感器的输出值储存
 Weight_Shiwu = Weight_Shiwu - Weight_Maopi; //获取实物的AD采样数值。
 Weight_Shiwu = (long)((float)Weight_Shiwu/GapValue);    //AD值转换为重量(g)
 return Weight_Shiwu; 
}
unsigned long HX711_Read(void) //选择芯片工作方式并进行数据读取
{
 unsigned long count;   ///储存输出值  
 unsigned char i;     
   ////high--高电平 1  low--低电平 0  
 digitalWrite(HX711_DT, HIGH);   ////  digitalWrite作用: DT=1;
 delayMicroseconds(1); ////延时 1微秒  
 digitalWrite(HX711_SCK, LOW);  ////  digitalWrite作用: SCK=0;
 delayMicroseconds(1);   ////延时 1微秒  
 count=0; 
  while(digitalRead(HX711_DT));    //当DT的值为1时,开始ad转换
  for(i=0;i<24;i++)   ///24个脉冲,对应读取24位数值
 { 
   digitalWrite(HX711_SCK, HIGH);  ////  digitalWrite作用: SCK=0;
                                /// 利用 SCK从0--1 ,发送一次脉冲,读取数值
  delayMicroseconds(1);  ////延时 1微秒  
  count=count<<1;    ///用于移位存储24位二进制数值
  digitalWrite(HX711_SCK, LOW);   //// digitalWrite作用: SCK=0;为下次脉冲做准备
 delayMicroseconds(1);
   if(digitalRead(HX711_DT))    ///若DT值为1,对应count输出值也为1
   count++; 
 } 
  digitalWrite(HX711_SCK, HIGH);    ///再来一次上升沿 选择工作方式  128增益
 count ^= 0x800000;   //按位异或  不同则为1   0^0=0; 1^0=1;
///对应二进制  1000 0000 0000 0000 0000 0000  作用为将最高位取反,其他位保留原值
 delayMicroseconds(1);
 digitalWrite(HX711_SCK, LOW);      /// SCK=0;     
 delayMicroseconds(1);  ////延时 1微秒  
 return(count);     ///返回传感器读取值
}

对于51、stm32等单片机的程序,只需做出简单修改就可。

如主要为 修改延时函数 ,端口高低电平。 stm32 加上端口初始化(可配置 推挽输出)

 

参考文章:

HX711AD +压力传感器(arduino) https://www.zhihu.com/tardis/bd/art/93838734?source_id=1001 

 

 

HX711 相关疑问

1. 该芯片集成了包括稳压电源、片内时钟振荡器等其它同类型芯片所需要的外围电路;

疑问:稳压电源、片内时钟振荡器的功能是什么?稳压电源的目的是什么,输出的电压是什么?

2. 通道A的可编程增益为128或64,对应的满额度差分输入信号幅值分别为±20mV或±40mV。通道B则为固定的32增益,用于系统参数检测。

疑问:幅值是最大的意思吗?最大20mV?假如超过了肿么办?

3. 芯片内提供的稳压电源可以直接向外部传感器和芯片内的A/D转换器提供电源,系统板上无需另外的模拟电源。

疑问:为什么要向外部提供电源呢?相应的引脚在哪里?

4. 简单的数字控制和串口通讯:所有控制由管脚输入,芯片内寄存器无需编程

疑问:串口通讯名字不适合吧,相应的引脚是否应该像I2C一样加上拉电阻呢?

5. 可选择10Hz 或80Hz 的输出数据速率

疑问:怎么选择,哪种速率好呢?是不是慢一点数据更精确一点?

6. 耗电量(含稳压电源电路):典型工作电流:<1.7mA, 断电电流:<1μA

疑问:断电电流?如何断电呢?

7. 典型应用图和管脚说明图

疑问:

a. VBG(参考电源输出)为什么要加电容到地?( VAVDD=VBG(R1 +R2 )/R2 )

b.  Vfb(稳压电路控制输入):为什么要进行分压呢?为什么要用稳压电路,其作用是什么?不用会怎么样?公式 ( VAVDD=VBG(R1 +R2 )/R2 ) 里面为什么是Vbg而不是Vfb。

c.  Vsup(稳压电路电源):与Vfb有啥区别?

d. Vavdd:(模拟电源):与Vsup有啥区别?能不能直接接电源呢?其应该是加在传感器上的电压,其数值是多少,怎么计算的?

e. BASE引脚接的三极管有什么作用?

f. 感觉好多引脚是浪费的,比如INPB,INNB; XI/XO基本不用,RATE也是经常默认接低电平。

而且其中稳压电源占了大部分

 

供电电源:数字电源(DVDD)应使用与MCU芯片相同的的数字供电电源。

疑问:假如电平不一样,该肿么办?比如MCU是5V,HX711是3.3V。

 

HX711芯片内的稳压电路可同时向A/D转换器和外部传感器提供模拟电源。

稳压电源的供电电压(VSUP)可与数字电源(DVDD)相同 (在典型应用图里就是 VSUP=DVDD)。

稳压电源的输出电压值(VAVDD)由外部分压电阻R1、R2 和芯片的输出参考电压VBG决定(图1),VAVDD=VBG(R1+R2)/R2。

VAVDD应该至少低于稳压电源的输入电压(VSUP)100mV。

疑问:稳压电源的输出电压值与输入电压值无关?

如果不使用芯片内的稳压电路,管脚VSUP和管脚AVDD应相连,并接到电压为2.6~5.5V的低噪声模拟电源。管脚VBG上不需要外接电容,管脚VFB应接地,管脚BASE 为无连接。

疑问:VSUP与AVDD直接相连?那应该省去了好多电子元件:不需要三极管(BASE无连接)、不需要分压电阻(VFB接地)、不需要加VBG电容。

 

 

 

如果PD_SCK从低电平变高电平并保持在高电平超过60μs,HX711 即进入断电状态(图三)

(当PD_SCK为低电平时,芯片处于正常工作状态。)

当PD_SCK 重新回到低电平时,芯片会自动复位后进入正常工作状态。芯片从复位或断电状态进入正常工作状态后,通道A和增益128会被自动选择作为第一次A/D转换的输入通道和增益。随后的输入通道和增益选择由PD_SCK的脉冲数决定,参见串口通讯一节。

 

当数据输出管脚DOUT为高电平时,表明A/D转换器还未准备好输出数据,此时串口时钟输入信号PD_SCK应为低电平。当DOUT从高电平变低电平后,PD_SCK应输入25至27个不等的时钟脉冲(图二)。其中第一个时钟脉冲的上升沿将读出输出24位数据的最高位(MSB),直至第24个时钟脉冲完成,24位输出数据从最高位至最低位逐位输出完成。第25至27个时钟脉冲用来选择下一次A/D转换的输入通道和增益

第25至27个时钟脉冲用来选择下一次A/D转换的输入通道和增益,参见表三。

posted @   FBshark  阅读(652)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具
历史上的今天:
2023-09-12 未解决:启动 unbuntu 卡在 initramfs
点击右上角即可分享
微信分享提示