打印
[STC单片机]

外部中断问题解决了,超声波数据如何捕捉到一个能稳定5秒左右的超声波稳定值

[复制链接]
1641|16
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
huzb11|  楼主 | 2016-7-18 14:54 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
下午外部中断的问题解决了,用PCA0做的。超声波身高体重秤,在最后联调中,发现超声波数据不稳定,有时头偏一下,没检测到数据。会导致有时语音播报在那儿发生异常,要么数据没有了,不播报了。要么9和0之间播报错了。坛友们有什么办法将采集到瞬间的超声波数据保持住5秒种左右。。能让语音能稳定播报超声波数据。。。只要能保持5秒钟左右就可以了。

相关帖子

沙发
ningling_21| | 2016-7-18 15:36 | 只看该作者
如果已经获取到准确的数据,可以暂停继续获取超声数据5秒,5S后再继续

使用特权

评论回复
板凳
huzb11|  楼主 | 2016-7-18 21:55 | 只看该作者
ningling_21 发表于 2016-7-18 15:36
如果已经获取到准确的数据,可以暂停继续获取超声数据5秒,5S后再继续

关键是程序如何检测到已经获取准确的数据?对于超声波数据,因为有时头低一点,或高一点,数据都不一样,我一般要么是求平均数,要么求最高值。一开始我是想用eerom,就是超声波函数获取的值直接存在eerom里面,然后按自己的需要设定时间读取,但觉得这种方法不太好,还有没有更好的方法,获取超声波稳定值。。。

使用特权

评论回复
地板
ccxlslr| | 2016-7-19 07:45 | 只看该作者
多看,多写。思维方式实在不敢恭维

使用特权

评论回复
5
supertankhzt| | 2016-7-19 19:58 | 只看该作者
定义一个数组,保存过去测量的值,比如一秒测量两次,则定义为a[10],每测量一次下标加1,到10回0,同时判断过去的十次中的最大值和最小值之差若小于“稳定”阈值,比如1CM,则认为稳定测量完成,然后这十个数已经相差不大,要取平均值还是别的算法随你便。

使用特权

评论回复
6
cuya| | 2016-7-20 10:38 | 只看该作者
huzb11 发表于 2016-7-18 21:55
关键是程序如何检测到已经获取准确的数据?对于超声波数据,因为有时头低一点,或高一点,数据都不一样, ...

实在不明白, 为何做不到稳定5秒, 难道 RAM 不够? 还要用 eeprom 保存临时数据?

使用特权

评论回复
7
huzb11|  楼主 | 2016-7-20 13:48 | 只看该作者
本帖最后由 huzb11 于 2016-7-20 13:51 编辑
supertankhzt 发表于 2016-7-19 19:58
定义一个数组,保存过去测量的值,比如一秒测量两次,则定义为a[10],每测量一次下标加1,到10回0,同时判 ...


现在,不要求取实时数据,人离开托盘时,超声数据要保持5S左右的稳定。。。我说的是这种意思。

使用特权

评论回复
8
huzb11|  楼主 | 2016-7-20 13:50 | 只看该作者
cuya 发表于 2016-7-20 10:38
实在不明白, 为何做不到稳定5秒, 难道 RAM 不够? 还要用 eeprom 保存临时数据?  ...

是人离开托盘时,超声数据仍要保持5秒左右的稳定,我说的是这个意思。不是实时采集的。

使用特权

评论回复
9
supertankhzt| | 2016-7-21 15:48 | 只看该作者
本帖最后由 supertankhzt 于 2016-7-21 15:59 编辑
huzb11 发表于 2016-7-20 13:50
是人离开托盘时,超声数据仍要保持5秒左右的稳定,我说的是这个意思。不是实时采集的。 ...

哪里需要动用EEPROM?你要存多少数据,RAM存不下了吗??!
先使用我之前的“稳定判定算法”,被认为稳定后,“显示程序”暂停刷新,等待五秒不就得了,多简单的事。
之所以要使用稳定判定算法,是为防止在不适当的时机(如人在动时),保持了不正确的数据并显示了五秒。
想要在适当的时机(如人站好不动时)保持并显示正确的数据,就必须连续采集一段时间内(不用5秒,一两秒够了)的数据保存好交给“稳定判定程序”去分析,认为稳定后再通知“显示程序”暂停刷新。

使用特权

评论回复
10
huzb11|  楼主 | 2016-7-21 23:08 | 只看该作者
supertankhzt 发表于 2016-7-21 15:48
哪里需要动用EEPROM?你要存多少数据,RAM存不下了吗??!
先使用我之前的“稳定判定算法”,被认为稳定 ...



#define n  10

u16 sum=0;
u16 dat;
u16 cnt;
u16 avr;
u16 a[10];
u16 max=0;  //初始Max变量为0;
u16 min=999;//初始化Min变量为999,实际上三位带小数的体重数最大值可显示为99.9KG

for(cnt=0;cnt<n;cnt++)
{
sum+=advalue(0); //此为10次AD求和

        if(max<a[cnt])
            max=a[cnt];
        if(min>a[cnt])
            min=a[cnt];
}
if(max-min<=1)  //小于
    {
    avr=sum/n;
    return avr;
     }
   else
    return  (sum-max-min)/8;


显示程序我是用595控制的段码与位码,另外加的延时函数,不是放在定时器里面的。

比如体重68.5KG:

tz_dat=tz_test();
Disp_tz(tz_dat);//此为显示程序,595控制的段码与位码,每一位中间加延时函数,开通位显示。

如何暂停刷新?

使用特权

评论回复
11
xxdcq| | 2016-7-22 09:43 | 只看该作者
huzb11 发表于 2016-7-21 23:08
#define n  10

u16 sum=0;

用卡尔曼滤波应该可以得到可信值,均值滤波不太好

使用特权

评论回复
12
supertankhzt| | 2016-7-22 10:16 | 只看该作者
本帖最后由 supertankhzt 于 2016-7-22 10:22 编辑
huzb11 发表于 2016-7-21 23:08
#define n  10

u16 sum=0;

方法有多种,要做得完美,细节方面比较多,我只说个大体:
//再一个定义标志变量
static bit sf=0;
//一个计时(计次)变量
static uchar tcount=0;
//一个上次的稳定值
static u16 lastavr=0;
/***********************
if(max-min<=1)  //小于
    {
    avr=sum/n;
    return avr;
     }
   else
    return  (sum-max-min)/8;
*******************************/
以上改为
if(max-min<=1) {
        if(sf) {                                                //十次采样时间内不更新新数据
                if(++tcount>10) {
                        tcount=0;                                //十次计时完成,清零标志
                        sf=0;
                }
        } else {                                               
                sf=1;
                lastavr=(sum-max-min)/8;        //保存好第一次的稳定值,并置位标志位防止重复保存。
        }
        return lastavr;
} else {
        return (sum-max-min)/8;
}



使用特权

评论回复
13
huzb11|  楼主 | 2016-7-22 14:38 | 只看该作者
supertankhzt 发表于 2016-7-22 10:16
方法有多种,要做得完美,细节方面比较多,我只说个大体:
//再一个定义标志变量
static bit sf=0;

亲,上面的代码能保持一个稳定的值,但始终是显示3.2是怎么回事?无论怎么改都是这个值。

使用特权

评论回复
14
huzb11|  楼主 | 2016-7-22 15:37 | 只看该作者
supertankhzt 发表于 2016-7-22 10:16
方法有多种,要做得完美,细节方面比较多,我只说个大体:
//再一个定义标志变量
static bit sf=0;

还有奇怪,亲上面的程序有时不能稳定,脚一拿开数字就消失了。怎么回事?

使用特权

评论回复
15
supertankhzt| | 2016-7-22 16:00 | 只看该作者
huzb11 发表于 2016-7-22 15:37
还有奇怪,亲上面的程序有时不能稳定,脚一拿开数字就消失了。怎么回事? ...

我说了只是给个大体程序思路,细节方面你得自己处理。
关键是理解我给出的思路,结合实际去运用。我没有你其它程序代码,只是随手一打,不要指望照抄能完美运行。

使用特权

评论回复
16
huzb11|  楼主 | 2016-7-22 16:28 | 只看该作者
supertankhzt 发表于 2016-7-22 16:00
我说了只是给个大体程序思路,细节方面你得自己处理。
关键是理解我给出的思路,结合实际去运用。我没有 ...

那是什么问题?为何不能稳定一下,就消失了数据。

使用特权

评论回复
17
huzb11|  楼主 | 2016-7-23 11:30 | 只看该作者
supertankhzt 发表于 2016-7-22 10:16
方法有多种,要做得完美,细节方面比较多,我只说个大体:
//再一个定义标志变量
static bit sf=0;


#define N2   10

u16 sg_test()
{
   u16 sg;
   u16 cnt2;
   u16 sum_sg;
   static bit sf=0;
   static u8 tcount=0;
   static u16 lastavr=0;
   //u16 new_sg;
   
        u16 a[12];
        u16 min=999;
        u16 max=0;
    sg=2000-sonic();                                       //身高数据                     
for(cnt2=0;cnt2<N2;cnt2++)                          
         {

        sum_sg+=sg;
         //delay(30);
         if(max<a[cnt2])
         max=a[cnt2];
         if(min>a[cnt2])
         min=a[cnt2];
         }  
          if(max-min<=1)
          {
        if(sf) {                                                //十次采样时间内不更新新数据
                if(++tcount>10)
                                {
                        tcount=0;                                //十次计时完成,清零标志
                        sf=0;
                }

                }
                else {                                                
                sf=1;
                lastavr=(sum_sg-max-min)/8;        //保存好第一次的稳定值,并置位标志位防止重复保存。
                 }
        return lastavr;
        }
        else
        {
        return (sum_sg-max-min)/8;
    }
}


使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

12

主题

55

帖子

1

粉丝