鳕鱼天空

This is Mr Wang's Tech Blog.

Arduino学习索引贴

DS3231的简易时钟,1602液晶显示、串口修改时间 极客工坊

I2C器件之PCF8574TS调试记录(i2c to io8) csdn 琉球主

休眠相关:

Arduino UNO 睡眠模式以及关键代码

更新外置气象应用_让arduino用2颗5号电池运行1年以上 

Arduino pro mini 休眠与看门狗唤醒

rduino的详细介绍(基于Mega2560)(分文)——外部中断attachInterrupt()

關於中断(Interrupt)的一些五四三... 中斷 . .

Arduino - 看门狗定时器(WDT:Watch Dog Timer)

arduino pro mini 烧录 :rts -> dtr,烧录时不需要重启 

参考1:说说流控制(RTS/CTS/DTR/DSR 你都明白了吗?)【转】

参考2:UART的RTS,CTS,DTR,DSR这类不常用的特殊信号

OLED中文取模:PCtoLCD

 

Arduino公开课

第15课 端口内部的上拉功能

arduino可用的标准c++库

常用数字滤波算法

常用数字滤波算法

第1种方法:限幅滤波法(又称程序判断滤波法)

  A方法: 根据经验判断,确定两次采样允许的最大偏差值(设为A),每次检测到新值时判断: 如果本次值与上次值之差<=A,则本次值有效,如果本次值与上次值之差>A,则本次值无效,放弃本次值,用上次值代替本次值。

  B优点: 能有效克服因偶然因素引起的脉冲干扰。

  C缺点: 无法抑制那种周期性的干扰,平滑度差。

第2种方法:中位值滤波法

  A方法: 连续采样N次(N取奇数),把N次采样值按大小排列,取中间值为本次有效值。

  B优点: 能有效克服因偶然因素引起的波动干扰,对温度、液位的变化缓慢的被测参数有良好的滤波效果。

  C缺点: 对流量、速度等快速变化的参数不宜。

第3种方法:算术平均滤波法

  A方法: 连续取N个采样值进行算术平均运算,N值较大时:信号平滑度较高,但灵敏度较低;N值较小时:信号平滑度较低,但灵敏度较高。N值的选取:一般流量,N=12;压力:N=4。

  B优点: 适用于对一般具有随机干扰的信号进行滤波,这样信号的特点是有一个平均值,信号在某一数值范围附近上下波动。

  C缺点: 对于测量速度较慢或要求数据计算速度较快的实时控制不适用,比较浪费RAM 。

第4种方法:递推平均滤波法(又称滑动平均滤波法)

  A方法: 把连续取N个采样值看成一个队列,队列的长度固定为N,每次采样到一个新数据放入队尾,并扔掉原来队首的一次数据(先进先出原则) 。把队列中的N个数据进行算术平均运算,就可获得新的滤波结果。N值的选取:流量,N=12;压力:N=4;液面,N=4~12;温度,N=1~4。

  B优点: 对周期性干扰有良好的抑制作用,平滑度高,适用于高频振荡的系统。

  C缺点: 灵敏度低,对偶然出现的脉冲性干扰的抑制作用较差,不易消除由于脉冲干扰所引起的采样值偏差,不适用于脉冲干扰比较严重的场合,比较浪费RAM。

第5种方法:中位值平均滤波法(又称防脉冲干扰平均滤波法)

  A方法: 相当于“中位值滤波法”+“算术平均滤波法”,连续采样N个数据,去掉一个最大值和一个最小值,然后计算N-2个数据的算术平均值。N值的选取:3~14。

  B优点: 融合了两种滤波法的优点,对于偶然出现的脉冲性干扰,可消除由于脉冲干扰所引起的采样值偏差。

  C缺点: 测量速度较慢,和算术平均滤波法一样,比较浪费RAM。

第6种方法:限幅平均滤波法

  A方法: 相当于“限幅滤波法”+“递推平均滤波法”,每次采样到的新数据先进行限幅处理,再送入队列进行递推平均滤波处理。

  B优点: 融合了两种滤波法的优点,对于偶然出现的脉冲性干扰,可消除由于脉冲干扰所引起的采样值偏差。

  C缺点: 比较浪费RAM 。

第7种方法:一阶滞后滤波法

  A方法: 取a=0~1,本次滤波结果=(1-a)*本次采样值+a*上次滤波结果。

  B优点: 对周期性干扰具有良好的抑制作用,适用于波动频率较高的场合。

  C缺点:相位滞后,灵敏度低,滞后程度取决于a值大小,不能消除滤波频率高于采样频率的1/2的干扰信号。

第8种方法:加权递推平均滤波法

  A方法: 是对递推平均滤波法的改进,即不同时刻的数据加以不同的权,通常是,越接近现时刻的资料,权取得越大,给予新采样值的权系数越大,则灵敏度越高,但信号平滑度越低。

  B优点: 适用于有较大纯滞后时间常数的对象和采样周期较短的系统。

  C缺点: 对于纯滞后时间常数较小,采样周期较长,变化缓慢的信号,不能迅速反应系统当前所受干扰的严重程度,滤波效果差。

第9种方法:消抖滤波法

  A方法: 设置一个滤波计数器,将每次采样值与当前有效值比较: 如果采样值=当前有效值,则计数器清零。如果采样值<>当前有效值,则计数器+1,并判断计数器是否>=上限N(溢出),如果计数器溢出,则将本次值替换当前有效值,并清计数器。

  B优点: 对于变化缓慢的被测参数有较好的滤波效果,可避免在临界值附近控制器的反复开/关跳动或显示器上数值抖动。

  C缺点: 对于快速变化的参数不宜,如果在计数器溢出的那一次采样到的值恰好是干扰值,则会将干扰值当作有效值导入系统。

第10种方法:限幅消抖滤波法

  A方法: 相当于“限幅滤波法”+“消抖滤波法”,先限幅后消抖。

  B优点: 继承了“限幅”和“消抖”的优点,改进了“消抖滤波法”中的某些缺陷,避免将干扰值导入系统。

  C缺点: 对于快速变化的参数不宜。

第11种方法:IIR 数字滤波器

  A方法: 确定信号带宽, 滤之。 Y(n) = a1*Y(n-1) + a2*Y(n-2) + ... + ak*Y(n-k) + b0*X(n) + b1*X(n-1) + b2*X(n-2) + ... + bk*X(n-k)。

  B优点: 高通,低通,带通,带阻任意。设计简单(用matlab)。

  C缺点: 运算量大。

 

部分程序:

1、限副滤波
/* A值可根据实际情况调整
value为有效值,new_value为当前采样值 
滤波程序返回有效的实际值 */

#define A 10
char value;
char filter()
{
char new_value;
new_value = get_ad();
if ( ( new_value - value > A ) || ( value - new_value > A )
return value;
return new_value;

}

2、中位值滤波法
/* N值可根据实际情况调整
排序采用冒泡法*/

#define N 11
char filter()
{
char value_buf[N];
char count,i,j,temp;
for ( count=0;count<N;count++)
{
   value_buf[count] = get_ad();
   delay();
}
for (j=0;j<N-1;j++)
{
   for (i=0;i<N-j;i++)
   {
    if ( value_buf>value_buf[i+1] )
    {
     temp = value_buf;
     value_buf = value_buf[i+1]; 
     value_buf[i+1] = temp;
    }
   }
}
return value_buf[(N-1)/2];
}

3、算术平均滤波法
/*
*/

#define N 12
char filter()
{
int sum = 0;
for ( count=0;count<N;count++)
{
   sum + = get_ad();
   delay();
}
return (char)(sum/N);
}

4、递推平均滤波法(又称滑动平均滤波法)
/*
*/

#define N 12 
char value_buf[N];
char i=0;
char filter()
{
char count;
int sum=0;
value_buf[i++] = get_ad();
if ( i == N ) i = 0;
for ( count=0;count<N,count++)
sum = value_buf[count];
return (char)(sum/N);
}

5、中位值平均滤波法(又称防脉冲干扰平均滤波法)
/*
*/

#define N 12
char filter()
{
char count,i,j;
char value_buf[N];
int sum=0;
for (count=0;count<N;count++)
{
   value_buf[count] = get_ad();
   delay();
}
for (j=0;j<N-1;j++)
{
   for (i=0;i<N-j;i++)
   {
    if ( value_buf>value_buf[i+1] )
    {
     temp = value_buf;
     value_buf = value_buf[i+1]; 
     value_buf[i+1] = temp;
    }
   }
}
for(count=1;count<N-1;count++)
sum += value[count];
return (char)(sum/(N-2));
}

6、限幅平均滤波法
/*
*/ 
略 参考子程序1、3


7、一阶滞后滤波法
/* 为加快程序处理速度假定基数为100,a=0~100 */

#define a 50
char value;
char filter()
{
char new_value;
new_value = get_ad();
return (100-a)*value + a*new_value; 
}


8、加权递推平均滤波法
/* coe数组为加权系数表,存在程序存储区。*/

#define N 12
char code coe[N] = {1,2,3,4,5,6,7,8,9,10,11,12};
char code sum_coe = 1+2+3+4+5+6+7+8+9+10+11+12;
char filter()
{
char count;
char value_buf[N];
int sum=0;
for (count=0,count<N;count++)
{
   value_buf[count] = get_ad();
   delay();
}
for (count=0,count<N;count++)
sum += value_buf[count]*coe[count];
return (char)(sum/sum_coe);
}


9、消抖滤波法

#define N 12
char filter()
{
char count=0;
char new_value;
new_value = get_ad();
while (value !=new_value);
{
   count++;
   if (count>=N) return new_value;
   delay();
   new_value = get_ad();
}
return value; 
}

10、限幅消抖滤波法
/*
*/

Ardino节电模式、自动休眠、按钮打开和关闭

#include <avr/sleep.h>
#include <avr/power.h>
//#include <avr/wdt.h>

#include <MsTimer2.h>

int pin = 13;

volatile int f_sleepButton = 0;
volatile int f_sleepTimer = 0;

void setup() {
  //Serial.begin(9600);
  //Serial.print("Welcome to use!\n");
  pinMode(pin, OUTPUT);
  pinMode(2, INPUT);

  MsTimer2::set(2000, sleepTimer);        // 中断设置函数,每 2000ms 进入一次中断
  MsTimer2::start();

  sleepNow();
}

void loop() {
  if (digitalRead(2)) {
    //sleepNow();
    f_sleepButton++;
    clearsleepTimer();
    delay(50);
  }
  if (f_sleepButton == 24) {  // 长按1.2秒关机
    sleepNow();
  }
  if (f_sleepTimer == 10) { // 延时没有操作关机
    sleepNow();
  }
}

void sleepTimer() {
  f_sleepTimer++;
}

void sleepNow()         // here we put the arduino to sleep
{
  //detachInterrupt(0);
  digitalWrite(pin, HIGH);

  //delay(1000);
  //return;
  //Serial.print("sleep_enable\n");


  /* Now is the time to set the sleep mode. In the Atmega8 datasheet
     http://www.atmel.com/dyn/resources/prod_documents/doc2486.pdf on page 35
     there is a list of sleep modes which explains which clocks and
     wake up sources are available in which sleep modus.

     In the avr/sleep.h file, the call names of these sleep modus are to be found:

     The 5 different modes are:
         SLEEP_MODE_IDLE         -the least power savings
         SLEEP_MODE_ADC
         SLEEP_MODE_PWR_SAVE
         SLEEP_MODE_STANDBY
         SLEEP_MODE_PWR_DOWN     -the most power savings

     For now, we want as much power savings as possible,
     so we choose the according sleep modus: SLEEP_MODE_PWR_DOWN

  */
  set_sleep_mode(SLEEP_MODE_PWR_DOWN);   // sleep mode is set here

  sleep_enable();              // enables the sleep bit in the mcucr register
  // so sleep is possible. just a safety pin

  /* Now is time to enable a interrupt. we do it here so an
     accidentally pushed interrupt button doesn't interrupt
     our running program. if you want to be able to run
     interrupt code besides the sleep function, place it in
     setup() for example.

     In the function call attachInterrupt(A, B, C)
     A   can be either 0 or 1 for interrupts on pin 2 or 3.

     B   Name of a function you want to execute at interrupt for A.

     C   Trigger mode of the interrupt pin. can be:
                 LOW        a low level triggers
                 CHANGE     a change in level triggers
                 RISING     a rising edge of a level triggers
                 FALLING    a falling edge of a level triggers

     In all but the IDLE sleep modes only LOW can be used.
  */

  attachInterrupt(0, wakeUpNow, RISING ); // use interrupt 0 (pin 2) and run function
  // wakeUpNow when pin 2 gets LOW

  sleep_mode();                // here the device is actually put to sleep!!
  //

  sleep_disable();             // first thing after waking from sleep:
  // disable sleep...


  detachInterrupt(0);          // disables interrupt 0 on pin 2 so the
  // wakeUpNow code will not be executed
  // during normal running time.
  power_all_enable();/* Re-enable the peripherals. */

  delay(100);                 // wat 2 sec. so humans can notice the
  // interrupt.
  // LED to show the interrupt is handled
  digitalWrite (pin, LOW);      // turn off the interrupt LED

}

void wakeUpNow()
{ //Serial.print("wakeUpNow\n");
  f_sleepButton = 0;
  //digitalWrite(pin, LOW);
  //attachInterrupt(0,sleepNow, FALLING ); // 睡眠模式
}

void clearsleepTimer() {
  f_sleepTimer = 0;
}

 

arduino学习备忘——WS2812B柔性拼接屏

2018-10-5 今日为了中旬的上海展会在调试led拼接屏,备忘如下:

1、之前困扰许久的显示过亮问题可以通过将RgbColor转换为然后HslColor调低L(亮度)来实现,初步测试亮度为0.1~0.01区间即可。

arduino中的HslColor取值:

H:Hue(色调)。0~1,0表示红色,0.33表示绿色,0.67表示蓝色

S:Saturation(饱和度)。取值为:0.0% - 100.0%

L:Lightness(亮度)。取值为:0.0% - 100.0%

 

2、每个WS2812B的LED小灯珠0.3W,具体说明如下:

主要特点

  • 智能反接保护,电源反接不会损坏IC。
  • IC控制电路与LED点光源公用一个电源。
  • 控制电路与RGB芯片集成在一个5050封装的元器件中,构成一个完整的外控像素点。
  • 内置信号整形电路,任何一个像素点收到信号后经过波形整形再输出,保证线路波形畸变不会累加。
  • 内置上电复位和掉电复位电路。
  • 每个像素点的三基色颜色可实现256级亮度显示,完成16777216种颜色的全真色彩显示,扫描频率不低于400Hz/s。
  • 串行级联接口,能通过一根信号线完成数据的接收与解码。
  • 任意两点传传输距离在不超过5米时无需增加任何电路。
  • 当刷新速率30帧/秒时,级联数不小于1024点。
  • 数据发送速度可达800Kbps
  • 光的颜色高度一致,性价比高。

主要应用领域

  • LED全彩发光字灯串,LED全彩模组, LED全彩软灯条硬灯条,LED护栏管。
  • LED点光源,LED像素屏,LED异形屏,各种电子产品,电器设备跑马灯。

引用自:WS2812B电路与引脚图及规格书下载 RGB5050资料(出处: 单片机论坛)

低压大功率电器的电线选择(LED整列)

查表可得不同温度下铜的电阻率:
0 0.0165欧姆平方毫米/米
10 0.0172欧姆平方毫米/米
20 0.0178欧姆平方毫米/米
30 0.0185欧姆平方毫米/米
35 0.0188欧姆平方毫米/米
40 0.0192欧姆平方毫米/米
50 0.0200欧姆平方毫米/米
60 0.0206欧姆平方毫米/米
70 0.0212欧姆平方毫米/米
75 0.0216欧姆平方毫米/米
80 0.0219欧姆平方毫米/米
90 0.0226欧姆平方毫米/米
100 0.0233欧姆平方毫米/米

 

线路选取计算公式:

5v供电,1米,20A,降压控制在0.5v

假设用铜线,全部按最大计算,R=0.0175欧*1米*2条*/S=0.5V/20A,
S=0.0175欧*1M*2*20A/0.5V=1.4
解得:S=1.4,取1.5平方铜线。

 

如果距离加长,需要大大增加导线截面积!

 

 

2018/10/5 加电测试所得,如果长时间保持全屏100%亮度显示,70A电压的风扇会持续工作,LED屏的功率还是很可观的,0.3W/个,加起来耗电相当厉害,此时使用的是2.5平方2米的线。