|
本帖最后由 shenhaiyu 于 2012-10-10 12:13 编辑
最近需要做一套带有测风速功能的仪器,苦于网上和坛子里都没有例子,于是自己动手改造了一个。
使用了TB买的一个手持风向风速仪,
将下面的把手拆掉,将原先4.5V的电源线接入Arduino的5V电源,GND接GND。风速仪里面是一个4叶的光电编码器,在板子上找到编码器信号放大的输出点,焊上一条引线接入Arduino的 Pin 2 做外部中断。
当时以为外部中断会打断正在运行的程序重新从loop的头部开始运行,
于是发了求助帖:http://www.geek-workshop.com/thread-2106-1-1.html
后来还是决定自己写程序试一下,代码如下:- float sCode = 0; // 码盘计数(即状态跳变次数)
- float ws = 0; // 1s 平均(瞬时)风速
- unsigned long t1 = 0, t2 = 0; // 时间标记
- void setup()
- {
- Serial.begin(9600); // 初始化串口通信
- attachInterrupt(0, Code, CHANGE); // 设置风杯码盘外部中断
- }
- void loop()
- {
- t1=0;
- while(1)
- {
- Serial.print(t1);
- Serial.print(" ");
- Serial.println(sCode);
- t1++;
- }
- }
- // 风速码盘计数
- void Code()
- {
- sCode += 1; // 码盘计数加一
- }
复制代码 运行后转动风杯,可以看到串口监视器里显示类似这样的值:
384 37.00
385 37.00
386 37.00
387 37.00
388 38.00
389 38.00
390 38.00
391 39.00
392 39.00
393 39.00
394 40.00
395 40.00
396 40.00
397 40.00
398 41.00
399 41.00
400 41.00
401 42.00
402 42.00
403 42.00
404 43.00
405 43.00
406 43.00
407 43.00
408 44.00
409 44.00
410 44.00
411 45.00
412 45.00
413 45.00
414 45.00
415 46.00
416 46.00
417 46.00
418 47.00
419 47.00
420 47.00
421 47.00
422 48.00
423 48.00
424 48.00
425 49.00
426 49.00
427 49.00
428 49.00
429 50.00
430 50.00
431 50.00
432 51.00
433 51.00
434 51.00
435 51.00
436 52.00
437 52.00
438 52.00
439 53.00
440 53.00
441 53.00
442 53.00
443 54.00
444 54.00
445 54.00
446 55.00
447 55.00
448 55.00
449 55.00
450 56.00
451 56.00
452 56.00
453 56.00
454 57.00
455 57.00
证明程序没有因外部中断而重新在loop开始处运行,但是会对程序运行时间有一定影响。
既然实验证明了中断发生后,程序会回到中断发生的地方继续执行,于是决定将这部分功能直接写入我的系统中。
下面是完整的瞬时风速(准确说是1s平均风速)程序,也给大家留个参考吧(补充了计算时关闭中断的函数):- float sCode = 0; // 码盘计数(即状态跳变次数)
- float ws = 0; // 1s 平均(瞬时)风速
- unsigned long t1 = 0, t2 = 0; // 时间标记
- void setup()
- {
- Serial.begin(9600); // 初始化串口通信
- attachInterrupt(0, Code, CHANGE); // 设置风杯码盘外部中断
- }
- void loop()
- {
- t1 = millis();
- if(abs(t1 - t2) >= 1000) // 1000ms 时间间隔
- {
- detachInterrupt(0) // 关闭中断
- t2 = t1; // 更新时间标记
- ws = 2 * 3.14159265 * 0.025 * 2.9 * (sCode / 8); // 计算风速 u=2πRbn
- Serial.println(ws); // 输出 1s 平均(瞬时)风速
- sCode = 0; // 码盘计数归零
- delay(1);
- attachInterrupt(0, Code, CHANGE); // 重新设置外部中断
- }
- }
- // 风速码盘计数
- void Code()
- {
- sCode += 1; // 码盘计数加一
- }
复制代码 其中风速计算这句:
ws = 2 * 3.14159265 * 0.025 * 2.9 * (sCode / 8);
还可以改进一下,不使用这种误差较大的线性公式,换用这里提到的完整公式:
http://wenku.baidu.com/view/06705521af45b307e871971d.html
欢迎大家讨论改进的办法~~~~~ |
本帖子中包含更多资源
您需要 登录 才可以下载或查看,没有帐号?注册
x
|