Hallo,

ich habe mir an den Stecker X5 einen SFH5110 IR-Empfänger angeschlossen und mit einer RC5-Fernbedienung etwas herumgespielt.
Was dabei herausgekommen ist, ist folgendes Programm, mit dem man die Nibobee fernsteuern kann.

Code:
/*********************************************
 ***  RC5 Dekoder
 ***  Version 1
 ***
 *** Nibobee wird mit IR-Fernbedienung ferngesteuert.
 ***
 *** PD0=RxD verbunden mit Ausgang IR-Empfänger SFH5110 
 ***
 *** 36kHz (27,7 usek) werden mit Timer2 erzeugt.
 *** Der Eingang PD0 wird alle 8 * 27,7 = 222 usek
 *** abgefragt.
 ***
 *** LED0 (linke gelbe) = Betrieb
 *** LED1 (linke rote)  = blinkt bei RC5 Empfang
 ***
 *** Author : H. Krause  2010 
 **********************************************/
#include <nibobee/iodefs.h> 
#include <nibobee/delay.h> 
#include <nibobee/led.h> 
#include <nibobee/usart.h>
#include <nibobee/sens.h>
#include <nibobee/motpwm.h>

#include <stdlib.h> 


volatile uint8_t count36kHz; 


//IR-Fernbedienung PhilipsII 
//diese Werte können an die Fernbedienung 
//angepasst werden
#define IRPIVor     0x1020 //Vorwärts
#define IRPIRueck   0x1021 //Rückwärts
#define IRPIPlus    0x1010 //schneller
#define IRPIMinus   0x1011 //langsamer
#define IRPIStop    0x1036 //stop
#define IRPIKr      0x1034 //Kurve rechts
#define IRPIKl      0x1032 //Kurve links
#define IRPIPlay    0x1035 //frei


/*********************************************
 ***   Unterprogramme
 *********************************************/

void SerPrint (char *data)
{
  unsigned char i = 0;

  while (data[i] != 0x00)
  {
    usart_putchar(data[i++]);
	delay(3);
  }
}


/***** RC5 ******** RC5 ********* RC5 ******************/

// -----------------------------------------------------------------------------
// Timing
// -----------------------------------------------------------------------------
#define IR_SAMPLES_PER_BIT     8   /*!< 8 Samples per Bit */
#define IR_SAMPLES_PER_BIT_EARLY 7  /*!< Flanke fruehestens nach 7 Samples */
#define IR_SAMPLES_PER_BIT_LATE 10  /*!< Flanke spaetestens nach 9 Samples */
#define IR_SAMPLES_PER_BIT_MIN   2  /*!< Flanke vor 3 Samples -> paket verwerfen */
#define IR_PAUSE_SAMPLES       250  /*!< Startbit ist erst nach 200 Samples ohne */
// Pegelaenderung gueltig -- eigentlich muesste
// man rund 500 Samples abwarten (50 x
// Bitzeit), doch weil der Samplezaehler ein
// Byte ist, beschraenken wir uns hier auf ein
// Minimum von 250 Samples

#define IR_PORT   PORTD     /*!< Port D */
#define IR_DDR    DDRD      /*!< DDR of Port D */
#define IR_PINR   PIND      /*!< Port D input */
#define IR_PIN    PD0       /*!< Pin 0 */

#define RC5_COMMAND 0x103F    /*!< Der Kommandobereich */
#define RC5_MASK (RC5_COMMAND)

static uint8_t     RC5lastsample = 0;  /*!< zuletzt gelesenes Sample */
static uint8_t     RC5bittimer   = 0;  /*!< zaehlt die Aufrufe von ir_isr() */

static uint16_t    RC5data_tmp = 0;    /*!< RC5-Bitstream */
static uint8_t     RC5bitcount = 0;    /*!< anzahl gelesener bits */

volatile uint16_t  RC5data = 0;        /*!< letztes komplett gelesenes RC5-paket */
volatile uint8_t   enableRC5 = 0;      /*!< schaltet die RC5 Abfrage ein/aus */



/**********************************
 * Interrupt Serviceroutine
 * wird alle 27.7us aufgerufen
 **********************************/
void IsrRC5 (void)
{
  // sample lesen
  uint8_t sample = 1;

  //PORTB ^= (1<<PB1); //PB1=LED1 toggeln (Test)

  if (enableRC5 && !(count36kHz % 8)) 
  {  
    if ((IR_PINR & (1<<IR_PIN)) != 0)
    {
      sample = 0;
    }

    // bittimer erhoehen (bleibt bei 255 stehen)
    if (RC5bittimer<255)
    {
      RC5bittimer++;
    }

    // flankenerkennung
    if ( RC5lastsample != sample)
    {
      if (RC5bittimer <= IR_SAMPLES_PER_BIT_MIN)
      {
        // flanke kommt zu frueh: paket verwerfen
        RC5bitcount=0;
      }
      else
      {
        // Startbit
        if (RC5bitcount==0)
        {
          if ( (sample==1) && (RC5bittimer > IR_PAUSE_SAMPLES) )
          {
            // Startbit speichern
            RC5data_tmp = 1;
            RC5bitcount++;
            led_set(1,1); //LED1 an
          }
          else
          {
            // error
            RC5data_tmp = 0;
          }

          // bittimer-reset
          RC5bittimer = 0;

        // Bits 2..14: nur Flanken innerhalb des Bits beruecksichtigen
        }
        else
        {
          if (RC5bittimer >= IR_SAMPLES_PER_BIT_EARLY)
          {
            if (RC5bittimer <= IR_SAMPLES_PER_BIT_LATE)
            {
              // Bit speichern
              RC5data_tmp = (RC5data_tmp<<1) | sample;
              RC5bitcount++;
            }
            else
            {
              // zu spaet: paket verwerfen
              RC5bitcount = 0;
            }
            // bittimer-reset
            RC5bittimer = 0;
          }
        }
      }

    }
    else
    {
      // keine flanke innerhalb bitzeit?
      if (RC5bittimer > IR_SAMPLES_PER_BIT_LATE)
      {
        // 14 bits gelesen?
        if (RC5bitcount==14)
        {
          RC5data = RC5data_tmp;
        }
        // paket verwerfen
        RC5bitcount = 0;
        led_set(1,0); //LED1 aus
      }
    }

    // sample im samplepuffer ablegen
    RC5lastsample = sample;
  }
}

/*********************************************************
 * IR-Daten lesen
 * @return wert von ir_data, loescht anschliessend ir_data
 *********************************************************/
uint16_t ReadRC5 (void)
{
  uint16_t retvalue = RC5data;
  RC5data = 0;
  return retvalue;
}

/*****************************************
 * Init IR-System
 *****************************************/
void InitRC5 (void)
{
  IR_DDR  &= ~IR_PIN;   // Pin auf Input
  IR_PORT |= IR_PIN;    // Pullup an
  enableRC5 = 1;
}

/************************ RC5 Ende **************************/


/*********************************************
 ***   Interrupt Service Routinen
 *********************************************/

ISR (TIMER2_COMP_vect) 
{ 
   //wird nicht benutzt 
} 

// Frequenzkorrektur für 36kHz (512-416 plus 3 Takte fürs Laden von TCNT2?) 
ISR (TIMER2_OVF_vect) 
{ 
   TCNT2 = 99; 
   count36kHz ++;
   IsrRC5();      //RC5 Decoder aufrufen
} 


/*********************************************
 ***   Hauptprogramm
 *********************************************/
int main(void) 
{ 
  static unsigned int cmd;
  int16_t speed_l = 0;
  int16_t speed_r = 0;
  //Test
  //char text[7];

  motpwm_init();
  led_init(); 
  sens_init();
  InitRC5();

  //usart_enable();
  //UCSRB = _BV(RXCIE) + _BV(UDRIE) + _BV(RXEN) + _BV(TXEN);
  UCSRB = _BV(TXEN); //Nur Sender TxD aktivieren
  usart_setbaudrate(2400);

  // Setup Timer2 
  TCCR2 = (1 << WGM20)|(1 << CS20); // PhaseCorrect-PWM, no prescaling, no OC2-Pin! 
  TCNT2  = 96; // (512-416) 36kHz @15MHz 
  //OCR2 = 151; // (255-(208/2)) 151 ist 50:50 Compare Match für symetrische Halbwellen 
  //TIMSK |= (1 << OCIE2)|(1 << TOIE2); // Comp und OVF-ISR enable, Overflow bei Bottom! 
  TIMSK |= (1 << TOIE2); // OVF-ISR enable, Overflow bei Bottom! 

  enable_interrupts(); 

  //Test
  //delay(200);  // wait4programmer 
  //SerPrint("\n\r\n*** Nibobee mit RC5 ***");

  led_set(0,1); 
  delay(2000); // wait4programmer 

  //Test
  //SerPrint("\n\r*** Fuehler links schalten --> Start ***");

  //mit Schalten von Fühler links das Programm starten
  while(sens_getLeft() == 0) 
  {
     delay(100); 
     PORTB ^= (1<<PB0);
  } // hektisches Blinken mit LED0
   
  led_set(0,1); //LED0 einschalten

  //Test
  //SerPrint("\n\r***  --> Start ***");

  while(1) 
  { 
     cmd = ReadRC5();

     if (cmd)
     {
        cmd &= RC5_MASK;

		//Test
        //led_set(2,1); 
        //itoa(cmd, text, 16);
        //SerPrint(text);


        switch (cmd)
        {
             case IRPIVor:
 		            //Test
                    //SerPrint("vor\r\n");
					speed_l = speed_r = 200;
                    break;
             case IRPIRueck:
 		            //Test
                    //SerPrint("zurueck\r\n");
					speed_l = speed_r = -200;
                    break;
             case IRPIPlus:
 		            //Test
                    //SerPrint("schneller\r\n");
					if (speed_r > 0)
					{
                       speed_l += 50;
                       speed_r += 50;
 					   if (speed_r > 1023)
					      speed_l = speed_r = 1023;
                   }
                    else
					{
                       speed_l -= 50;
                       speed_r -= 50;
 					   if (speed_r < -1023)
					      speed_l = speed_r = -1023;
                    }
                    break;
             case IRPIMinus:
 		            //Test
                    //SerPrint("langsamer\r\n");
					if (speed_r > 0)
					{
                       speed_l -= 50;
                       speed_r -= 50;
 					   if (speed_r < 0)
					      speed_l = speed_r = 0;
                    }
                    else
					{
                       speed_l += 50;
                       speed_r += 50;
 					   if (speed_r > 0)
					      speed_l = speed_r = 0;
                    }
                    break;
             case IRPIStop:
 		            //Test
                    //SerPrint("stop\r\n");
					speed_l = speed_r = 0;
                    break;
             case IRPIKr:
 		            //Test
                    //SerPrint("Kurve rechts\r\n");
					if (speed_r > 0)
					{
                       speed_l += 50;
                       speed_r -= 50;
 					   if (speed_r < 0)
					      speed_l = speed_r = 0;
                    }
                    else
					{
                       speed_l -= 50;
                       speed_r += 50;
 					   if (speed_r > 0)
					      speed_l = speed_r = 0;
                    }
                    break;
             case IRPIKl:
 		            //Test
                    //SerPrint("Kurve links\r\n");
					if (speed_r > 0)
					{
                       speed_l -= 50;
                       speed_r += 50;
 					   if (speed_r < 0)
					      speed_l = speed_r = 0;
                    }
                    else
					{
                       speed_l += 50;
                       speed_r -= 50;
 					   if (speed_r > 0)
					      speed_l = speed_r = 0;
                    }
                    break;
             case IRPIPlay:
 		            //Test
                    //SerPrint("play taste\r\n");
                    break;
        }//end switch

        motpwm_setLeft(speed_l);
        motpwm_setRight(speed_r);
     }//end if (cmd)

     delay(100); 

  } 
  return(0); 
}
Viel Spass beim Ausprobieren.
Skroete