OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 4309|回复: 24

关于C语言求平均数的问题,求C语言高手指点

[复制链接]

13

主题

41

帖子

0

精华

初级会员

Rank: 2

积分
74
金钱
74
注册时间
2016-8-15
在线时间
52 小时
发表于 2018-4-1 18:42:21 | 显示全部楼层 |阅读模式
10金钱
因为ADC采样的数据是有抖动的,我用求平均数来滤波以得到一个稳定的值,将ADC读到的值的放在数组中,然后对数组求平均值。


常规的求平均数的方法是 (a+b+c)/3,比如采集到的数是4,5,6,那么均值就是(4+5+6)/3=5,


现在问题来了,因为传感器的原因,假如真实值是0,那么采样到的值就有可能在0左右波动, 有可能是1,2,也有可能是补码0xff,0xfe,

那么这时求得的平均数就有可能是 (1+0xfe+2)=85,得出的结果就有问题了。

虽然这问题比较简单,不过想了好久也没想到一个高效方法,不知道有没有C语言高手能提供一下思路。

正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

13

主题

41

帖子

0

精华

初级会员

Rank: 2

积分
74
金钱
74
注册时间
2016-8-15
在线时间
52 小时
 楼主| 发表于 2018-4-1 18:45:34 | 显示全部楼层
其实是一个角度传感器,如果是用12位的ADC来读取,在0°的时候值就可能是1,2,3,也有可能是0xfff,0xffe
回复

使用道具 举报

70

主题

6761

帖子

0

精华

论坛大神

Rank: 7Rank: 7Rank: 7

积分
13118
金钱
13118
注册时间
2012-11-26
在线时间
3813 小时
发表于 2018-4-1 18:46:58 | 显示全部楼层
既然你知道有正负,还当ff fe处理?
回复

使用道具 举报

13

主题

41

帖子

0

精华

初级会员

Rank: 2

积分
74
金钱
74
注册时间
2016-8-15
在线时间
52 小时
 楼主| 发表于 2018-4-1 19:23:56 | 显示全部楼层
jermy_z 发表于 2018-4-1 18:46
既然你知道有正负,还当ff fe处理?

采集到的值是无符号的,我想过转换成有符号的整型,但是在正负交界的地方依旧存在这个问题,比如传感器180°的时候,-127和127的均值就是0了
回复

使用道具 举报

70

主题

6761

帖子

0

精华

论坛大神

Rank: 7Rank: 7Rank: 7

积分
13118
金钱
13118
注册时间
2012-11-26
在线时间
3813 小时
发表于 2018-4-1 19:37:25 | 显示全部楼层
carvenl 发表于 2018-4-1 19:23
采集到的值是无符号的,我想过转换成有符号的整型,但是在正负交界的地方依旧存在这个问题,比如传感器18 ...

不知道你的什么传感器,如果结果有正负,传出的却只有正,那你的传感器及测量方法比较扯淡
学无止境
回复

使用道具 举报

33

主题

984

帖子

1

精华

论坛元老

Rank: 8Rank: 8

积分
8024
金钱
8024
注册时间
2014-8-13
在线时间
1595 小时
发表于 2018-4-1 20:09:14 | 显示全部楼层
我就问你一个问题:你如何定义一个8位的负数?
回复

使用道具 举报

4

主题

211

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
2600
金钱
2600
注册时间
2016-7-6
在线时间
546 小时
发表于 2018-4-1 20:55:46 | 显示全部楼层
先判断数的±嘛,如果数大于等于0x80,则判断为负数,然后进行处理,这样应该能解决你的问题 吧
把复杂的事,做简单!
回复

使用道具 举报

24

主题

695

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1666
金钱
1666
注册时间
2016-4-29
在线时间
266 小时
发表于 2018-4-1 23:16:16 | 显示全部楼层
本帖最后由 d1z1y2 于 2018-4-1 23:19 编辑

ADC 的值为0时对应电压为0V,4095时是3.3V(假设参考电压是3.3V),那楼主的意思是说传感器输出的电压一会儿0V,一会儿3.3V?


楼主,ADC的值表示的是其Pin脚上的电压值的数字量,电压值……
回复

使用道具 举报

13

主题

41

帖子

0

精华

初级会员

Rank: 2

积分
74
金钱
74
注册时间
2016-8-15
在线时间
52 小时
 楼主| 发表于 2018-4-2 00:22:13 | 显示全部楼层
d1z1y2 发表于 2018-4-1 23:16
ADC 的值为0时对应电压为0V,4095时是3.3V(假设参考电压是3.3V),那楼主的意思是说传感器输出的电压一会儿0 ...

是这样的,就像角度,359°和1°,按照常规求平均数的话,结果就是(359+1)/2=180°了
回复

使用道具 举报

13

主题

41

帖子

0

精华

初级会员

Rank: 2

积分
74
金钱
74
注册时间
2016-8-15
在线时间
52 小时
 楼主| 发表于 2018-4-2 00:23:47 | 显示全部楼层
mack13013 发表于 2018-4-1 20:09
我就问你一个问题:你如何定义一个8位的负数?

是无符号的整型,可以用强制转换(int)的方法转成带符号的整型
回复

使用道具 举报

13

主题

41

帖子

0

精华

初级会员

Rank: 2

积分
74
金钱
74
注册时间
2016-8-15
在线时间
52 小时
 楼主| 发表于 2018-4-2 00:25:15 | 显示全部楼层
jermy_z 发表于 2018-4-1 19:37
不知道你的什么传感器,如果结果有正负,传出的却只有正,那你的传感器及测量方法比较扯淡

就是角度的传感器,采样的时候是无符号整型,比如359°和1°,按照常规求平均数的话,结果就是(359+1)/2=180°了
回复

使用道具 举报

33

主题

984

帖子

1

精华

论坛元老

Rank: 8Rank: 8

积分
8024
金钱
8024
注册时间
2014-8-13
在线时间
1595 小时
发表于 2018-4-2 00:37:19 | 显示全部楼层
carvenl 发表于 2018-4-2 00:25
就是角度的传感器,采样的时候是无符号整型,比如359°和1°,按照常规求平均数的话,结果就是(359+1)/2= ...

我说一个最笨的办法:制作一个表,每个角度对应一个无符号数,或者每一个无符号数对应一个角度(float),
求平均值之前,先把采集的无符号数转换成角度(float),然后对角度求平均。

实际上我用过模拟的角度仪,采集区间对应±46度(超过此区间,角度仪线性不好),输出模拟量,使用12位AD采集,采集结果是无符号的0-4096,对应-46~46度。不管是直接对无符号求均值,还是对转换了的角度求均值,都是没问题的。
回复

使用道具 举报

15

主题

184

帖子

0

精华

高级会员

Rank: 4

积分
647
金钱
647
注册时间
2014-4-29
在线时间
299 小时
发表于 2018-4-2 09:52:39 | 显示全部楼层
你们是自己做的传感器还是外边买的?
正常的模拟接口的角度传感器,正转和反转的输出电压绝对不一样,线性的纯模拟电路,当输入量只是微小变动时,输出电压是没办法跳变的。模拟电路只会饱和,不会溢出归零。所以挺好奇这个传感器从哪来的。

你要是量程用满360°,还不如换成绝对编码器,数字接口的。既然你之前用了12位ADC,看起来精度需求也不是很大,也选12位的编码器就够,不是很贵。担心有0点溢出的问题可以选多圈编码器,截取中间的360°使用。
回复

使用道具 举报

13

主题

41

帖子

0

精华

初级会员

Rank: 2

积分
74
金钱
74
注册时间
2016-8-15
在线时间
52 小时
 楼主| 发表于 2018-4-2 17:46:40 | 显示全部楼层
xianshasaman 发表于 2018-4-2 09:52
你们是自己做的传感器还是外边买的?
正常的模拟接口的角度传感器,正转和反转的输出电压绝对不一样,线性 ...

现在就是用的绝对值编码器,0~360°模拟输出,我是用adc来采集的,问题就是在0°左右求平均值,得出的结果是180°左右的
回复

使用道具 举报

31

主题

265

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
413
金钱
413
注册时间
2018-1-9
在线时间
65 小时
发表于 2018-4-2 18:06:19 | 显示全部楼层
这个问题的本质是,角度是一个圆形每圈都会复位的变量,而ADC的值是一个线性增长的变量。你可以把多圈信息也记录一下,这样就是359,360,361,平均的结果,再除以360取余数就可以了。等过了0度比如超过了60度,就可以把多圈信息清零,重新记录,以免多圈信息溢出。
回复

使用道具 举报

31

主题

265

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
413
金钱
413
注册时间
2018-1-9
在线时间
65 小时
发表于 2018-4-2 18:09:41 | 显示全部楼层
jinfeihan57 发表于 2018-4-2 18:06
这个问题的本质是,角度是一个圆形每圈都会复位的变量,而ADC的值是一个线性增长的变量。你可以把多圈信息 ...

采样得数据做一个微分,就是后一个减前一个绝对值,如果大于你的最大采样时间乘以角速度的值的1.5倍,就做过零点的判断。
回复

使用道具 举报

33

主题

215

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
2035
金钱
2035
注册时间
2017-12-11
在线时间
454 小时
发表于 2018-4-2 21:00:55 | 显示全部楼层
本帖最后由 bootblack 于 2018-4-3 09:10 编辑

参数解决办法如下:
x = (int)(((a+b+c)%256) - 256)

<1> == 0  正好 <2> == -x 左偏
<3> == +x  右偏



回复

使用道具 举报

15

主题

184

帖子

0

精华

高级会员

Rank: 4

积分
647
金钱
647
注册时间
2014-4-29
在线时间
299 小时
发表于 2018-4-3 09:07:43 | 显示全部楼层
carvenl 发表于 2018-4-2 17:46
现在就是用的绝对值编码器,0~360°模拟输出,我是用adc来采集的,问题就是在0°左右求平均值,得出的结 ...

这个编码器是你自己选的吗?不太理解为什么要用模拟接口的。码盘采集来的信号已经是数字信号了,何必还要加个DA转换成模拟信号输出呢?数字接口传过来就能直接读数据,比ADC快,抗干扰性还好,有的编码器还自带奇偶校验。

非要用模拟接口的,可以 选个多圈的,比如2圈(-360~+360),把其中-180~+180作为有效量程,能避开溢出归零的问题。

如果你不是用满整个360°,而是只使用一部分,比如0~180°,可以把角度从0~360映射到-90~270(就是说假如a>=270,a=a-360),也可以避开溢出归零。

如果你要用满360°,不换器件肯定不行。
回复

使用道具 举报

37

主题

596

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1574
金钱
1574
注册时间
2017-7-17
在线时间
308 小时
发表于 2018-4-3 09:25:13 | 显示全部楼层
你是说如果采集到0xfe,那就有可能变得很大吗?你没有理解数据类型的意义呀。你的1+0xfe,如果这个采集变量是定义成有符号数,那结果也是负的呀(-1),而不是无符号的255,如果1+0xfe+2,那就等于1了。
回复

使用道具 举报

37

主题

596

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1574
金钱
1574
注册时间
2017-7-17
在线时间
308 小时
发表于 2018-4-3 09:26:38 | 显示全部楼层
所以,关键的地方就是,如果你确定采集到的AD值会出现负的,那就吧变量定义成有符号的,这样不管加减乘除,算出来也是有符号的。
回复

使用道具 举报

13

主题

41

帖子

0

精华

初级会员

Rank: 2

积分
74
金钱
74
注册时间
2016-8-15
在线时间
52 小时
 楼主| 发表于 2018-4-3 12:28:07 | 显示全部楼层
可能我的问题表达不是很清楚,我科学上网在google终于找到了一篇专利文档,可以很好的说明了这个问题。不过是国内的专利,不知为啥国内搜不到,出口转内销了

CN103873015B.pdf

475.72 KB, 下载次数: 44

回复

使用道具 举报

13

主题

41

帖子

0

精华

初级会员

Rank: 2

积分
74
金钱
74
注册时间
2016-8-15
在线时间
52 小时
 楼主| 发表于 2018-4-3 13:10:01 | 显示全部楼层
还有两篇日文的日志,也对这一问题提出了方法。
一种是通过三角函数转变成空间矢量
https://qiita.com/koyo-miyamura/items/37d555ae150047ebefde

一种是对数据进行处理后计算平均值
http://d.hatena.ne.jp/ootanAW/20111030/1319981509
回复

使用道具 举报

7

主题

199

帖子

0

精华

高级会员

Rank: 4

积分
711
金钱
711
注册时间
2017-5-20
在线时间
96 小时
发表于 2018-4-3 15:59:08 | 显示全部楼层
楼主的问题跟角度平均值不是同样的问题。
关于温度补码,要先求出实际温度,在做四则运算求平均值。
但是角度问题,是有预置条件的。比如说,0和180度的平均值,是多少?90还是270?必须要定好这些模糊不清的边界。
回复

使用道具 举报

20

主题

79

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
456
金钱
456
注册时间
2012-3-19
在线时间
102 小时
发表于 2018-4-3 16:01:17 | 显示全部楼层
多采样几个,排序回把最大、最小的去掉,再平均
回复

使用道具 举报

7

主题

162

帖子

0

精华

高级会员

Rank: 4

积分
541
金钱
541
注册时间
2017-4-6
在线时间
67 小时
发表于 2018-4-3 17:55:04 | 显示全部楼层
是一直采样还是偶尔采一次样?
是前者的话可以判断方向,然后再预测下下次的数据大小,在进行滤波时做一个动态的处理就可以。
如果是偶尔采样,那采用算法的意义就不大了,到了0度附近你就无法判断究竟是355度还是1度了,因为没有方向,无法判断。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-6-9 00:16

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表