两个移相算法

网友投稿 737 2022-08-31

两个移相算法

两个移相算法

方法一: 积分移项 这个移项是不是90度, 不太好说. 得到的幅值会变大,需要缩小. 而且还有相位逐渐下移的趋势. 下移的原因未知.也未深入探索, 因计算量比较大, 也没采用顾抛弃掉.

private double[] 积分移相90度( List sindata){ double[] cosdata = new double[sindata.Count]; double s = 0; for (int i = 0; i < sindata.Count; i++) { var d = sindata[i]; s += sindata[i]; cosdata[i] =s; } return cosdata;}

方法二: 索引移相位 利用数字计算机的下标索引, 将数值提前或者移后1/4 第一步,先测量出,两个正弦波峰值之间数据的个数 N. 第二步,将下标索引 前移1/4 或者后移 3/4.

/* 检测波峰测量周期宽度 代码比较简单,速度也比较快, 如果是程序生成的波形, 比较容易测量两个波峰的数值. 如果是ADC转换测量得到的数据. 测量峰值比较麻烦. . . 经过测试,此测量峰值求脉宽算法只对完美的正弦波比较适用. 对于有点干扰杂波的不太适用, 会陷入局部最小宽度. 不建议使用, 使用过零点检测脉宽更合适.*/private void 检测波峰测量周期宽度(List sindata,out double width_count, out double avg_max_data){ //求索引的个数 double pre = double.MinValue; double max = double.MinValue; int maxIndex = 0; //int preIndex = 0; List 波峰Index = new List(); List maxs = new List(); //上升或下降次数 int upcount = 0; int downcount = 0; for (int i = 1; i < sindata.Count; i++) { if (sindata[i] > sindata[i-1] ) { upcount++; max = sindata[i]; maxIndex = i; //连续10个以上的,上升视为真正的上升 if (upcount > 10) { downcount = 0; } } //连续下降2次的视为真正的下降 else if ( sindata[i] < sindata[i - 1]) { downcount ++; //下降了10个数, 视为真正的下降,防止波形干扰. if (downcount == 10 ) { //说明开始走下降趋势,那么认为 max 中的值便是真的波峰值. 波峰Index.Add(maxIndex); maxs.Add(max); max = double.MinValue; maxIndex = 0; upcount = 0; if (波峰Index.Count >= 10) { break; } } } } var juli = new List(); for (int i = 1; i < 波峰Index.Count; i++) { juli.Add(波峰Index[i] - 波峰Index[i - 1]); } width_count = juli.Average(); avg_max_data = maxs.Average(); return;}

检测过零点测量周期宽度

/// 检测过零点测量周期宽度, 要求数据必须无直流分量.否则无效./// /// private double 检测过零点测量周期宽度(List sindata ){ //求索引的个数 List 过零点Index = new List(); //上升或下降次数 for (int i = 1; i < sindata.Count; i++) { if (sindata[i -1] <= 0 && sindata[i]>=0) { 过零点Index.Add(i); if (过零点Index.Count >= 10) { break; } } } var juli = new List(); for (int i = 1; i < 过零点Index.Count; i++) { juli.Add(过零点Index[i] - 过零点Index[i - 1]); } var width_count = juli.Average(); return width_count;}

索引实现移相的使用方法.

//去掉参考信号的直流部分//取前面10000个数据,求平均值,平均值约等于直流分量,//完美的去直流方案,建议通过在电路中串联一个合适的电容.起到隔直通交的作用.var sinAvg = Sin_data.Take(10000).Average();for (int i = 0; i < LN; i++){ Sin_data[i] = Sin_data[i] - sinAvg;}//2.移相90度//2.1 移项先计算两个波峰之间的数据的个数.//2.2 知道了每个波峰之间数据的个数, 再把索引提前1/4 就是移项90度. //var cos_data = 积分移相90度(Sin_data); double width_count = 检测过零点测量周期宽度(Sin_data); //360度往前移相位1/4是90度. 往后移3/4是270度也是90度,也是同一个相位. 为了程序更容易运行,减少一个判断. 无法取未来的数据, 可以改成取历史的数据 //所以从第270个相位的数据, 开始, 一般情况下. 数据很多的, 不在乎这点数据. var his270index = (int) width_count / 4 * 3; //var N90 = this.trackBar1.Value; for (int i = his270index; i < LN; i++) { //this.chartMathNet.Series[0].Points.AddXY(i, GD_data[i]); //this.chartMathNet.Series[1].Points.AddXY(i, A_data[i]); this.chartMathNet.Series[2].Points.AddXY(i, Sin_data[i]); //显示 this.chartMathNet.Series[0].Points.AddXY(i, Sin_data[i - his270index]); //移相90度后的数据显示 }

经过测试, 更改索引实现移项的算法还是比较快速和稳定的.建议使用过零检测算法.

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:Go的标准项目布局(go企业级开发)
下一篇:go语言打造个人博客系统(一)
相关文章

 发表评论

暂时没有评论,来抢沙发吧~