2012年07月 文档列表

用一块Arduino输出多路PWM

【经wwwtiger同学提醒,关于Arduino原生PWM的频率,我之前的理解是错的,应该是490Hz左右,特此更正】

周末有朋友来家里玩,看到了放在角落里的那个大的四轴飞行器。拿下来看了看,发现上面已经落满了灰尘。应该有几个月没动了,当时写的攻略目录也好久没更新了。这段时间打算抽空陆陆续续把这个页面里的目录内容都补齐,免得成为烂尾工程。可惜实验还没有成功,所以不能算是经验,各位兄弟权当教训看吧 :)

四轴飞行器最终的控制手段,就是分别调节4个电机的转速。对于常见的无刷电机,一般通过高电平在0.9ms~2.1ms左右的PWM来控制转速。这就涉及到如何用arduino输出多路PWM的问题,在Arduino中,一般可以通过下面这些方式来输出PWM方波:

1. 用原生的PWM输出功能
把pinMode定义为输出,然后用analogWrite就可以输出PWM。以Arduino Mega 1280为例,它有14路PWM输出。analogWrite的参数范围是0~255,对应的是0~2ms的高电平。
一般情况下,原生的PWM频率固定为490Hz,通过一些参数的修改,可以提高PWM频率,但是参数范围只能是0~255。

int pin = 8; //0~13

void setup()
{
    pinMode(pin, OUTPUT);
}   

void loop()
{
    analogWrite(pin, 128);
    delay(500);
}

2. 通过普通的输出管脚手动控制PWM

PWM归根结底无非就是输出0,1序列的方波,所以我们还可以简单的通过digitalWrite和delay来生成PWM方波。
这种方式的特点是可以非常精确的控制高电平时间和PWM周期,缺点是CPU时间不好充分利用,多路时编程有点复杂。

void loop()
{
  long t0 = micros(); //记录进入loop的时间
  double T = 20000; //一个周期的微秒值
  double len = 900;  //高电平时间
  for(int i = 0; i < 4; i++) digitalWrite(pins[i], HIGH);
  delayMicroseconds(len);
  for(int i = 0; i < 4; i++) digitalWrite(pins[i], LOW);
  /*
   *在这里干别的事情
   */
  int leftMs = (int) (t0 + T - micros()); //剩余时间
  if(leftMs < 0 ) leftMs = 0; //万一超出周期,只能立刻中止
  delayMicroseconds(leftMs);
}

3. 用servo库
Servo库是Arduino用来控制伺服电机的,印象中是使用了内部中断来触发的,所以主程序只管干自己的事情,时间到了PWM就会自动触发。
它默认的频率是50Hz,但是可以在头文件中修改。文件位置是arduino-0023\libraries\Servo.h,修改下面这行可以把PWM频率升到400Hz:
#define REFRESH_INTERVAL 2500

具体的细节在之前的一篇小结里提到了:Arduino自带的Servo库小实验

先记录这些,希望在把全部的“教训”写完之前,能有空把四轴飞起来 :)

热水先结冰?

这几天不知道为什么,一条新闻被各个报纸转载:

【为何热水冻结更快?英国悬赏1000英镑求解】将一杯35℃的水和一杯100℃的水放入冰箱,100℃的水先结冰,这是为什么?此谜也称“姆佩巴效应”,培根和笛卡尔都曾试图揭谜,均告失败。现在,英国皇家化学学会向公众悬赏1000英镑破解,截止日期为7月30日。

如果你在网上搜一下,会看到很多答案,包括:越热的水散热越快、水中气体减少不容易结晶等等。
事实上十年前我读研的时候,就看过这个理论,当时觉得非常不靠谱,就做了一个实验。放了两杯水到窗外(当时北京正在冬季),事实证明这个理论基本是胡扯,冷水的杯子先结冰!

今天再次看到这些报纸转载,我决定再做一次实验。首先用一个量杯来保证两杯水是一样多的:

小量杯

小量杯

21:46分,同时放到温度为-18度的冰箱冷冻室,并且标上了冷热的记号:

冷水和热水同时放进冷冻室

冷水和热水同时放进冷冻室

我每隔几分钟就去看一次,到22:30分时,冷水杯表明出现薄薄的冰层,热水杯完全没有任何迹象。

冷水杯出现冰层,热水杯全是水

冷水杯先出现冰层

到22:50分时,热水杯出现薄薄的冰层,冷水杯上面冰层已经较厚了:

热水杯也开始结冰了热水杯出现冰层的时候,冷水杯已经比较厚了

到23点10分,冷水杯已经基本用手捏不动了,而热水杯底部还是软的。事实证明,还是冷水杯冻的更快!

哎呀,这么无聊的一个实验,我自己都觉得做的很不值啊。但是看到网上的各种原理说明,这些人就不能动手做一个毫无成本的实验吗?