// 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 #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; }