标题:
关于使用单片机+应变片制作电子秤的一个问题
[打印本页]
作者:
brokaya
时间:
2020-10-4 00:39
标题:
关于使用单片机+应变片制作电子秤的一个问题
各位大神好,我这里有一个使用四个应变片做全电桥来制作一个电子秤的课题,电桥的输入是5V的电源,输出接入一个24位的AD模块HX711,然后使用stc8a单片机来读取HX711的值,再通过读取到的值使用公式转化成实测物品的质量。单片机的程序流程是首先测试200个数据取平均值作为基准数据,然后每次取一个原始数据都进行一次窗口为100的滑动均值滤波,接下来使用滤波后的数值对基准数据做差得到的增量作为一个用来代入公式计算质量的待处理数据,而这一步的待处理数据和实际质量的关系式原计划是使用多次测值进行数据拟合的方式来得到,可目前遇到了一个问题是实测到的这个待处理数据的波动范围非常大,最大值和最小值有两三千甚至可能更多的差距,因此没有办法进行选合适的值进行拟合,所以想要问一问各位有没有做过这类的东西的有什么解决办法吗?
获取质量相关的单片机程序如下(weight.h文件中仅有函数声明和窗口长度的宏定义,没有其他内容):
#include <stc8.h>
#include "weight.h"
#include <intrins.h>
//与HX711通信的两个端口
sbit SCK=P1^6;
sbit DOUT=P1^7;
//这两个变量分别是基准数据和窗口滤波用的数组
unsigned long zero_point;
unsigned long xdata window[100]={0};
//软件延时函数,1us
void Delay1us(int n) //@24.000MHz
{
unsigned char i;
while(n--)
{
_nop_();
_nop_();
i = 3;
while (--i);
}
}
//读取HX711输出的数据
unsigned long Read711()
{
unsigned long dat=0;
char i;
DOUT=1;
SCK=0; Delay1us(1);
while(DOUT);
for(i=0;i<24;i++)
{
SCK=1;
Delay1us(1);
SCK=0;
dat|=DOUT;
dat<<=1;
Delay1us(1);
}
SCK=1; //这里多进行一次脉冲的目的是选择hx711的工作模式为128倍增益,通道一
Delay1us(1);
SCK=0;
return dat;
}
//读200次数取均值为零点,返回零点(基准数据)
unsigned long get_zpoint(void)
{
unsigned long sum=0;
unsigned long dat;
unsigned char i;
for(i=0;i<100;i++)
{
dat=Read711();
sum+=dat;
}
return (sum/200);
}
//零点初始化函数,用于获得基准数值
void zpoint_init()
{
zero_point=get_zpoint();
}
//滑动滤波函数
//参数:每次读取到的原始数据
//返回值:滤波后的数据
unsigned long sfilter(unsigned long basic_dat)
{
static unsigned char cnt=0;
unsigned long sum=0;
unsigned long res_dat;
char i;
window[cnt]=basic_dat;
for(i=0;i<WINDOW_LEN;i++) //WINDOW_LEN是窗口长度,当前值是100
{
sum+=window[i];
}
res_dat=sum/WINDOW_LEN;
cnt++;
if(cnt==WINDOW_LEN)
cnt=0;
return res_dat;
}
//获取增量函数
//说明:滤波后的数据与基准数据(零点)作差得到增量,随后通过增量计算待测物品的质量
//参数:待处理数据,基准数据
//返回值:增量
unsigned long get_increment(unsigned long pd,unsigned long zp)
{
unsigned long inc;
if(pd<zp) pd=zp; //当前数据小于基准数据时把增量置零,防止出现负数
inc=pd-zp;
return inc;
}
/*
这里应有一个换挡函数,用于选择分段拟合的比率(如果有这样的需求)
*/
//说明:获取质量
//参数:无
//返回值:当前物品质量
//ps:目前由于没有进行数据拟合因此仅返回滤波后的增量
unsigned long get_weight()
{
unsigned long zp;
unsigned long pd;
unsigned long zm;
/*
这里要声明比率
*/
pd=sfilter(Read711());
zp=zero_point;
zm=get_increment(pd,zp);
/*
这里要计算实际质量
*/
return zm;
}
复制代码
作者:
langshan
时间:
2021-1-26 22:13
真是懒得看这么多 你先用其他称重仪表或者示波器 看看你的信号线路有没有问题
HX711 上16位精度 很轻松的
作者:
f556
时间:
2021-1-26 22:38
HX711是24位SD型 AD,实际上能到15、16位,还算不错了。处理办法:丢掉几个低位,数值就很稳定。
如 :ADV=ADV>>6;
或者除1000000也行
我实际操作是移位丢的。
作者:
rundstedt
时间:
2021-1-26 23:08
如果是HX711的原始数据波动两三千那太正常了,你自己算々这点数字对于HX711的满量程来说是多么的渺小和微不足道?
欢迎光临 (http://www.51hei.com/bbs/)
Powered by Discuz! X3.1