2011年3月30日 星期三

1.1 接收紅外線訊號

實驗目的

練習用 IRRemote 函式庫接收紅外線訊號。在這個實驗裏,你將學習用 IRrecv 物件接收紅外線訊號。

前提

在做這個實驗前,我假設:

  1. 你已經看過「IRRemote 紅外線遙控教學」一文,而且
  2. 也已經把 IRRemote 函式庫安裝起來了
材料
接線
  • 照下表把紅外線接收器跟 Arduino 連接起來:
紅外線接收器接腳 Arduino 接腳
GND (-) 接到 GND
Vcc (+ 或 V+) 接到 +5V 電源
Vout (或 OUT) 接到 pin 2。你可以接到其它 Digital pin,但程式要配合修改

image 
▲ 有些紅外線接收器 GND 和 Vcc 是相反的,接線時請查閱你的 datasheet

程式

底下這支程式 (Example1.1.pde) 示範如何用 IRrecv 物件接收紅外線訊號:

在收到紅外線訊號的時候,程式會順便把收到的紅外線編碼以及編碼長度 (位元數) 列印到 Serial Port 上,所以在跑程式的時候就可以用 Serial Monitor 來觀察解碼結果。

如何用 IRrecv 物件接收紅外線訊號

要接收紅外線訊號,有四個步驟要做:

1) 引用 IRRemote 函式庫:

2) 建立一個 IRrecv 的物件以及一個用來存放解碼結果的 decode_results 結構的變數:

3) 呼叫 enableIRIn() 啟動紅外線解碼:

4) 這時候 IRrecv 物件會在背景收紅外線訊號。接著,就可以在 loop() 函式裏用 decode() 函式持續的檢查,看看有沒有解碼成功:

假如有成功解碼,decode() 函式會回傳 true,並且把解碼結果放在 result 變數裏。

在解到一個紅外線編碼後,記得要呼叫 resume() 函式,這樣才能繼續收下一組訊號。

示範照片

隨手拿起一個電視遙控器按幾個鈕測試:

image
▲ 接受紅外線訊號

打開 Serial Monitor 觀察,我得到的解碼結果如下:

 image
▲ 上圖中,紅外線編碼是以 16 進位格式顯示,我遙控器的編碼長度皆為 32 位元

動動腦
  1. 請找一個紅外線遙控器,電視、音響、手機、相機、投影機或是冷氣機的遙控器都可以,用這個實驗的範例程式測試,看看 IRRemote 能否為你的遙控器解碼。
  2. 閱讀「Arduino 筆記 – Lab6 控制蜂鳴器發聲」一文,試連接一顆蜂鳴器到 Arduino 板子上並修改範例程式,讓程式在收到紅外線時發個聲響。

67 意見:

凱富 提到...

請問需要插電阻嗎? 我接上電腦接受器就開始發燙了

Cooper Maa 提到...

你紅外線接收器用的是哪一顆(型號)? 接線是怎麼接的? 要注意有些紅外線接收器 GND 和 Vcc 是相反的喔!

Cyansky 提到...

請問若傳回值經常夾雜irCode: 0, bits: 0 會是什麼情形?
而且有時按一下遙控器會跑出多行傳回值... Thanks~
BTW,我用的是FM-8038TM2-5DN, GND在中間腳位

Cooper Maa 提到...

很可能是 NEC 的 repeat code,見 紅外線遙控原理與 NEC IR Protocol一文說明。

你可以用判斷式把它過瀘掉,像這樣:

if (irrecv.decode(&results) && results.value != 0) {
....
}

weigo chen 提到...

請問我執行程式之後,按遙控器之後只會回傳irCode: 0, bits: 0
會是哪個部分的問題呢?

Cooper Maa 提到...

@weigo_chen
那可能是 IRRemote 判斷不出來的紅外線協定。不過,IRRemote 會把它當作 UNKNOWN protocol,應該還是可以印出 irCode 的原始資料,請參考 IRremote library 的 IRrecvDump.pde 這個範例。

Cooper Maa 提到...

@青番
請參考我前面那則留言。

另外,如果收到的是 NEC Protocol 的 repeat code 的話,那麼 results.value 會是 -1。

小B 提到...

你好~請問為什麼我還沒按~irCode跑很多數值每次都不一樣

Cooper Maa 提到...

@liaw22
你是說還沒按遙控器就跑出很多 irCode 嗎?
我沒遇過這種情況,不曉得是哪裏的問題。

l21019 提到...

你好,我想請問關於第八行的decode_results results 雖然有看懂後面的注解,但對於寫法不是很了解,還有第十六行的 (irrecv.decode(&results)) ,對於為什麼要再括弧裡放&results也不是很了解,可以說明一下嘛,真的很謝謝你

Cooper Maa 提到...

hi,

decode_results results;

這行是宣告一個 decode_result 結構型別的變數,變數名稱叫 results。精確一點說,decode_result 其實是一個類別 (class),而 results 則是一個物件,所以這行其實應該這樣解釋「產生一個屬於 decode_result 這一類的物件」。

irrecv.decode(&results); 這行之所以用 &results 是因為 irrecv.decode() 會去改變 results 裏的內容,因此必須加一個 & 取址符號 (call by address)。關於 call by address,你可以參考一下這篇 http://edisonshih.pixnet.net/blog/post/27987626

chenanco 提到...

您好,我使用IRrecvDump.pde時,會出現三行資訊,
由上至下分別是:16進位紅外線碼,通訊協定,紅外線長度資訊,
想請問您,第一行出現"0"是什麼原因呢?

以下是我解出的紅外線碼:
0
Could not decode message
Raw (76): -28012 3500 -1650 500 -1250 400 -450 450 -400 500 -400 450 -1250 450 -400 500 -400 450 -400 450 -400 450 -1300 450 -400 450 -1250 500 -1250 450 -400 450 -1300 450 -1250 450 -1250 500 -1250 450 -1300 450 -400 450 -400 450 -1300 450 -400 450 -400 450 -400 500 -400 450 -400 450 -400 450 -1300 450 -1250 450 -1250 500 -1250 450 -400 450 -400 500 -400 450 -400 450

chenanco 提到...

而且以上解出的rawbuf並不能啟動相對應的裝置

chenanco 提到...

請問有什麼辦法讓raw length增長,我需要解一個總長0.5秒的紅外線碼,實際有幾個0與1的變化並不清楚

Cooper Maa 提到...

上面解出的紅外線應該是屬於 Unknown protocol,也就是不是 IRRemote 認得紅外線協定。從 Ircevdump.pde 的 code 看來,你解出的紅外線碼中,第一行的 0 是 results->value 的內容。之所以會是 0,很可能是 IRRemote 把不認得的 protocol 原始資料儲存在 rawbuf 裏,所以 results->value 就只放 0。

為什麼不能啟動相對應的裝置,這我也不太清楚,我是覺得如果解出的紅外線碼不完整,可能是其中一個原因。

Cooper Maa 提到...

有什麼辦法讓 raw length 增長?
你要不要試試調整 IRRemote.h L95 這行:

#define RAWBUF 76 // Length of raw duration buffer

目前是 76 個 entry,把它弄大一點或許有用

chenanco 提到...
作者已經移除這則留言。
小B 提到...
作者已經移除這則留言。
小B 提到...

請問~我以知紅外線碼,我想當等於irswitch時,發射另外一組紅外線碼~
long irswitch=0XCF358A7;
if (results.value == irswitch){
irsend.sendNEC(0xCF3906F, 32);}
我這樣試不行~大大幫解惑

Cooper Maa 提到...

應該是可行的啊,你可以試著在幾個地方印出訊息方便除錯,比如在解碼成功的時候印出收到的紅外線碼,還有在發現紅外線碼跟 irswitch 相同時也印出個訊息,像這樣:

long irswitch = 0xCF358A7;

if (irrecv.decode(&results))
{
Serial.print("irCode: ");
Serial.println(results.value, HEX);
if (results.value == irswitch) {
Serial.println("Sending IR...");
irsend.sendNEC(0xCF3906F, 32);
}
}

小B 提到...

不好意思~這是我的程式碼,在Serial有顯示SENDING沒錯但我的開關沒啟動!(我單一使用大大得按鈕發射試沒問題的)
#include
const int irReceiverPin = 2;
long irswitch=0xCF3D827;
IRrecv irrecv(irReceiverPin);
IRsend irsend;
decode_results results;
void setup()
{ Serial.begin(9600);
irrecv.enableIRIn();}
void loop()
{
if (irrecv.decode(&results))
{
Serial.print("irCode:");
Serial.println(results.value,HEX);
if (results.value == irswitch){
Serial.println("Sending IR.....");
irsend.sendNEC(0xCF310EF,32);
}
irrecv.resume();
}
}

Cooper Maa 提到...

譬如底下的 code,你的意思是像「2.1 發射紅外線訊號」這樣用一個發射按鈕是沒問題的嗎?

void loop()
{
// 讀取按鍵狀態
buttonState = digitalRead(buttonPin);

// 檢查按鍵是否被按下(pressed)
// 有的話,buttonState 會是 HIGH
if (buttonState == HIGH) {
irsend.sendNEC(0xCF310EF, 32);
}
}

你上面給的程式碼不 work,但是卻又會顯示 "Sending IR..." 的訊息嗎?

Mm..
我在猜一個可能是跟 irrrecv.resume(); 這行有關,也許 sendNEC() 跟 ir 接收功能彼此間會有影響,所以你要不要在這行前面加個一行試試,像這樣:

delay(100); // 加這行
irrrecv.resume();

另外,你把 irswitch 變數型別宣告成 long:

long irswitch=0xCF3D827;

建議你把它改成 unsigned long 跟 results.value 的型別一致比較好:

unsigned long irswitch=0xCF3D827;

對了,你紅外線發射器是接在 pin 3 嗎?

小B 提到...

恩恩~我使用按鈕發射2.1 發射紅外線訊號沒問題~我的發射有接在PIN3~
剛剛我改了unsigned long和加上delay還是失敗^^
在serial看有一個問題
就是~我第一次按下收得得值是正確的接著顯示SENDING....
但我接著在按一次紅外現竟然變成另外一組值~
我有把irrrecv.resume();這行砍掉~結果還是一樣~
我再想是不是衝突導致發射出去得值?

Cooper Maa 提到...

我看了一下 IRRemote.cpp,發現 IRRemote Library 在發射時會停掉接收功能,所以「第一次收到的是正確的,第二次卻不一樣。」可能跟這有關,你試試看把 irrecv.resume(); 換成 irrecv.enableIRIn(); 也許第二次收到的就會一樣了。

我想到一個方法,假如在發射前後都加個 delay,像這樣:

delay(100);
irsend.sendNEC(0xCF310EF, 32);
delay(100);

不曉得這樣會不會 work? 為什麼要這麼做,是因為我在想也許你按下遙控器 Arduino 也解碼成功時,因為 Arduino 會馬上發射,我在猜設備所以不 work 有沒有可能是在那瞬間遙控器跟 Arduino 發射紅外線剛好撞在一起的關係。也許你可以試試。

小B 提到...

真謝謝大大還幫我看程式碼,剛剛我測紅外線不會再改變了,我delay也把它拉長看看還是不能發射

Cooper Maa 提到...

前後都加 delay 然後還拉長 delay 時間還是不能發射嗎?

Mm.. 好,晚上回家我也來試試看

小B 提到...

是的!再麻煩你~

Cooper Maa 提到...

真的耶,IRRemote 沒辦法同時發射又接收
IRRemote 在發射的時候會把接收功能停掉
理論上,發射之後,我們再用 irrecv.enableIRIn(); 打開接收功能應該會可以動才對,可是卻不行。

我已經追蹤到一個事實,只要跑過 irrecv.enableIRIn(); 這行指令,發射功能就不 work 了。所以可能是 irrecv.enableIRIn(); 這個 function 裏動到了什麼,因而造成發射功能失效,可能要深入去看 irrecv.enableIRIn(); 才行

Cooper Maa 提到...

哈,找到原因了,原來是 IRRemote Library 的 bug,請改一下 IRRemoteInt.h L178 這行:

#define TIMER_DISABLE_INTR (TIMSK2 - 0)

把它修正為:

#define TIMER_DISABLE_INTR (TIMSK2 = 0)

這樣就行了。我試過,可以同時發射與接收。

記得要把 irrecv.resume(); 換成 irrecv.enableIRIn();

不然的話,接收功能只能跑一次,第二次接收功能就不 work 了。

小B 提到...

哈哈終於成功! 大大你辛苦辛苦!

Cooper Maa 提到...

不會,不會,只是碰巧發現而已。

小Y 提到...

請問一下各位前輩,我想實現同時送收的功能
我依照站長大大提到的lib修改,接收部分算是正常了
不過還是沒辦法發射,而把他們拆開獨立運行是OK的
我想要當arduino收到Serial的訊號之後發射_
其餘時間會一直掃描是否有紅外線的訊號
程式碼如下,他會跑Serial.print(3227957319, HEX);這段
但是 irsend.sendNEC(3227957319, 32);卻沒有效果
不知道問題出在哪邊 .. 請各位大大指教

#include

const int irReceiverPin = 2;

IRsend irsend;

IRrecv irrecv(irReceiverPin);
decode_results results;

void setup()
{
Serial.begin(9600);
irrecv.enableIRIn();
}

void loop()
{
if (Serial.read() != -1)
{
Serial.print(3227957319, HEX);
Serial.println();
delay(2000);
irsend.sendNEC(3227957319, 32);
delay(2000);
irrecv.enableIRIn();
}
if (irrecv.decode(&results)) {
showIRProtocol(&results);
irrecv.resume();
}
}

Cooper Maa 提到...

Hi, 請問你 IRRemoteInt.h L178 這行目前的內容是?

小Y 提到...

#define TIMER_DISABLE_INTR (TIMSK2 = 0)

小Y 提到...

我發現好像 irrecv.enableIRIn() 這段加進去
如果加在setup就後面連送都不能送
再送之後加 .. 就只能送一次

Cooper Maa 提到...

底下是我前幾天寫的程式,給你參考看看:

#include // 引用 IRRemote 函式庫

const int irReceiverPin = 2; // 紅外線接收器 OUTPUT 訊號接在 pin 2
IRsend irsend; // 定義 IRsend 物件來發射紅外線訊號

IRrecv irrecv(irReceiverPin); // 定義 IRrecv 物件來接收紅外線訊號
decode_results results; // 解碼結果將放在 decode_results 結構的 result 變數裏

void setup()
{
Serial.begin(9600); // 開啟 Serial port, 通訊速率為 9600 bps
irrecv.enableIRIn(); // 啟動紅外線解碼
}

void loop()
{
if (irrecv.decode(&results)) { // 解碼成功,收到一組紅外線訊號
if (results.value != -1) {
// 印到 Serial port
Serial.print("irCode: ");
Serial.print(results.value, HEX); // 紅外線編碼
Serial.print(", bits: ");
Serial.println(results.bits); // 紅外線編碼位元數
}

if (results.value == 0x4FB40BF) {
Serial.println("Sending IR...");
irsend.sendNEC(0x4FB48B7, 32);
}

irrecv.enableIRIn();
}
}

我是照網友小B 的需求「收到後發射」,這樣是可以 work 的。同時使用發射與接收,唯一的條件就是發射後要用 irrecv.enableIRIn() 重新打開接收功能。

你的程式邏輯看起來是正確的,看不出哪裏不對,晚上有空我來試試看。

Cooper Maa 提到...

Hi 小Y,我寫的程式如下:

#include // 引用 IRRemote 函式庫

const int irReceiverPin = 2; // 紅外線接收器 OUTPUT 訊號接在 pin 2
IRsend irsend; // 定義 IRsend 物件來發射紅外線訊號

IRrecv irrecv(irReceiverPin); // 定義 IRrecv 物件來接收紅外線訊號
decode_results results; // 解碼結果將放在 decode_results 結構的 result 變數裏

void setup()
{
Serial.begin(9600); // 開啟 Serial port, 通訊速率為 9600 bps
irrecv.enableIRIn(); // 啟動紅外線解碼
}

void loop()
{
// 檢查 Serial Port 是否有資料
// 有的話,Serial.read() 會回傳非 -1 的數值
if (Serial.read() != -1) {
Serial.println(0x4FB48B7, HEX);
delay(2000);
irsend.sendNEC(0x4FB48B7, 32); // 我電視 Power 鈕的紅外線編碼, 記得換成你的紅外線編碼
delay(2000);
irrecv.enableIRIn();
}

if (irrecv.decode(&results)) { // 解碼成功,收到一組紅外線訊號
if (results.value != -1) {
// 印到 Serial port
Serial.print("irCode: ");
Serial.print(results.value, HEX); // 紅外線編碼
Serial.print(", bits: ");
Serial.println(results.bits); // 紅外線編碼位元數
}

irrecv.resume();
}
}

可以動啊,程式運作很正常耶,當 Arduino 收到 Serial 訊號時會發射,而且也可以接收紅外線訊號。
你程式還是沒辦法 work 嗎?要不要確認一下幾個可能原因,例如發射和接收腳位正不正確、電阻值是否給太大等

小Y 提到...

原來改錯個libary了
感謝站長大大熱心幫忙
小弟感激不盡

Cooper Maa 提到...

原來是改錯 Library 了
找到原因就好,恭禧你,程式終於可以用了
請教一下,你為什麼會想要玩 Arduino?是工作/功課上或的需要嗎?還是跟我一樣純粹是玩票性質?

Unknown 提到...

親愛的大大:
想問一下?如果我是用L298N驅動控制兩個馬達?現在就是用家裡的遙控器去發射信號控制,四驅車的前後左右,可是為什麼解碼後如:2FF0877 碼.可是放在IF邏輯是會一直錯誤阿?請問一下要如何用紅外線接收器去接收已經解碼的遙控器,然後讓馬達前進後退阿?可以教我嗎.可以的話給我整套的code嗎.

Cooper Maa 提到...

「2FF0877 碼.可是放在IF邏輯是會一直錯誤阿」
這句話是指?

往前數四樓,就有一個可以用的 code,照著改一改應該就可以套用在你應用上。

Unknown 提到...

#include
const int irReceiverPin = 2; // 紅外線接收器 OUTPUT 訊號接在 pin 2
IRrecv irrecv(irReceiverPin); // 定義 IRrecv 物件來接收紅外線訊號
decode_results results;

// motor A
int dir1PinA = 13;
int dir2PinA = 12;
int speedPinA = 10;
// motor B
int dir1PinB = 11;
int dir2PinB = 8;
int speedPinB = 9;


unsigned long time;
int speed;
int dir;

void setup() {
pinMode(dir1PinA, OUTPUT);
pinMode(dir2PinA, OUTPUT);
pinMode(speedPinA, OUTPUT);
pinMode(dir1PinB, OUTPUT);
pinMode(dir2PinB, OUTPUT);
pinMode(speedPinB, OUTPUT);
Serial.begin(9600);
irrecv.enableIRIn();

time = millis();
speed = 0;
dir = 1;
}

void loop()
{
analogWrite(speedPinA, speed);
analogWrite(speedPinB, speed);
// set direction
if (irrecv.decode(&results)){
if (results.value != -1){
if (results.value == 0x2FF08F7) {
digitalWrite(dir1PinA, HIGH);
digitalWrite(dir2PinA, LOW);
} else {
digitalWrite(dir1PinA, LOW);
digitalWrite(dir2PinA, LOW);
}
if (results.value == 0x2FF30CF) {
digitalWrite(dir1PinA, LOW);
digitalWrite(dir2PinA, HIGH);
} else {
digitalWrite(dir1PinA, LOW);
digitalWrite(dir2PinA, LOW);
}
if (results.value == 0x2FF906F) {
digitalWrite(dir1PinB, HIGH);
digitalWrite(dir2PinB, LOW);
} else {
digitalWrite(dir1PinB, LOW);
digitalWrite(dir2PinB, LOW);
}
if (results.value == 0x2FF8877) {
digitalWrite(dir1PinB, LOW);
digitalWrite(dir2PinB, HIGH);
} else {
digitalWrite(dir1PinB, LOW);
digitalWrite(dir2PinB, LOW);
}

if (millis() - time > 5000) {
time = millis();
speed += 20;
if (speed > 255) {
speed = 0;
}
if (1 == dir) {
dir = 0;
} else {
dir =1;
}
}
}

問一下哪裡有錯阿!!一直編譯不過餒
底下一直顯示
MOTO_MOVE.cpp: In function 'void loop()':
MOTO_MOVE:82: error: expected `}' at end of input
MOTO_MOVE:82: error: expected `}' at end of input

Cooper Maa 提到...

"error: expected `}' at end of input"

這個錯誤訊息很好懂喔,它是在跟你說: "期望要有一個 '}'"
也就是說你程式少了右大括號 '}'
仔細檢查一下,看看左右大括號哪邊沒有 match.

amanda 提到...

請問用紅外線發射器發射訊號時可以同時接收紅外線訊號並且解碼嗎?
已經修改Library且加入irrecv.enableIRIn();

Cooper Maa 提到...

Hi amanda,

可以的,之前我有試過
可以同時發射並接收紅外線訊號

afrit320 提到...

請問一下 我接收到的紅外線訊號同一顆按鍵會有不同的編碼耶 甚至我按不同的按鍵卻跑出一樣的編碼
這是正常的嗎?

Cooper Maa 提到...

不正常
是只有同一支遙控器會這樣嗎?其它遙控器會不會有這個情形?

Unknown 提到...

請問跑程式完 結果出現
IRrecv dose not name a type
這要怎麼解決呢

Cooper Maa 提到...

可能是 IRRemote 跟 Arduino 版本不匹配的關係。

你 IRRemote Library 是裝哪個版本?
是這個? https://github.com/coopermaa/Arduino-IRremote (1)
還是這個? http://www.arcfn.com/2009/08/multi-protocol-infrared-remote-library.html (2)

(2) 的版本不相容於 Arduino 1.0 要修改程式碼才行,建議用 (1) 的版本。

afrit320 提到...

其他遙控器也一樣耶...難道是我的接收器有問題?

afrit320 提到...
作者已經移除這則留言。
Cooper Maa 提到...

可能要換一顆接收器試試看
BTW,你接收器是 38 kHz 的嗎?

Unknown 提到...

請問我測試紅外線接收器時,在serial monitor,不會顯示ircode,可是紅外線接收器的指示燈顯示有接收到是甚麼問題??

Cooper Maa 提到...

紅外線接收器的指示燈?
這篇並沒有控制指示燈啊,怎麼燈號會有反應?請問你是用這篇的程式還是?

Unknown 提到...

對 我用這篇的程式 但ircode沒有跑出來

專題生 提到...
作者已經移除這則留言。
Cooper Maa 提到...

@bryant kobe,
不確定你的 Serial 通訊正不正常,你可以跑一下底下的程式嗎? 試看看 Serial Monitor 會不會出現 "Hello World" 字串:

void setup() {
Serial.begin(9600);
Serial.println("Hello World");
}

void loop() {
}

Unknown 提到...

跑完程式之後,按遙控器就會出現Hello World嗎? 我測試之後沒出現 是什麼問題?

Cooper Maa 提到...

上面那支程式不用按遙控器,只要打開 Serial Monitor 就會出現 Hello World 了

程式跑了之後沒出現 Hello World 嗎?
有沒可能你程式並沒有上傳到 Arduino 板子上?

Unknown 提到...

問題已解決 非常感謝~~

Cooper Maa 提到...

恭禧!
後來有找到原因嗎?

Unknown 提到...

我想請問這電路圖是用什麼軟體所繪製而成的

Cooper Maa 提到...

我用 Fritzing 畫的,可參考這篇: Fritzing – PCB 印刷電路板的設計工具

Unknown 提到...
作者已經移除這則留言。
Unknown 提到...

你好
目前我正在寫一個程式
我希望可以用紅外線控制伺服馬達
我寫的程式如下:
#include // 引用 IRRemote 函式庫
#include
const int irReceiverPin = 2; // 紅外線接收器 OUTPUT 訊號接在 pin 2

IRrecv irrecv(irReceiverPin); // 定義 IRrecv 物件來接收紅外線訊號
decode_results results; // 解碼結果將放在 decode_results 結構的 result 變數裏
Servo myservo;
void setup()
{
myservo.write(0);
Serial.begin(9600); // 開啟 Serial port, 通訊速率為 9600 bps
irrecv.enableIRIn(); // 啟動紅外線解碼
myservo.attach(3);
// 啟動紅外線解碼
}

void loop()
{
myservo.write(0);
if (irrecv.decode(&results)) { // 解碼成功,收到一組紅外線訊號
// 印到 Serial port
Serial.print("irCode: ");
Serial.print(results.value, HEX); // 紅外線編碼
Serial.print(", bits: ");
Serial.println(results.bits);
// 紅外線編碼位元數
irrecv.resume(); // 繼續收下一組紅外線訊號
}
if (results.value == 0xFF02FD){ //收到訊號後,執行下列工作
delay(1500);
myservo.write(0);
delay(1500);
myservo.write(85);
delay(1500);
}
if (results.value == 0xFFE21D){//收到訊號後,執行下列工作
delay(1500);
myservo.write(0);
delay(1500);
myservo.write(45);
delay(1500);
}

}
我實際測試之後
我發現一些問題
1.紅外線編碼,不一定每次都一樣,常常會跑出很怪異的編碼
2.有時候會正確運作,有時後收到正確編碼後,馬達會不停重複轉動(照程式設定那樣轉)
是我哪裡程式有寫錯嗎?

Unknown 提到...

我上面貼的程式註解怪怪的
我重貼
#include // 引用 IRRemote 函式庫 #include const int irReceiverPin = 2; // 紅外線 接收器 OUTPUT 訊號接在 pin 2

IRrecv irrecv(irReceiverPin); // 定義 IRrecv 物件來接收紅外線訊號 decode_results results; // 解碼結果將 放在 decode_results 結構的 result 變 數裏 Servo myservo;
void setup() {
myservo.write(0); //讓伺服馬達轉到0度
Serial.begin(9600); // 開啟 Serial port, 通訊速率為 9600 bps
irrecv.enableIRIn(); // 啟動紅外線解碼 myservo.attach(3); // 伺服馬達接腳為3
}

void loop() {
myservo.write(0); //馬達轉到0度
if (irrecv.decode(&results)) { // 解碼成 功,收到一組紅外線訊號 // 印到 Serial port
Serial.print("irCode: ");
Serial.print(results.value, HEX); // 紅外 線編碼
Serial.print(", bits: ");
Serial.println(results.bits); // 紅外線編碼位元數
irrecv.resume(); // 繼續收下一組紅外 線訊號 }
if (results.value == 0xFF02FD){ //收到 訊號後,執行下列工作
delay(1500);
myservo.write(0); //馬達轉到0度
delay(1500);
myservo.write(85); 馬達轉到85度
delay(1500); }
if (results.value == 0xFFE21D){//收到 訊號後,執行下列工作
delay(1500);
myservo.write(0);
delay(1500);
myservo.write(45); 馬達轉到45度
delay(1500); }

}
這樣應該就沒問題了

Cooper Maa 提到...

謝謝你的分享啊 ^o^