佳礼资讯网

 找回密码
 注册

ADVERTISEMENT

查看: 1136|回复: 0

Digispark红外接收器

[复制链接]
发表于 1-6-2013 06:18 PM | 显示全部楼层 |阅读模式
之前的红外遥控制作都是使用别人的代码或程序库完全。其中Ken Shirriff 的Arduino红外程序库,更是许多Arduino发烧友使用之设计红外制作。

不过这个适合不同红外协议的Ken Shirriff红外程序库並不适合用在Digispark,因为代码复杂,工作繁重,根本不能置入Digispark。没有办法之下唯有自行研究。

由于不熟悉红外原理,花费了一些时间在网站浏览资料,同时一面阅读资料一面测试,终于大功告成。

了觧一下Digispark自带的红外例子
Digispark自带了一个infrared例子,却没有对红外协议分析,按下任何遥控器按钮,只能触发同一事件。以下例子按下任何按钮,都会点亮LED,一秒后关灯。
  1. int irPin=2;  //digital 2 (ATTINT85 pin 7)
  2. int ledPin=0; //digital 0 (ATTINY85 pin 5)

  3. void setup()
  4. {
  5. pinMode(irPin,INPUT);
  6. pinMode(ledPin,OUTPUT);
  7. digitalWrite(0,HIGH);
  8. }

  9. void loop()
  10. {
  11.   if(pulseIn(irPin,LOW)) //reads a pulse on a pin
  12.   {
  13.      //button pressed
  14.      delay(100);
  15.      digitalWrite(ledPin,HIGH);
  16.      delay(1000);
  17.      digitalWrite(ledPin,LOW);
  18.   }  
  19. }
复制代码
代码运用了pulseIn来侦察红外信号。pulseIn是用来侦察谋个引脚的脉冲升高或降低,以便测量其长度,而长度则以微秒(microseconds)计算。

根据以上代码(Sketch),我设计了以下线路图。





下面例子使用Arduino(不是Digispark)作红外解码,毎一个脉冲的长度将从串行监控器(Serial monitor)显示在屏幕上。
  1. int irPin = 2; //IR detector connected to digital 2
  2. const byte BIT_PER_BLOCK = 32;

  3. void setup() {
  4.   pinMode(irPin, INPUT);
  5.   Serial.begin(9600);
  6. }
  7. void loop() {
  8.   int data[BIT_PER_BLOCK];
  9.   int i;  

  10.   for(i = 0 ; i < BIT_PER_BLOCK ; i++) {
  11.     //Start measuring bits, I only want high pulses
  12.     //you may want to use LOW pulse --> pulseIn(irPin, LOW)
  13.     data[i] = pulseIn(irPin, HIGH);   
  14.   }

  15.   delay(100);
  16.   for(i = 0 ; i < BIT_PER_BLOCK ; i++) {
  17.     Serial.println(data[i]);
  18.   }  
  19.   Serial.println("=========");
  20. }
复制代码
以下是我的红外数据採样


更完整的数据採样


当然你也可以使用Digispark,将获取的红外资料,通过模拟键盘发送数据至电脑,同时打开文本编辑器(如Windows Notepad)来查看数据,但是此方式的显示速度要比使用串行监视慢许多。
  1. #include "DigiKeyboard.h"
  2. int irPin = 2; //IR receiver wired to digital 2 (ATTINY pin7)
  3. const byte BIT_PER_BLOCK = 32;
  4. void setup() {
  5.   pinMode(irPin, INPUT);
  6.   Serial.begin(9600);
  7. }
  8. void loop() {
  9.   int data[BIT_PER_BLOCK];
  10.   int i;  

  11.   // this is generally not necessary but with some older systems it seems to
  12.   // prevent missing the first character after a delay:
  13.   DigiKeyboard.sendKeyStroke(0);  

  14.   for(i = 0 ; i < BIT_PER_BLOCK ; i++) {
  15.     //Start measuring bits, I only want high pulses
  16.     //you may want to use LOW pulse --> pulseIn(irPin, LOW)
  17.     data[i] = pulseIn(irPin, HIGH);
  18.   }

  19.   delay(100);
  20.   for(i = 0 ; i < BIT_PER_BLOCK ; i++) {
  21.     DigiKeyboard.println(data[i]);
  22.   }  
  23.   DigiKeyboard.println("=========");
  24. }
复制代码
这里发放完整且可以运行的源代码(针对NEC协议),如想要知道如何工作及分析其他的红外协议,去浏览我的个人网站吧!

以下代码把处理了的NEC红外信号,转换成整数(decimal),通过模拟键盘发送数据至电脑,从而显示各按钮的值。
  1. #include "DigiKeyboard.h"
  2. int irPin = 2; //Sensor pin connect to digital pin2 (ATINY85 pin7)
  3. int start_bit = 2200; //Start bit threshold (Microseconds)
  4. int bin_1 = 1000; //Binary 1 threshold (Microseconds)
  5. int bin_0 = 400; //Binary 0 threshold (Microseconds)
  6. const byte BIT_PER_BLOCK = 32;

  7. void setup() {
  8.   pinMode(irPin, INPUT);
  9. }

  10. void loop() {
  11.   DigiKeyboard.update(); //keep on updating the keyboard
  12.   // this is generally not necessary but with some older systems it seems to
  13.   // prevent missing the first character after a delay:
  14.   DigiKeyboard.sendKeyStroke(0);

  15.   int key = getIRKey();        //Fetch the key

  16.   if(key != 0) //Ignore keys that are zero
  17.   {
  18.     DigiKeyboard.print("=>");  //uncomment this if you want to
  19.     DigiKeyboard.println(key); //print out the value of the button
  20.   }
  21. }

  22. /////////////////////////////////////////////////////////////
  23. // decode infrared signal
  24. /////////////////////////////////////////////////////////////
  25. int getIRKey() {
  26.   int data[BIT_PER_BLOCK];
  27.   int i;
  28.   while(pulseIn(irPin, HIGH) < start_bit); //Wait for a start bit

  29.   for(i = 0 ; i < BIT_PER_BLOCK ; i++)
  30.     data[i] = pulseIn(irPin, HIGH); //Start measuring bits, I only want HIGH pulses

  31.   delay(100);  
  32.   for(i = 0 ; i < BIT_PER_BLOCK ; i++) //Parse them
  33.   {   
  34.     if(data[i] > bin_1) //is it a 1?
  35.       data[i] = 1;
  36.     else if(data[i] > bin_0) //is it a 0?
  37.       data[i] = 0;
  38.     else
  39.       return -1; //Flag the data as invalid;  Return -1 on invalid data
  40.   }
  41.   //based on NEC protocol, command data started from bit 16
  42.   //and end with bit 24 (8 bits long)
  43.   int result = 0;
  44.   for(i = 16 ; i < 24; i++) {
  45.     DigiKeyboard.print(data[i]); //print out the value of button in binary form
  46.     if(data[i] == 1) result |= (1<<i-16); //Convert data bits to integer
  47.   }  
  48.   return result; //Return key number
  49. }
复制代码
以下代码用于遥控电脑。我用来遥控点唱。此代码占用了4408 Byte Flash Memory,可以使用的Flash Memory剩下1604 Byte 。
  1. #include "DigiKeyboard.h"
  2. // not all keys are mapped in the DigiKeyboard.h file.
  3. // you have to map it here
  4. #define KEY_HOME   0x4A
  5. #define KEY_PAGE_UP   0x4B
  6. #define KEY_PAGE_DOWN   0x4E
  7. #define KEY_ESCAPE   0x29
  8. #define KEY_UP_ARROW   0x52
  9. #define KEY_DOWN_ARROW   0x51
  10. #define KEY_LEFT_ARROW   0x50
  11. #define KEY_RIGHT_ARROW   0x4F

  12. int irPin = 2; //Sensor pin connect to digital pin2 (ATINY85 pin7)
  13. int start_bit = 2200; //Start bit threshold (Microseconds)
  14. int bin_1 = 1000; //Binary 1 threshold (Microseconds)
  15. int bin_0 = 400; //Binary 0 threshold (Microseconds)
  16. const byte BIT_PER_BLOCK = 32;

  17. void setup() {
  18.   pinMode(irPin, INPUT);
  19. }

  20. void loop() {
  21.   DigiKeyboard.update(); // keep updating the keyboard
  22.   // this is generally not necessary but with some older systems it seems to
  23.   // prevent missing the first character after a delay:
  24.   DigiKeyboard.sendKeyStroke(0);

  25.   int key = getIRKey();        //Fetch the key

  26.   if(key != 0) //Ignore keys that are zero
  27.   {
  28.     //DigiKeyboard.print("=>");  //uncomment this if you want to
  29.     //DigiKeyboard.println(key); //print out the value of the button

  30.     switch(key)
  31.     {
  32.       case 78: DigiKeyboard.println("1"); break;
  33.       case 74: DigiKeyboard.println("2"); break;
  34.       case 70: DigiKeyboard.println("3"); break;
  35.       case 77: DigiKeyboard.println("4"); break;
  36.       case 73: DigiKeyboard.println("5"); break;
  37.       case 69: DigiKeyboard.println("6"); break;
  38.       case 76: DigiKeyboard.println("7"); break;
  39.       case 72: DigiKeyboard.println("8"); break;
  40.       case 68: DigiKeyboard.println("9"); break;   
  41.       case 12: DigiKeyboard.println("0"); break;
  42.       case 15: DigiKeyboard.sendKeyStroke(KEY_SPACE); break;
  43.       case  6: DigiKeyboard.sendKeyStroke(KEY_ENTER); break;   
  44.       case  4: DigiKeyboard.sendKeyStroke(KEY_ESCAPE); break;
  45.       case 81: DigiKeyboard.sendKeyStroke(KEY_HOME); break;
  46.       case 14: DigiKeyboard.sendKeyStroke(KEY_LEFT_ARROW); break;
  47.       case 10: DigiKeyboard.sendKeyStroke(KEY_RIGHT_ARROW); break;
  48.       case 11: DigiKeyboard.sendKeyStroke(KEY_DOWN_ARROW); break;  
  49.       case  7: DigiKeyboard.sendKeyStroke(KEY_UP_ARROW); break;   
  50.     }   
  51.   }
  52. }

  53. /////////////////////////////////////////////////////////////
  54. // decode infrared signal
  55. /////////////////////////////////////////////////////////////
  56. int getIRKey() {
  57.   int data[BIT_PER_BLOCK];
  58.   int i;
  59.   while(pulseIn(irPin, HIGH) < start_bit); //Wait for a start bit

  60.   for(i = 0 ; i < BIT_PER_BLOCK ; i++)
  61.     data[i] = pulseIn(irPin, HIGH); //Start measuring bits, I only want HIGH pulses

  62.   delay(100);  
  63.   for(i = 0 ; i < BIT_PER_BLOCK ; i++) //Parse them
  64.   {   
  65.     if(data[i] > bin_1) //is it a 1?
  66.       data[i] = 1;
  67.     else if(data[i] > bin_0) //is it a 0?
  68.       data[i] = 0;
  69.     else
  70.       return -1; //Flag the data as invalid;  Return -1 on invalid data
  71.   }

  72.   //based on NEC protocol, command data started from bit 16
  73.   //and end with bit 24 (8 bits long)
  74.   int result = 0;
  75.   for(i = 16 ; i < 24; i++) {
  76.     //DigiKeyboard.print(data[i]); //print out the value of button in binary form
  77.     if(data[i] == 1) result |= (1<<i-16); //Convert data bits to integer
  78.   }  
  79.   return result; //Return key number
  80. }
复制代码
最後一个是4路红外遥控 使用相同的红外遥控器来控制4个LED,按下各自按键将会切换各自相关LED。完成代码(Sketch)上载后 ,你可以除去1.5K电阻,两个68ohm电阻和两个Zener二极管。
有句广东话:打完齊唔要和尚
此代码占用了1682Byte Flash Memory,可以使用的Flash Memory剩下4330 Byte 。
  1. int irPin = 2;   //Sensor pin connect to digital pin2 (ATINY85 pin7)
  2. int led1 = 0; //led connect to digital pin0 (ATTINY85 pin5)
  3. int led2 = 1; //led connect to digital pin1 (ATTINY85 pin6)
  4. int led3 = 3; //led connect to digital pin3 (ATTINY85 pin2)
  5. int led4 = 4; //led connect to digital pin4 (ATTINY85 pin3)
  6. int start_bit = 2200; //Start bit threshold (Microseconds)
  7. int bin_1 = 1000; //Binary 1 threshold (Microseconds)
  8. int bin_0 = 400; //Binary 0 threshold (Microseconds)
  9. const byte BIT_PER_BLOCK = 32;

  10. void setup() {
  11.   pinMode(irPin, INPUT);
  12.   pinMode(led1, OUTPUT);
  13.   pinMode(led2, OUTPUT);
  14.   pinMode(led3, OUTPUT);
  15.   pinMode(led4, OUTPUT);
  16.   digitalWrite(led1, LOW); //turn off LED
  17.   digitalWrite(led2, LOW);
  18.   digitalWrite(led3, LOW);
  19.   digitalWrite(led4, LOW);
  20. }

  21. void loop() {
  22.   int key = getIRKey();        //Fetch the key

  23.   if(key != 0) //Ignore keys that are zero
  24.   {
  25.     switch(key)
  26.     {
  27.       case  78: toggleLED(led1); break;
  28.       case  74: toggleLED(led2); break;
  29.       case  70: toggleLED(led3); break;
  30.       case  77: toggleLED(led4); break;
  31.     }   
  32.   }
  33. }

  34. /////////////////////////////////////////////////////////////
  35. // toggle led
  36. /////////////////////////////////////////////////////////////
  37. void toggleLED(byte ledPin) {
  38.   if(digitalRead(ledPin) != 1) //This toggles the led
  39.     digitalWrite(ledPin, HIGH);
  40.   else
  41.     digitalWrite(ledPin, LOW);   
  42. }
  43. /////////////////////////////////////////////////////////////
  44. // decode infrared signal
  45. /////////////////////////////////////////////////////////////
  46. int getIRKey() {
  47.   int data[BIT_PER_BLOCK];
  48.   int i;
  49.   while(pulseIn(irPin, HIGH) < start_bit); //Wait for a start bit

  50.   for(i = 0 ; i < BIT_PER_BLOCK ; i++)
  51.     data[i] = pulseIn(irPin, HIGH); //Start measuring bits, I only want HIGH pulses

  52.   delay(100);  
  53.   for(i = 0 ; i < BIT_PER_BLOCK ; i++) //Parse them
  54.   {   
  55.     if(data[i] > bin_1) //is it a 1?
  56.       data[i] = 1;
  57.     else if(data[i] > bin_0) //is it a 0?
  58.       data[i] = 0;
  59.     else
  60.       return -1; //Flag the data as invalid;  Return -1 on invalid data
  61.   }

  62.   //based on NEC protocol, command data started from bit 16
  63.   //and end with bit 24 (8 bits long)
  64.   int result = 0;
  65.   for(i = 16 ; i < 24; i++) {
  66.     if(data[i] == 1) result |= (1<<i-16); //Convert data bits to integer
  67.   }  
  68.   return result; //Return key number
  69. }
复制代码
本帖最后由 西门庆33 于 1-6-2013 07:27 PM 编辑

回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

 

ADVERTISEMENT



ADVERTISEMENT



ADVERTISEMENT

ADVERTISEMENT


版权所有 © 1996-2023 Cari Internet Sdn Bhd (483575-W)|IPSERVERONE 提供云主机|广告刊登|关于我们|私隐权|免控|投诉|联络|脸书|佳礼资讯网

GMT+8, 20-4-2024 01:01 AM , Processed in 0.061597 second(s), 27 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表