2011-12-21 46 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