微波EDA网,见证研发工程师的成长!
首页 > 研发问答 > 嵌入式设计讨论 > MCU和单片机设计讨论 > 电子秤的称值不稳定,该怎么修改程序好?

电子秤的称值不稳定,该怎么修改程序好?

时间:10-02 整理:3721RD 点击:
我用的芯片是STC89C52RC,A/D转换用的HX711,显示用的是12864,传感器用的是10KG的,问题:把100G砝码放在传感器上,数值一直跳,范围在98-104之间跳动,没有稳定下来,该怎么解决?
主程序如下
#include "main.h"
#include "LCD12864.h"
#include "HX711.h"
#include "keyboard.h"
unsigned long HX711_Buffer = 0;
unsigned int Weight_Maopi = 0,Weight_Shiwu = 0;
char Price_Count = 0;
uchar KEY_NUM = 0;
unsigned char Price_Buffer[6] = {0x00,0x00,0x00,0x00,0x00,0x00};
unsigned long Money = 0;
bit Flag_OK = 0;
volatile bit FlagTest = 0;                //定时测试标志,每0.5秒置位,测完清0

//定时器0初始化
void Timer0_Init()
{        EA=1;
        ET0 = 1;        //允许定时器0中断
        TMOD = 1;       //定时器工作方式选择
        TL0 = 0xb0;     
        TH0 = 0x3c;     //定时器赋予初值
        TR0 = 1;        //启动定时器
}
//定时器0中断
void Timer0_ISR (void) interrupt 1 using 0
{
uchar Counter;
        TL0 = 0xb0;
        TH0 = 0x3c;     //定时器赋予初值
        //每0.5秒钟刷新重量
    Counter ++;
    if (Counter >= 10)
    {
       FlagTest = 1;
           Counter = 0;
    }
}
void main()
{
        Timer0_Init();
   //初中始化完成,开断
        LCD12864_Reset();                                                                //初始化液晶
        LCD12864_HAIZI_SET();                                                        //设置为普通模式
        LCD12864_NoWaitIdle_COM_Write(0x80);                                                //指针设置
        LCD12864_write_word("※※※※※※※※");
        LCD12864_NoWaitIdle_COM_Write(0x90);                                                //指针设置
        LCD12864_write_word("※※欢迎使用※※");                       
        LCD12864_NoWaitIdle_COM_Write(0x88);                                                //指针设置
        LCD12864_write_word("※10公斤电子秤※");
        LCD12864_NoWaitIdle_COM_Write(0x98);                                                //指针设置
        LCD12864_write_word("※※※※※※※※");
        Get_Maopi();                                //称毛皮重量
                               
        Delay_ms(2000);                 //延时2s,等待传感器稳定
loop:
        Price_Count = 0;
        KEY_NUM = 0;
        Price_Buffer[0] = 0;
        Price_Buffer[1] = 0;
        Price_Buffer[2] = 0;
        Price_Buffer[3] = 0;
        Price_Buffer[4] = 0;
        Price_Buffer[5] = 0;
        Price_Buffer[6] = 0;
        Money = 0;
        Flag_OK = 0;
        Get_Maopi();                                //称毛皮重量
        LCD12864_NoWaitIdle_COM_Write(0x01);                        //清空
       
        while(1)
        {
                LCD12864_NoWaitIdle_COM_Write(0x80);                                                //指针设置
                LCD12864_write_word("★10公斤电子秤★");
                if( Flag_OK == 0)
                {
                        if (FlagTest==1)
                        {
                        Get_Weight();
                        FlagTest = 0;
                        }
                //        Get_Weight();                        //称重
       
                        //显示当前重量
                        LCD12864_NoWaitIdle_COM_Write(0x90);
                        LCD12864_write_word("重量:");
                        LCD12864_Data_Write(' ');
                        LCD12864_Data_Write(' ');
                        if( Weight_Shiwu/10000 != 0)
                        {
                                LCD12864_Data_Write(Weight_Shiwu/10000 + 0x30);
                        }
                        else
                        {
                                LCD12864_Data_Write(' ');       
                        }
                        LCD12864_Data_Write(Weight_Shiwu%10000/1000 + 0x30);
                        LCD12864_Data_Write('.');
                        LCD12864_Data_Write(Weight_Shiwu%1000/100 + 0x30);
                        LCD12864_Data_Write(Weight_Shiwu%100/10 + 0x30);
                        LCD12864_Data_Write(Weight_Shiwu%10 + 0x30);
                        LCD12864_write_word("Kg");
                }
                LCD12864_NoWaitIdle_COM_Write(0x88);
                LCD12864_write_word("单价:");
                LCD12864_Data_Write(' ');
               
                if( Price_Count == 0 )
                {
                        LCD12864_Data_Write('_');       
                }
                else
                {
                        LCD12864_Data_Write( Price_Buffer[0] + 0x30);
                }
                if( Price_Count == 1 )
                {
                        LCD12864_Data_Write('_');       
                }
                else
                {
                        LCD12864_Data_Write( Price_Buffer[1] + 0x30);
                }
               
                if( Price_Count == 2 )
                {
                        LCD12864_Data_Write('_');       
                }
                else
                {
                        LCD12864_Data_Write( Price_Buffer[2] + 0x30);
                }
                 
               
                if( Price_Count == 3 )
                {
                        LCD12864_Data_Write('_');       
                }
                else
                {
                        LCD12864_Data_Write( Price_Buffer[3] + 0x30);
                }
                LCD12864_Data_Write( '.' );
                if( Price_Count == 4 )
                {
                        LCD12864_Data_Write('_');       
                }
                else
                {
                        LCD12864_Data_Write( Price_Buffer[4] + 0x30);
                }
                if( Price_Count == 5 )
                {
                        LCD12864_Data_Write('_');       
                }
                else
                {
                        LCD12864_Data_Write( Price_Buffer[5] + 0x30);
                }

                LCD12864_write_word("元");
                LCD12864_NoWaitIdle_COM_Write(0x98);
                LCD12864_write_word("金额:");
                LCD12864_NoWaitIdle_COM_Write(0x9f);
                LCD12864_write_word("元");
                KEY_NUM = KEY_Scan();
                                                         
                if( KEY_NUM != 0x55)                        //当返回的不是初值时候,确认按键按下。
                {
                        if(KEY_NUM == 10)                        //数字A键,去皮功能
                        {
                                Get_Maopi();                        //去皮       
                        }
                        if(KEY_NUM == 15)                        //数字B键清除键,二次测量
                        {
                                goto loop;       
                        }
                        if(KEY_NUM == 12)                        //数字C输入单价错误时返回上一步
                        {
                                Price_Count--;
                                if( Price_Count < 0)
                                {
                                        Price_Count = 0;
                                }       
                        }
                        if(KEY_NUM == 13)                        //数字D键,计算总价
                        {
                                Money = Price_Buffer[0] * 100000 + Price_Buffer[1] * 10000 + Price_Buffer[2]*1000 + Price_Buffer[3]*100+Price_Buffer[4]*10+Price_Buffer[5];       
                                Money = Money * Weight_Shiwu / 1000;
                                LCD12864_NoWaitIdle_COM_Write(0x9b);
                                if( Money/1000000 > 0 )
                                {
                                        LCD12864_Data_Write(Money/1000000 + 0x30);
                                        LCD12864_Data_Write(Money%1000000/100000 + 0x30);
                                        LCD12864_Data_Write(Money%100000/10000 + 0x30);
                                        LCD12864_Data_Write(Money%10000/1000 + 0x30);
                                        LCD12864_Data_Write(Money%1000/100 + 0x30);
                                        LCD12864_Data_Write('.');
                                        LCD12864_Data_Write(Money%100/10 + 0x30);
                                        LCD12864_Data_Write(Money%10 + 0x30);
                                }
                                else
                                {
                                        if( Money/100000 > 0 )
                                        {
                                                LCD12864_Data_Write(' ');
                                                LCD12864_Data_Write(Money%1000000/100000 + 0x30);
                                                LCD12864_Data_Write(Money%100000/10000 + 0x30);
                                                LCD12864_Data_Write(Money%10000/1000 + 0x30);
                                                LCD12864_Data_Write(Money%1000/100 + 0x30);
                                                LCD12864_Data_Write('.');
                                                LCD12864_Data_Write(Money%100/10 + 0x30);
                                                LCD12864_Data_Write(Money%10 + 0x30);
                                        }
                                        else
                                        {
                                                if( Money/10000 > 0 )
                                                {
                                                        LCD12864_Data_Write(' ');
                                                        LCD12864_Data_Write(' ');
                                                        LCD12864_Data_Write(Money%100000/10000 + 0x30);
                                                        LCD12864_Data_Write(Money%10000/1000 + 0x30);
                                                        LCD12864_Data_Write(Money%1000/100 + 0x30);
                                                        LCD12864_Data_Write('.');
                                                        LCD12864_Data_Write(Money%100/10 + 0x30);
                                                        LCD12864_Data_Write(Money%10 + 0x30);
                                                }
                                                else
                                                {
                                                        if( Money/1000 > 0 )
                                                        {
                                                                LCD12864_Data_Write(' ');
                                                                LCD12864_Data_Write(' ');
                                                                LCD12864_Data_Write(' ');
                                                                LCD12864_Data_Write(Money%10000/1000 + 0x30);
                                                                LCD12864_Data_Write(Money%1000/100 + 0x30);
                                                                LCD12864_Data_Write('.');
                                                                LCD12864_Data_Write(Money%100/10 + 0x30);
                                                                LCD12864_Data_Write(Money%10 + 0x30);
                                                        }
                                                        else
                                                        {
                                                                LCD12864_Data_Write(' ');
                                                                LCD12864_Data_Write(' ');
                                                                LCD12864_Data_Write(' ');
                                                                LCD12864_Data_Write(' ');
                                                                LCD12864_Data_Write(Money%1000/100 + 0x30);
                                                                LCD12864_Data_Write('.');
                                                                LCD12864_Data_Write(Money%100/10 + 0x30);
                                                                LCD12864_Data_Write(Money%10 + 0x30);
                                                        }       
                                                }       
                                        }       
                                }
                               
                                Flag_OK = 1;                                       
                        }
                        if(KEY_NUM >= 0 && KEY_NUM <= 9)                                          //显示输入的价格值
                        {
                                if( Price_Count < 6 )
                                {
                                        Price_Buffer[Price_Count] = KEY_NUM;
               
                                        Price_Count++;
                                }
                        }         
                }          
        }
}
void Get_Weight()
{
    HX711_Buffer = HX711_Read();
    HX711_Buffer = HX711_Buffer/100;
    if(HX711_Buffer > Weight_Maopi)            
    {
        Weight_Shiwu = HX711_Buffer;
        Weight_Shiwu = Weight_Shiwu - Weight_Maopi;                //获取实物的AD采样数值。
        Weight_Shiwu = (unsigned int)((float)Weight_Shiwu/4.109+0.05);     //计算实物的实际重量
                                                                        //因为不同的传感器特性曲线不一样,因此,每一个传感器需要矫正这里的2.15这个除数。
                                                                        //当发现测试出来的重量偏大时,增加该数值。
                                                                        //如果测试出来的重量偏小时,减小改数值。
                                                                        //该数值一般在4.30附近调整之间。因传感器不同而定。
                                                                        //+0.05是为了四舍五入百分位
                if(  Weight_Shiwu > 10000 )
                {
                        Buzzer = 0;                                //打开警报
                        LED=!LED;
                        LCD12864_COM_Write(0x90);
                        LCD12864_write_word("※※※超重※※※");       
                }
                else
                {
                        if(Weight_Shiwu==0)
                        LED=1;
                        else if(Weight_Shiwu>0)
                        LED=0;
                        Buzzer = 1;                                //关闭警报
               
                }
        }
        else if(HX711_Buffer < Weight_Maopi - 30)
        {
                Buzzer = 0;                                //负重量报警
        }                                       
   // Weight_Shiwu=Weight_Shiwu/2;   

}
//****************************************************
//获取毛皮重量
//****************************************************
void Get_Maopi()
{
    uchar i = 0;
    uint Temp_Weight = 0;
    Weight_Maopi = 0;
    for( i = 0 ; i < 10 ; i++)
   {
        HX711_Buffer = HX711_Read();
        Temp_Weight = HX711_Buffer/100;
        if( Temp_Weight > Weight_Maopi)
        {
            Weight_Maopi = Temp_Weight;     
        }
    }        
}
//****************************************************
//MS延时函数(12M晶振下测试)
//****************************************************
void Delay_ms(uint n)
{
    unsigned int  i,j;
    for(i=0;i<n;i++)
        for(j=0;j<123;j++);
}

这就要用到各种算法啦~~~~

做个小的滤波,如何和上一次测量值相差2个,就不更新显示,

软件滤波,推荐参考一本书《匠人手记》里面有详细写各种滤波算法的实现,小编如果有兴趣可以去买一本或者找个PDF看看。

滤波 加算法

AD几位的?

可以参考网络上的一阶滤波方法,做个动态调整
void DynamicFilter(FILTER_PARAMETER_STRU *Par)
{
    float tmp=0.0;
    if(fabs((*Par).NewValue - (*Par).OldValue)>100.0)
                        {
                       (*Par).NewValue=(*Par).OldValue;
                        return;
                    }
               
    (*Par).Dir_Thre.bit0 = (*Par).Dir_Thre.bit1;
    (*Par).Dir_Thre.bit1 = 0;
    tmp = (*Par).NewValue - (*Par).OldValue;
    if(tmp >= 0)(*Par).Dir_Thre.bit1 = 1;
    if((*Par).Dir_Thre.bit0 == (*Par).Dir_Thre.bit1)    //μY????D??àí?
        {
                (*Par).Fliter_Counter += 1;
                if(fabs(tmp) >= FITLER_VALUE_THRESHOLD)(*Par).Fliter_Counter += 2;
                if((*Par).Fliter_Counter >= FILTER_COUNTER_MAX)
                        {
                            (*Par).FilterScale += FILTER_SCALE_STEP;
                            if((*Par).FilterScale >= FILTER_SCALE_MAX)   (*Par).FilterScale = FILTER_SCALE_MAX;
                        }
        }
   else
        {
                (*Par).Fliter_Counter = 0;
                     (*Par).FilterScale = 0.005;
        }
    (*Par).NewValue = ((*Par).OldValue)*(1.0-((*Par).FilterScale)) + ((*Par).FilterScale)*((*Par).NewValue);
    (*Par).OldValue = (*Par).NewValue;
}


Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top