NEC IR protocol

There was surprisingly little interest in this topic but I will at least share the code I have now that I have finally gotten it to work. As far as I can see, the NEC-protocol works roughly as follows:

preamble:
8000us carrier ON
4000us OFF

device code:
8 bit code
8 bit code inverted (1 becomes 0, 0 becomes 1)

command code:
8 bit code
8 bit code inverted (1 becomes 0, 0 becomes 1)

560us carrier ON

For the data part, a 0 is transmitted as:
560us carrier ON
565us OFF

...and a 1 is transmitted as
560us carrier ON
1690us OFF

Here comes the code:

int irPin = 13;
int data[32];
int val;
int timeout = 0;

void setup()
{
  pinMode(irPin, OUTPUT);
  Serial.begin(115200);
  Serial.println("System ready!");
}

void loop()
{

  if(Serial.available())
  {
    //get and decode first byte
    val = Serial.read();
    Serial.print("Byte1: ");
    Serial.println(val);
    makedata(val, 0);
    
    //get and decode second byte
    timeout = millis();
    while(!Serial.available() && millis() < timeout + 100) {}
    if(Serial.available())
    {
      val = Serial.read();
      Serial.print("Byte2: ");
      Serial.println(val);
      makedata(val, 16);
    }
    
    //send preamble
    oscWrite(irPin, 8000);
    delayMicroseconds(4000);

    //send data
    for(int i = 0; i < 32; i++)
    {
      //space
      oscWrite(irPin, 560);
      
      //data
      if(data[i] == '0')
      {
        delayMicroseconds(565);
        Serial.print('0');
      }
      else
      {
        delayMicroseconds(1690);
        Serial.print('1');
      }
    }
    Serial.println();
    oscWrite(irPin, 560);
  }
  
}

void oscWrite(int pin, int time)
{
  for(int i = 0; i < (time / 26) - 1; i++)
  {
    digitalWrite(pin, HIGH);
    delayMicroseconds(13);
    digitalWrite(pin, LOW);
    delayMicroseconds(13);
  }
}

void makedata(double foo, int ofs)
{
  for(int i = 0; i < 8; i++)
  {
    data[i + ofs] = '0';
    data[i + ofs + 8] = '0';
    if(foo / 2 > floor(foo / 2))
    {
      data[i + ofs] = '1';
    }
    else
    {
      data[i + ofs + 8] = '1';
    }
    foo = floor(foo / 2);
  }
}

And here is a small list of the 256 possible device codes (the numbers are ASCII-codes):

56 = device code for our TV

0-9 = channel 0-9
10 = -- (2 digit channel)
12 = channel up
13 = channel down

17 = "normal" (set volume low)

20 = TV/AV
21 = mute
22 = volume up
23 = volume down
24 = OK
25 = menu (says "sleep", don't know what this is)
26 = menu - color

28 = power
29 = last channel (P<->P)
64 = mono/stereo
66 = menu - color
69 = on-screen clock
70 = text tv
75 = sound bass?
76 = on-screen clock
85 = sound bass?
125 = volum max?! RETARDEEEED!
128 = volum max?! RETARDEEEED!

I haven't gotten further than 128. It was getting late last night and when I stumbled onto those two codes that set the volume to max I decided to stop for the time beeing before my girlfriend decided to take a roller to the back of my head or something. -__-'

Anyways, I'm waiting for my internet hookup and my brand new HTC S730 phone. With this, I will make a smooth interface to control the arduino (and thus the TV, DVD-player, a couple of LED-bars and who knows what else). I can hardly wait! =D