2011-12-21 53 views
0

我需要使用Arduino發送紅外信號來運行三星電視。在Arduino上發送紅外線

我嘗試下面的代碼:

// Lucas Eckels 
// Http://lucaseckels.com 

// IR remote control emitter for NEC protocol remote, as described at 
// Http://www.sbprojects.com/knowledge/ir/nec.htm 
// Tested on a Samsung LCD TV. 

#include <util/delay.h> 

#define IR_PIN 13 

// With CONTINOUS defined, the first command is repeated continuously until 
// You reset the Arduino. Otherwise, it sends the code once, then waits for 
// Another command. 
#define CONTINUOUS 

// Times are in microseconds 
#define ON_START_TIME 4500 
#define OFF_START_TIME 4500 
#define ON_TIME 580 
#define OFF_TIME_ONE 1670 
#define OFF_TIME_ZERO 540 

#define DEVICE_1 7 
#define DEVICE_2 7 

void setup() { 
    pinMode (IR_PIN, OUTPUT); 
    digitalWrite(IR_PIN, LOW); 
    Serial.begin(9600); 
    delay(1000); 
    Serial.write("Starting up..\n"); 
} 

byte command = 0; 
int commandCount = 0; 
bool commandReady = false; 

void loop() { 
    if (commandReady) { 
    Serial.print("Writing command"); 
    Serial.print(command, DEC); 
    Serial.print("\n"); 

    writeStart(); 
    // Writing device code 
    writeByte(DEVICE_1); 
    writeByte(DEVICE_2); 

    // Writing command code 
    writeByte(command); 
    writeByte(~command); 
    writeEnd(); 
    delay(100); 

#ifndef CONTINUOUS 
    commandReady = false; 
    command = 0; 
    commandCount = 0; 
#endif 
    return; 
    } 

    if (Serial.available() > 0) { 
    // Read in a 3-digit decimal command code. 
    byte incoming = Serial.read(); 
    if (incoming <= '9 ' || incoming >= '0') { 
     command *= 10; 
     command += incoming - '0 '; 
     ++commandCount; 
    } 
    if (commandCount == 3) { 
     commandReady = true; 
    } 
    } 
} 

void writeStart() { 
    modulate(ON_START_TIME); 
    delayMicroseconds(OFF_START_TIME); 
} 

void writeEnd() { 
    modulate(ON_TIME); 
} 

void writeByte(byte val) { 
    // Starting with the LSB, write out the 
    for (int i = 0x01; i & 0xFF; i <<= 1) { 
    modulate(ON_TIME); 
    if (val & i) { 
     delayMicroseconds (OFF_TIME_ONE); 
    } else { 
     delayMicroseconds (OFF_TIME_ZERO); 
    } 
    } 
} 

void modulate(int time) { 
    int count = time/26; 
    byte portb = PORTB; 
    byte portbHigh = portb | 0x20; // Pin 13 is controlled by 0x20 on PORTB. 
    byte portbLow = portb & ~0x20; 
    for (int i = 0; i <= count; i++) { 
    // The ideal version of this loop would be: 
    // DigitalWrite(IR_PIN, HIGH); 
    // DelayMicroseconds(13); 
    // DigitalWrite(IR_PIN, LOW); 
    // DelayMicroseconds(13); 
    // But I had a hard time getting the timing to work right. This approach was found 
    // Through experimentation. 
    PORTB = portbHigh; 
    _delay_loop_1(64); 
    PORTB = portbLow; 
    _delay_loop_1(64); 
    } 
    PORTB = portb; 
} 

代碼編譯,但不是爲我工作。

+1

「我+ +」看起來對我很可疑 - 也許「我++」會更好? – 2011-12-24 01:13:58

+0

您的代碼中有相當多的錯誤,所以我編輯並修復了它們,至少讓它能夠正確編譯。不是說我添加了任何可以使它按預期工作的任何東西。看到我的答案。 – fuzz 2012-02-17 05:09:26

回答

0

DelayMicroseconds相當準確,並且對於您的任務來說足夠精確。但是,您應該遠離DigitalWrite。與直接端口分配(PORTB = ...)相比,完成所需的時鐘週期大約需要50倍。你將只能以這種方式計時38MHz的脈衝。我不知道你的_delay_loop_1做了什麼,但其他一切似乎都沒問題。 (除了「我+ +」,但這是我猜'cut'n'paste錯字)

你檢查它實際上點亮了嗎?一部手機或便宜的數碼相機實際上會在屏幕上向您顯示紅外。

1

我寫這個來控制LG電視和索尼放大器。你只需要在自己的原始代碼保存在頭文件和您去:

Sensor tutorials - IR remote receiver/decoder tutorial

https://github.com/gotnull/SiriProxy-TV-Control/blob/master/arduino-remote/Remote/Remote.pde

// This procedure sends a 38KHz pulse to the IRledPin 
// for a certain # of microseconds. We'll use this whenever we need to send codes 
void pulseIR(long microsecs) { 
    // we'll count down from the number of microseconds we are told to wait 

    cli(); // this turns off any background interrupts 

    while (microsecs > 0) { 
    // 38 kHz is about 13 microseconds high and 13 microseconds low 
    digitalWrite(IRledPin, HIGH); // this takes about 3 microseconds to happen 
    delayMicroseconds(10); // hang out for 10 microseconds 
    digitalWrite(IRledPin, LOW); // this also takes about 3 microseconds 
    delayMicroseconds(10); // hang out for 10 microseconds 

    // so 26 microseconds altogether 
    microsecs -= 26; 
    } 

    sei(); // this turns them back on 
} 

我還建議採取通過Ladyada的精彩教程閱讀

+0

@orenberkovich有沒有幫助? – fuzz 2012-02-19 23:56:20

+0

修正了github的URL。 – fuzz 2013-01-31 00:14:59