2018年6月4日 星期一

Digispark chap2.通訊應用-3 IR紅外線遙控器按鍵讀取(UART to PC)

對於一般的專題製作,如果希望有無線遙控的功能
最簡單而且低成本的方式,就是運用加裡老舊的紅外線遙控器
Digispark搭配一個紅外線接收器就可以簡單地達到遙控的功能
如同家裡的冷氣、電視遙控器

學會了這個簡單的IR遙控器後,還可以控制不少東西,可能實現的範例如下
1.居家的燈光控制:搭配一個繼電器,就可以簡單的控制家中的燈光
2.搭配一個輪型平台,LM298就可以做成簡單的遙控車
3.搭配WS2812 RGB LED,可以簡單的控制RGB 3色的燈光
這幾個都是非常簡單可以達成的小實驗,如果下次有機會,會再補充在網誌上

本篇文章,希望運用Digispark搭配紅外接收(IRM0208-A538),讀取一般遙控器的協定
將資料再透過UART傳到電腦端,這個實驗可以幫助我們判讀遙控器每個按鍵的碼
將來在實際上製作東西的時候,就可以透過判讀這個碼來控制其他東西



相關接線方式:



範例程式碼:
 1  
 2 #include  <SoftSerial.h>
 3  
 4 uint8_t situation = 0;
 5 uint8_t START = 0;
 6 uint8_t x = 0;
 7 uint8_t BIT = 0;
 8 uint8_t Id = 0;
 9 uint8_t Id_inv = 0;
10 uint8_t Data = 0;
11 uint8_t Data_back = 0;
12 uint8_t Data_inv = 0;
13 uint8_t Repeat = 0;
14 uint8_t sended = 0;
15  
16 uint16_t Time_old = 0;
17 uint16_t Time = 0;
18 uint16_t TimeDelta = 0;
19  
20 SoftSerial Serialport(5, 0 );      //設定Rx/Tx對應的PIN
21 unsigned char Serialdata[32],Serial_DATA;
22 int Serial_num;
23  
24 void setup(void) {
25   attachInterrupt(0, IR_Read, FALLING);
26   pinMode(1,OUTPUT);
27   digitalWrite(1,LOW);
28  
29   Serialport.begin(9600);
30   Serialport.write("SoftSerial Test \r\n");
31 }
32  
33 void loop(void) {
34   if(sended == 1) {
35  
36     Serialport.write("IR data:");  //傳送字串
37     Char_to_Uart((unsigned char)Id);
38     Serialport.write(",");  //傳送字串
39     Char_to_Uart((unsigned char)Id_inv);
40     Serialport.write(",");  //傳送字串
41     Char_to_Uart((unsigned char)Data_back);
42     Serialport.write(",");  //傳送字串
43     Char_to_Uart((unsigned char)Data_inv);
44     Serialport.write(",\r\n");  //傳送字串
45  
46     sended = 0;
47   } else {
48  
49   }
50 }
51  
52 void IR_Read(void) {
53   digitalWrite(1,HIGH);
54   Time = micros();
55   if (Time_old != 0) {
56     TimeDelta = Time - Time_old;
57     if ((TimeDelta > 12000)&&(TimeDelta < 14000)) {
58       START = 1;
59       x = 0;
60       situation = 1;
61       Id = 0;
62       Id_inv = 0;
63       Data = 0;
64       Data_inv = 0;
65     } else if ((TimeDelta > 10000)&&(TimeDelta < 12000)) {
66       situation = 2; // repeat
67     } else if ((TimeDelta > 1500)&&(TimeDelta < 2500)) {
68       situation = 3; //"1"
69       BIT = 1;
70     } else if ((TimeDelta > 1000)&&(TimeDelta < 1500)) {
71       situation = 3; //"0"
72       BIT = 0;
73     } else situation = 5; 
74  
75     if (situation == 3) {
76       if (x < 8) {
77         Id |= BIT;
78         if (x < 7) Id <<= 1;  
79         x++;
80       } else if (x < 16) {
81         Id_inv |= BIT;
82         if (x < 15) Id_inv <<= 1;
83         x++;
84       } else if (x < 24) {
85         Data |= BIT;
86         if (x < 23) Data <<= 1;
87          x++;
88       } else if (x < 32) {
89         Data_inv |= BIT;
90         if (x < 31) {
91           Data_inv <<= 1;
92         } else {    
93           /* DO SOMETHING HERE */
94           sended = 1;
95  
96           Data_back = Data;
97           Repeat = 0;
98         }
99         x++;
100       }
101     } else if (situation == 2) {
102       if(Repeat == 1) {     
103         /* DO SOMETHING HERE */
104         /*sended = 1;*/
105       } else {
106         Repeat = 1;
107       }
108     }
109   }
110   Time_old = Time;
111   digitalWrite(1,LOW);
112 }
113  
114 void Char_to_Uart(unsigned char ChartoUart_NUM) {
115 unsigned char ChartoUart_TEMP;
116  
117 ChartoUart_TEMP=ChartoUart_NUM/100;
118 Serialport.write(ChartoUart_TEMP+'0');
119 ChartoUart_NUM=ChartoUart_NUM-(ChartoUart_TEMP*100);
120  
121 ChartoUart_TEMP=ChartoUart_NUM/10;
122 Serialport.write(ChartoUart_TEMP+'0');
123 ChartoUart_NUM=ChartoUart_NUM-(ChartoUart_TEMP*10);
124  
125 ChartoUart_TEMP=ChartoUart_NUM;
126 Serialport.write(ChartoUart_TEMP+'0'); 
127 }
128  

電腦端接收到的資料:
每一行代表一個按鍵的資料,第三組資料代表的是按鍵的位置代碼

沒有留言:

張貼留言

專題許願池,請不要吝嗇將你想製作的專題用回覆的方式寫在下方

專題許願池 開這個板是為了幫助一些人,有專題製作需求,但是又不知道要如何實現 如果您有想製作的專題,請您將您的題目回覆在下方,先提出您的需求,進而討論可行性或製做的方向,或是您進行到什麼階段,有遇到什麼樣的問題也可以提出來討論,如果我知道會盡量幫助您順利完成。 不限...