一、传感器的数据处理算法

在传感器使用中,我们常常需要对传感器数据进行各种整理,让应用获得更好的效果,以下介绍几种常用的简单处理方法:

  • 加权平滑:平滑和均衡传感器数据,减小偶然数据突变的影响。
  • 抽取突变:去除静态和缓慢变化的数据背景,强调瞬间变化。
  • 简单移动平均线:保留数据流最近的K个数据,取平均值。

    下面,具体介绍一下这3种处理方法。

加权平滑

    使用算法如下:

    (新值) = (旧值)*(1 - a) + X * a其中a为设置的权值,X为最新数据,程序实现如下:

float ALPHA = 0.1f;
public void onSensorChanged(SensorEvent event){
x = event.values[0];
y = event.values[1];
z = event.values[2];
mLowPassX = lowPass(x,mLowPassX);
mLowPassY = lowPass(x,mLowPassY);
mLowPassZ = lowPass(x,mLowPassZ);
}
private float lowPass(float current,float last){
return last * (1.0f - ALPHA) + current * ALPHA;
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.

抽取突变

    此算法采用上面加权平滑的逆算法实现代码如下:

public void onSensorChanged(SensorEvent event){
final float ALPHA = 0.8;gravity[0] = ALPHA * gravity[0] + (1-ALPHA) * event.values[0];
gravity[1] = ALPHA * gravity[1] + (1-ALPHA) * event.values[1];
gravity[2] = ALPHA * gravity[2] + (1-ALPHA) * event.values[2];filteredValues[0] = event.values[0] - gravity[0];
filteredValues[1] = event.values[1] - gravity[1];
filteredValues[2] = event.values[2] - gravity[2];
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.

简单移动平均线

    这个算法,保留传感器数据流中最近的K个数据,返回它们的平均值。k表示平均“窗口”的大小,实现代码如下:

public class MovingAverage{
private float circularBuffer[]; //保存传感器最近的K个数据
private float avg; //返回到传感器平均值
private float sum; //数值中传感器数据的和
private float circularIndex; //传感器数据数组节点位置
private int count;public MovingAverage(int k){
circularBuffer = new float[k];
count= 0;
circularIndex = 0;
avg = 0;
sum = 0;
}
public float getValue(){
return arg;
}
public long getCount(){
return count;
}
private void primeBuffer(float val){
for(int i=0;i<circularbuffer.length;++i){
 circularBuffer[i] = val;
sum += val;
}
}
private int nextIndex(int curIndex){
if(curIndex + 1 >= circularBuffer.length){
return 0;
}
return curIndex + 1;
}
public void pushValue(float x){
if(0 == count++){
primeBuffer(x);
}
float lastValue = circularBuffer[circularIndex];
circularBuffer[circularIndex] = x; //更新窗口中传感器数据
sum -= lastValue; //更新窗口中传感器数据和
sum += x;
avg = sum / circularBuffer.length; //计算得传感器平均值
circularIndex = nextIndex(circularIndex);
}
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.
  • 33.
  • 34.
  • 35.
  • 36.
  • 37.
  • 38.
  • 39.
  • 40.
  • 41.
  • 42.
二、STM32的启动模式配置与应用

三种BOOT模式

    所谓启动,一般来说就是指我们下好程序后,重启芯片时,SYSCLK的第4个上升沿,BOOT引脚的值将被锁存。用户可以通过设置BOOT1和BOOT0引脚的状态,来选择在复位后的启动模式

嵌入式分享合集119_嵌入式硬件

  • Main Flash memory
    是STM32内置的Flash,一般我们使用JTAG或者SWD模式下载程序时,就是下载到这个里面,重启后也直接从这启动程序。
  • System memory
    从系统存储器启动,这种模式启动的程序功能是由厂家设置的。一般来说,这种启动方式用的比较少。系统存储器是芯片内部一块特定的区域,STM32在出厂时,由ST在这个区域内部预置了一段BootLoader, 也就是我们常说的ISP程序, 这是一块ROM,
    出厂后无法修改。一般来说,我们选用这种启动模式时,是为了从串口下载程序,因为在厂家提供的BootLoader中,提供了串口下载程序的固件,可以通过这个BootLoader将程序下载到系统的Flash中。但是这个下载方式需要以下步骤:
    Step1:将BOOT0设置为1,BOOT1设置为0,然后按下复位键,这样才能从系统存储器启动BootLoader
    Step2:最后在BootLoader的帮助下,通过串口下载程序到Flash中
    Step3:程序下载完成后,又有需要将BOOT0设置为GND,手动复位,这样,STM32才可以从Flash中启动可以看到, 利用串口下载程序还是比较的麻烦, 需要跳帽跳来跳去的,非常的不注重用户体验。
  • Embedded Memory
    内置SRAM,既然是SRAM,自然也就没有程序存储的能力了,这个模式一般用于程序调试。假如我只修改了代码中一个小小的地方,然后就需要重新擦除整个Flash,比较的费时,可以考虑从这个模式启动代码(也就是STM32的内存中),用于快速的程序调试,等程序调试完成后,在将程序下载到SRAM中。

开发BOOT模式选择

    通常使用程序代码存储在主闪存存储器,配置方式:

BOOT0=0,BOOT1=X
  • 1.

Flash锁死解决办法

    开发调试过程中,由于某种原因导致内部Flash锁死,无法连接SWD以及Jtag调试,无法读到设备,可以通过修改BOOT模式重新刷写代码。

    修改为BOOT0=1,BOOT1=0即可从系统存储器启动,ST出厂时自带Bootloader程序,SWD以及JTAG调试接口都是专用的。重新烧写程序后,可将BOOT模式重新更换到BOOT0=0,BOOT1=X即可正常使用。

三、两种USB接口电路图解析

1  USB接口电路的原理图中,R3是上拉电阻器,它可使USB口的D+端上拉到DS2490S的VB端,表示USB主机系统是高速设备,同时这个上拉电阻器告诉主机有USB设备插入。该上拉电阻器的设置对适配器的影响很大,它的负载值和1-Wire网络的总长决定1-Wire总线电压上升到5 V的速度。经过实验测试选择R3的阻值为27 Ω±lO%。R1、R2为USB数据线保护电阻器。L、L2具有禁止高频干扰并且减弱EMI辐射的功能。LF33CV为3.3 V电压稳压器,与周围元件C1、C2组成强上拉部分,给EEPROM或温度传感器等器件提供额外的电源。

嵌入式分享合集119_数据_02

2  采用PDIUSBD12芯片,这是一种价格便宜、功能完善的并行接口芯片,它支持多路复用、非多路复用和 DMA并行传输。PDIUSBD12接口芯片遵从协议USB1.1,适合于不同用途的传输类型。PDIUSBD12需要外接微控制器(MCU)来进行协议处理和数据交换,它对MCU没有特殊要求,而且接口方便灵活,因此设计师可以选用自己熟悉的MCU对芯片进行控制,也可利用Philips公司的固件 (firmware)结构来缩短开发时间、降低风险、减小投资。

嵌入式分享合集119_数据_03

PDIUSBD12除了具有USB设备的一般特性外,还具有如下特点:

    (1)是一种高性能的USB接口芯片,其内部集成有 SIE(Serial Interface Engine)、320字节的FIFO、收发器和电压调节器。

    (2)适用于大部分设备类规范。可与任何外部微控制器/微处理器实现高速并行接口,其速度可高达2Mbit/s。

    (3)可进行完全独立的DMA操作。

    (4)主端点配置有双缓冲,因而可提高数据的吞吐量、减小数据传输时间,轻松实现数据的实时传输。

    (5)当采用同步传输方式时,数据的传输速度为1Mbit/s;而采用批量传输方式的速度为1Mbyte/s。在使用上述方式进行数据传输时,可方便地使用多种中断方式。

    (6)带有可编程的时钟输出,与USB总线的连接可通过软件来控制(Soft Connect TM)。

    (7)有两种工作电压可供选择:分别为3.3±0.3V和3.6~5.5V。

    (8)输出和数据传输状态可通过USB连接指示灯来监控。

四、三种LED驱动电源电路

1 开关恒流源

    采用变压器将高压变为低压,并进行整流滤波,以便输出稳定的低压直流电。开关恒流源又分隔离式电源和非隔离式电源,隔离是指输出高低电压隔离,安全性非常高,所以对外壳绝缘性要求不高。非隔离安全性稍差,但成本也相对低,传统节能灯就是采用非隔离电源,采用绝缘塑料外壳防护。RGB电源的安全性相对较高(一般是输出低压),性能稳定,缺点是电路复杂、价格较高。开关电源技术成熟,性能稳定,是目前LED照明的主流电源。

嵌入式分享合集119_数据_04

上图,开关恒流隔离式日光灯管电源。

嵌入式分享合集119_嵌入式硬件_05

上图,开关恒流隔离电源原理图。 

嵌入式分享合集119_数据_06

上图,开关恒流源电源。 

嵌入式分享合集119_ci_07

上图,开关恒流非隔离电源原理图。

2 线性IC电源

    采用一个IC或多个IC来分配电压,电子元器件种类少,功率因数、电源效率非常高,不需要电解电容,寿命长,成本低。缺点是输出高压非隔离,有频闪,要求外壳做好防触电隔离保护。市面上宣称无(去)电解电容,超长寿命的,均是采用线性IC电源。RGB电源IC驱电源具有高可靠性,高效率低成本优势,是未来理想的LED驱动电源。

嵌入式分享合集119_数据_08

上图,线性IC电源。 

嵌入式分享合集119_嵌入式硬件_09

 上图,线性IC电源原理图。

3 阻容降压电源

    采用一个电容通过其充放电来提供驱动电流,电路简单,成本低,但性能差,稳定性差,在电网电压波动时及容易烧坏LED,同时输出高压非隔离,要求绝缘防护外壳。功率因数低,寿命短,一般只适于经济型小功率产品(5W以内)。RGB电源功率高的产品,输出电流大,电容不能提供大电流,否则容易烧坏,另外国家对高功率灯具的功率因数有要求,即7W以上的功率因数要求大于0.7,但是阻容降压电源远远达不到(一般在0.2-0.3之间),所以高功率产品不宜采用阻容降压电源。市场上,要求不高的低端型的产品,几乎全部是采用阻容降压电源,另外,一些高功率的便宜的低端产品,也是采用阻容降压电源。

嵌入式分享合集119_ci_10

上图,阻容降压电源。 

嵌入式分享合集119_数据_11

上图,阻容降压电源原理图。

三种电源成本性能比较

    以3W小球泡和16W日光灯管为例,各种电源成本比较:

    可见,不同类别的电源,其成本差异是非常大的,其中过认证的开关隔离源最贵,阻容降压电源最便宜。

    各类电源性能比较:

    在中高端市场,开关恒流非隔离电源仍是市场的主流电源,厂家一般会在结构设计上进行防高压隔离。而在低端市场,大部份厂家是采用阻容降压电源,也有部分厂家采用线性IC电源,这要求厂家有一定的设计能力。

    采用不同的电源,产品的性能及价格是不一样的,我们应该根据不同的市场选用不同的产品。