遥控变色灯

课程作业总是没完没了。有时候不得不日复一日地做同样的事情,虽然明明知道不久就会全忘掉。

早晨起来就开始琢磨这次信息产品课要做点什么。淘宝上买的蓝牙模块还没有送到,电脑无线互动做不了。而且第一周是基本练习,包括数字输入输出,模拟输入输出,串口上载和下载,开关。原材料也很少,电阻,LED,一个全彩LED,遥控器,还有光敏二极管,电位器,开关,小键盘什么的。最后选择了全彩LED和红外遥控器。全彩LED我是第一次用,红外遥控看起来很酷。他们拼起来便是一个遥控变色灯。

原理设想比较简单,通过红外遥控输入控制信号,使R,G,B值增减,单片机控制三路PWM输出的占空比,从而达到变幻颜色的目的。电路也很快搭好了,只接了两个元件:全彩LED,红外接收器。全彩LED使用了9,10,11三个PWM端口,而红外接收器接在13端口。
遥控彩灯原理图示意
Arduino有现成的红外接收库。一开始就非常顺利地接收了红外遥控的信号,并记录下了每个键所对应的值,这是通过串口发送电脑回来的。很特别的是,当一直按下一个键时,后续会重复返回FFFFFFFF。然后根据按键控制红灯的亮度,并设计成若一直按下,则会重复动作,这样就不必按很多次按钮了。

当我们如法炮制,添加了绿灯,一切正常,添加了蓝灯,却无法工作。按下蓝灯控制键,程序便会中断。这是为什么呢?我们开始一直以为是遥控的原因,更换了遥控上的其他键来控制,情况是一样的。后来我们又检查程序,将可能的错误修正。但依旧是红绿灯正常,而蓝灯不能使用。三个灯应该是对等的,如果其他两个没有问题,说明程序是可行的。既然该换了按键也没有用,说明遥控这部分也没有问题。我们将蓝绿调换,发现蓝色可以正常工作,说明全彩LED正常。所以最终有问题的是电路板硬件或者连接。蓝灯接入的11端口可能存在问题,便将其该换到6号端口,如此就解决了问题。

AVR单片机的6路PWM是有差异的。Arduino将其同质化处理,虽然简化了认知过程,但导致很多问题无法解释。机器人协会曾经也讨论过是否要引进Arduino,但后来还是否定了这个计划。因为Arduino的思维方式虽然在早期能够快速入门,但却导致在进阶的过程中处处遭遇困难。以后再去认识硬件细节的设计,摒弃原有的理解,是非常困难的。

IMG_0054

IMG_0055

IMG_0056

#include "IRremote.h"

int RECV_PIN = 13;

int red = 0;
int blue = 0;
int green = 0;

int last = 0;
int now = 0;
 
IRrecv irrecv(RECV_PIN);
 
decode_results results;
 
void setup() {
  Serial.begin(9600);
  irrecv.enableIRIn();
  pinMode(9, OUTPUT);
  pinMode(10, OUTPUT);
  pinMode(6, OUTPUT);
}
 
void loop() {
  
  if (irrecv.decode(&results)) {
    now = results.value;
    Serial.println(now);
    
    if(now==-1)
      now = last;
    
    switch(now){
      case -23971:
	if(red==0)
	  red=255;
	else
	  red--;
	break;
      case 25245:
	if(red==255)
	  red=0;
	else
	  red++;
	break;
      case 8925:
	if(green==0)
	  green=255;
	else
	  green--;
	break;
      case 765:
	if(green==255)
	  green=0;
	else
	  green++;
	break;
      case -8161:
	if(blue==0)
	  blue=255;
	else
	  blue--;
	break;
      case -22441:
	if(blue==255)
	  blue=0;
	else
	  blue++;
	break;
      case -7651:
	red=0;
	green=0;
	blue=0;
	break;
      default:break;
    }
    irrecv.resume();
    last = now;
  }
  
  color(red, green, blue);            
}

void color(int r, int g, int b){
  analogWrite(9, r);
  analogWrite(10, g);
  analogWrite(6, b);
}

发表评论

电子邮件地址不会被公开。 必填项已用*标注

This site uses Akismet to reduce spam. Learn how your comment data is processed.