Hallo

Nichts zu danken, das ist doch ein spannendes Thema :)

Ich denke wir werden in den nächsten Tagen die Programme mal ausprobieren. Dann wrd ich mich nochmal eben melden, wie weit wir gekeommen sind.
Solange mag ich eigentlich nicht warten denn die Lösung ist quasi schon zum Greifen nahe. Wenn man das Timeing und die Trägerfrequenz im Griff hat ist der Rest eine Kleinigkeit:
Code:
// asuro als RC5-Fernbedienung                                      19.10.08 mic

// Das Bitmuster empfangener RC5-Signale wird zum Terminal gesendet und der Code
// anschliessend zusätzlich über die IR-LED ausgegeben.

// Zusätzlich kann das Programm mit den asuro-Tasten einen RP6
// über das TV-Remote-Demo fernsteuern :)

// Vermutlich funktioniert das auch mit der normalen asuro-Lib, allerdings muss
// man wegen des 36kHz-Timers der neueren Libs die Werte bei den Sleep()-Aufrufen
// halbieren! Die ISR am Ende wäre bei Verwendung der asuro-Lib auch überflüssig.

#include "fernbedienunglib.c"

unsigned int  rc5_daten;
unsigned char bit, taste;

void send_rc5(unsigned int bitmuster)
{
   // Aufbau der RC5-Daten:
	// Bitnummer: 1111110000000000
   //            5432109876543210
   // Funktion:  --sstaaaaacccccc
   //bitmuster=0b0011001001000001; // Adresse 9, Kommando 1
   //bitmuster=0b1111111111111111;

	UCSRB &= ~(1<<TXEN); // USART-Senden ausschalten! (ATMega8-Datenblatt S.140!)
	bit=14;
   while(bit--)
   {
		// Bit invertiert ausgeben
		if(bitmuster & (1<<bit)) PORTD |= (1<<PD1); else PORTD &= ~(1<<PD1);
		// zum debugen die FrontLED verwenden
		if(bitmuster & (1<<bit)) FrontLED(OFF); else FrontLED(ON);
		// halbe Bitlänge warten (1.Halbbit)
		Sleep(64);
		// jetzt Bit ausgeben
		if(bitmuster & (1<<bit)) PORTD &= ~(1<<PD1); else PORTD |= (1<<PD1);
		// zum debugen die FrontLED verwenden
		if(bitmuster & (1<<bit)) FrontLED(ON); else FrontLED(OFF);
		// nochmals halbe Bitlänge warten (2.Halbbit)
		Sleep(64);
   }
	UCSRB |= (1<<TXEN); // USART-Senden wieder einschalten
   FrontLED(OFF);
}
int main(void)
{
   Init(); // Auch diese kleine Lib muss initialisiert werden

   while(1)
   {
   	StatusLED(RED); // Wir sind nun Empfangsbereit
   	rc5_daten=0;
		bit=14;

   	while (PIND & (1 << PD0)) //warten auf die Flanke des Startbits
   	{
   	   taste=PollSwitch(); //  nebenher die Tasten abfragen
			if(taste && (taste == PollSwitch()))
			{
				// RC5-Kommandos für RP6-TV-Remote-Demo den Tasten zuordnen
				switch (taste) {
   	      case 1: send_rc5(0b0011001001000111); break; // Adr 9, Kommando 7
   	      case 2: send_rc5(0b0011001001000001); break; // Adr 9, Kommando 1
   	      case 4: send_rc5(0b0011001001001011); break; // Adr 9, Kommando 11
   	      case 8: send_rc5(0b0011001001001011); break; // Adr 9, Kommando 11
   	      case 16:send_rc5(0b0011001001000011); break; // Adr 9, Kommando 3
   	      case 32:send_rc5(0b0011001001001001); break; // Adr 9, Kommando 9
   	      }
   	      Sleep(100); // nach Senden kurz warten sonst empfangen wir uns selbst
			}
		}
		
   	StatusLED(YELLOW); // Alarmstufe ROT: ein Zeichen ist im Anflug
      Sleep(80); // Information einlesen nach ca. 3/4 der Bitlaenge
 		while(bit--) // 14 Bits RC5-Bits einlesen
		{
			// das MSB(=mostsuefikantbit) zuerst
			if(PIND & (1 << PD0)) rc5_daten |= (1 << (bit));
			   else rc5_daten &= ~(1 << (bit));
			Sleep(128); // auf nächstes Bit warten
		}

		// ??? Wo ist denn das erste Startbit geblieben ???
		// RC5-Bits an richtige Position schieben und erstes Startbit hinzufügen
		rc5_daten = rc5_daten/2 + (1<<13);
		
      StatusLED(GREEN); // warten
      Msleep(1000);
      StatusLED(RED); // Daten senden
      SerWrite("\n\r",2); // RC5-Schrott wegschieben
      PrintBin(rc5_daten); // erkannte Daten zum PC senden
      SerWrite("\n\r",2);

      StatusLED(GREEN); // warten
      Msleep(1000);
      StatusLED(RED); // Daten senden
      send_rc5(rc5_daten); // und zusätzlich RC5 senden

      StatusLED(GREEN); // RC5-Daten gesendet
      Msleep(500);
   }
   return(0);
}
/* uses timer2 (36kHz for IR communication */
/* bits falling and rising edge => 36kHz*2 = 72kHz */
SIGNAL (SIG_OUTPUT_COMPARE2)
{
   count72kHz ++;
}
Beim Einlesen eines RC5-Signals wird das erste Startbit irgendwie verschluckt und die restlichen Bits haben dadurch eine falsche Wertigkeit. Das war auch schon in der Version weiter oben so. Ich habe das nun manuell korrigiert weil ich die Ursache dafür noch nicht gefunden habe.

Sehr verwirrend ist die häufige Invertierung des Signals durch die Manchestercodierung und die Funktion des IR-Empfängers. Zusätzlich gibt es noch verschiedene Beschreibungen über die Pegelwechsel des Codes. Es funktioniert zwar, ich kann aber nicht sicher sagen warum.

Die Sende- und Empfangsfunktionen sind blockierend. Das reicht wohl für die ersten Versuche. Deutlich eleganter wäre natürlich eine Interruptlösung die das im Hintergrund erledigt.

Eine erste Anwendung mit meinem RP6. Der kann mit einem seiner mitgelieferten Demos auch RC5 verstehen:
Bild hier  
http://www.youtube.com/watch?v=9Hh1h6V5qRM

Das dürfte wohl die erste dokumentierte Kommunikation zwischen einem asuro und einem RP6 sein ;) Wer zwei asuros besitzt könnte mal testen ob die beiden miteinander Daten-PingPong spielen wenn beide das Programm geladen haben.

Gruß

mic

[Edit]
Da beim RC5 die Bitlängen schwanken können wäre es ein wissenschaftlicherer Ansatz beim Einlesen die Bitzeiten zu messen. Das macht nun dieses Programm:
Code:
// asuro als RC5-Fernbedienung                                      19.10.08 mic

// Messen der Bitlängen

#include "fernbedienunglib.c"

unsigned int  rc5_daten;
unsigned char bit, bitstring[28];
unsigned char bitlaengen[255] ;

int main(void)
{
   Init(); // Auch diese kleine Lib muss initialisiert werden
   Msleep(1000);
   FrontLED(OFF);

   while(1)
   {
   	rc5_daten=0;
		bit=0;

   	while(PIND & (1 << PD0)); //warten auf Startbit
      while((rc5_daten<100) && (count72kHz <= 200))
		{
			count72kHz=0;
   		if(PIND & (1 << PD0))
			{
				FrontLED(OFF);
				while((PIND & (1 << PD0)) && (count72kHz <= 200));
   		}
			else
			{
				FrontLED(ON);
				while(!(PIND & (1 << PD0)));
			}
      	bitlaengen[rc5_daten++]=count72kHz;
		}
      FrontLED(OFF);
      Msleep(500);

		StatusLED(YELLOW);
		SerWrite("\n\n\r_", 4);
		bitstring[0]='0';
 		rc5_daten=0;
		bit=1;
		while(bit<28)
		{
			if(bitlaengen[rc5_daten] < 96) SerWrite("-", 1); else SerWrite("--", 2);
			if(bitlaengen[rc5_daten+1] < 96) SerWrite("_", 1); else SerWrite("__", 2);
			Sleep(100);
			if(bitlaengen[rc5_daten] < 96) bitstring[bit++]='1';
				else { bitstring[bit++]='1'; bitstring[bit++]='1'; }
			if(bitlaengen[rc5_daten+1] < 96) bitstring[bit++]='0';
				else { bitstring[bit++]='0'; bitstring[bit++]='0'; }
			rc5_daten +=2;
		}
		rc5_daten=0;
		bit=14;
		while(bit--) if(bitstring[27-bit*2] == '1') rc5_daten |= (1<<bit);

		SerWrite("\n\n\r", 3);
		SerWrite(bitstring, 28);
		SerWrite("\n\n\r", 3);
		PrintBin(rc5_daten);
		SerWrite("\n\r--sstaaaaacccccc\n\r", 20);

		SerWrite("\n\n\r", 3);
		bit=0;
		do
		{
			PrintChar(bitlaengen[bit++]);
			SerWrite(" ", 1);
		}while((bitlaengen[bit] < 200) && bitlaengen[bit]);
		SerWrite("\n\r", 2);
   }
   return(0);
}
/* uses timer2 (36kHz for IR communication */
/* bits falling and rising edge => 36kHz*2 = 72kHz */
SIGNAL (SIG_OUTPUT_COMPARE2)
{
   count72kHz ++;
}
Die Ausgabe der Tasten 1-3 an Adresse 8:
Code:
þþþ

_-_--_-__--_-_-_-_-_-_-_-__-__

0101101001101010101010101001

0011001000000001
--sstaaaaacccccc


00069 00057 00135 00059 00067 00122 00133 00059 00066 00059 00067 00061 00067 00
061 00070 00056 00068 00059 00068 00060 00067 00123 00066
3ø3ø3ø

_-_-_--__--_-_-_-_-_-_-__--__

0101011001101010101010100110

0011101000000010
--sstaaaaacccccc


00078 00050 00073 00055 00136 00120 00134 00059 00070 00056 00070 00058 00069 00
058 00069 00058 00069 00058 00068 00122 00133
cÆãÆcÆãÆcÆãÆ

_-_--_-__--_-_-_-_-_-_-__-_-__

0101101001101010101010100101

0011001000000011
--sstaaaaacccccc


00070 00057 00134 00059 00068 00123 00131 00061 00068 00059 00068 00060 00068 00
058 00069 00060 00066 00060 00067 00123 00069 00059 00067
Man sieht den RC5-Schrott, das Signal grafisch und als Bitmuster, dann folgen die übertragenen RC5-Daten und ihre Bedeutung (s=Startbits, t=Togglebit, a=Adresse und c=Kommando). Anschliessend folgen die Werte der gemessenen Bitlängen. Laut RC5-Doku sollte ein ganzes Bit ca. 128 sein. Gemessen wird mit count72kHz das in der alten ISR freundlicherweise erhöht wird;)