- LiFePO4 Speicher Test         
Ergebnis 1 bis 6 von 6

Thema: Asuro als Fernbedienung

  1. #1

    Asuro als Fernbedienung

    Anzeige

    LiFePo4 Akku selber bauen - Video
    Hallo erstmal!
    aslo ich bzw meine Gruppe in der Schule haben eine Frage.

    Erst mal kurz zu Erklärung, wir haben das Projekt Kommunikation, welches wir vorstellen sollen und dazu drei Unterbereiche (Asuro-Asuro, Asuro-PC & Asuro Fernbedienung) soweit klappt alles.
    Jetzt haben wir uns oder in diesem Fall viel mehr ich mir ausgedacht, dass es doch interessant wäre den asuro mal im rc5 code senden zu lassen. könnte uns dabei vielleicht einer von euch helfen? Da ich echt nicht die große Programmierin bin, würde auch einfach nur ein Programmteil, mit dem eine 1 gesendet wird ohne Erklärungen reichen. (Über leicht verständliche Erklärungen würde ich mich aber trotzdem natürlich freuen!)

    Danke schon mal & liebe Grüße
    Saskia
    Projekt Kommunikation

  2. #2
    Moderator Robotik Visionär Avatar von radbruch
    Registriert seit
    27.12.2006
    Ort
    Stuttgart
    Alter
    61
    Beiträge
    5.799
    Blog-Einträge
    8
    Hallo

    RC5 zu senden ist schon etwas anspruchsvoll. Man benötigt die Trägerfrequenz des Signals, in der Regel 36kHz(=72kHz-Takt!), die man üblicherweise mit einem Timerinterrupt erzeugt. Mit dieser Frequenz schaltet man einen Ausgang (asuro: PB3, OC2) an dem eine Seite einer (IR-)LED (asuro: D10) angeschlossen wird. Das andere Ende der LED wird mit passenendem Vorwiderstand (asuro: R16, 220R) an den Pin (asuro: PD1,TXD) angeschlossen an dem man das Bitmuster ausgeben möchte. So kann man der Trägerfrequenz ein Signal aufmodulieren.

    Nun zum Bitmuster. Das RC5-Signal ist wird mit der Manchester-Codierung (anklicken!) gesendet. Ein Wechsel von low nach high bedeutet '1', von high nach low bedeutet '0'. Die Bitlänge ist ein Bruchteil der 36kHz-Trägerfrequenz (es war ein 64stel soweit ich mich erinnern kann).

    Mein Lösungsansatz (ich hatte das mal in Bascom programmiert) ist folgender:
    Ein 72kHz-Timer im CTC-Mode toggelt einen OCR-Pin und erzeugt so die 36kHz-Trägerfrequenz. Gleichzeitig ruft dieser Timer eine ISR auf in der die zwei Manchester-Halbbits erzeugt werden. Das erste Halbbit ist quasi das Gegenteil des eigentlichen Datenbits und wird für 64 ISR-Aufrufe am Sendepin ausgegeben. Nun folgt der entscheidende Pegelwechsel und der (eigentliche) Pegel des Datenbits wird am Datenpin für weitere 64 ISR-Zyklen ausgegeben. Das Ganze wird mit allen 14 RC5-Datenbits wiederholt. Das wars. (Wie man die 14 RC5-Datenbits zusammensetzt ist noch offen).

    Das Setup des Timers kann man z.B. aus der Datei asuro.c der orginalen CD-Version entnehmen. In dieser Version der Library wird noch ein 72kHz-Timer zur Erzeugung der Trägerfrequenz für die IR-Kommunikation verwendet. Hier könnte man vermutlich relativ einfach einen RC5-Sender aufsetzen.

    Gruß

    mic
    Bild hier  
    Atmel’s products are not intended, authorized, or warranted for use
    as components in applications intended to support or sustain life!

  3. #3
    Moderator Robotik Visionär Avatar von radbruch
    Registriert seit
    27.12.2006
    Ort
    Stuttgart
    Alter
    61
    Beiträge
    5.799
    Blog-Einträge
    8
    Nochmal hallo

    Weil mich das Thema "asuro als Fernbedienung" selbst auch sehr interessiert habe ich mal eine Art Grundgerüst gebastelt:
    Code:
    #include <avr/io.h>
    #include <avr/interrupt.h>
    
    #define  OFF    0
    #define  ON     1
    
    volatile unsigned char count72kHz;
    
    /* uses 72kHz timer => Sleep(x) = x/72kHz [sec] */
    void Sleep(unsigned char time72kHz)
    {
       count72kHz = 0;
       while (count72kHz < time72kHz);
    }
    /* function to read out switches */
    unsigned char PollSwitch (void)
    {
       unsigned int i;
    
       DDRD |= (1 << PD3);            // Switches as Output
       PORTD |= (1 << PD3);                  // Output HIGH for measurement
       ADMUX = (1 << REFS0) | (1 << MUX2);   // AVCC reference with external capacitor
       Sleep(10);
    
       ADCSRA |= (1 << ADSC);         // Start conversion
       while (!(ADCSRA & (1 << ADIF)));// wait for conversion complete
       ADCSRA |= (1 << ADIF);         // clear ADCIF
       i = ADCL + (ADCH << 8);
    
       PORTD &= (1 << PD3);
    
       //return  ((unsigned char) ((( 1024.0/(float)i - 1.0)) * 63.0 + 0.5));
       return ((10240000L/(long)i-10000L)*63L+5000L)/10000;
    }
    /* function for serial communication */
    void SerWrite(unsigned char *data,unsigned char length)
    {
       unsigned char i = 0;
       UCSRB = 0x08; // enable transmitter
       while (length > 0) {
          if (UCSRA & 0x20) { // wait for empty transmit buffer
             UDR = data[i++];
             length --;
          }
       }
       while (!(UCSRA & 0x40));
       for (i = 0; i < 0xFE; i++)
          for(length = 0; length < 0xFE; length++);
    }
    // aus: https://www.roboternetz.de/phpBB2/ze...=328394#328394
    void PrintChar(unsigned int x)
    {
       char ergebnis[5]  = {'0','0','0','0','0'};
       while (x >=10000) { ergebnis[0]++; x -=10000; }
       while (x >= 1000) { ergebnis[1]++; x -= 1000; }
       while (x >=  100) { ergebnis[2]++; x -=  100; }
       while (x >=   10) { ergebnis[3]++; x -=   10; }
       ergebnis[4] +=x;
       SerWrite(ergebnis,5);
    }
    /* Front LED */
    inline void FrontLED(unsigned char status)
    {
       PORTD = (PORTD &~(1 << PD6)) | (status << PD6);
    }
    /* Status LED (OFF,GREEN,YELLOW,RED)*/
    inline void StatusLED(unsigned char color)
    {
    #define GREEN   1
    #define RED      2
    #define YELLOW  3
    #define GREEN_LED   (1 << PB0)
    #define RED_LED     (1 << PD2)
    #define GREEN_LED_ON  PORTB |=  GREEN_LED
    #define GREEN_LED_OFF PORTB &= ~GREEN_LED
    #define RED_LED_ON    PORTD |=  RED_LED
    #define RED_LED_OFF   PORTD &= ~RED_LED
       if (color == OFF)    {GREEN_LED_OFF; RED_LED_OFF;}
       if (color == GREEN)  {GREEN_LED_ON; RED_LED_OFF;}
       if (color == YELLOW) {GREEN_LED_ON; RED_LED_ON;}
       if (color == RED)    {GREEN_LED_OFF; RED_LED_ON;}
    }
    void Msleep(int dauer)
    {
       int z;
       for(z=0;z<dauer;z++) Sleep(72);
    }
    int main(void)
    {
       //-------- seriell interface programmed in boot routine and already running -------
       //  prepare 36kHz for IR - Communication
       TCCR2 = (1 << WGM21) | (1 << COM20) | (1 << CS20);
       OCR2  = 0x6E; // 36kHz @8MHz
       TIMSK |= (1 << OCIE2); // 36kHz counter for sleep
    
       // prepare RS232
       UCSRA = 0x00;
       UCSRB = 0x00;
       UCSRC = 0x86; // No Parity | 1 Stop Bit | 8 Data Bit
       UBRRL = 0xCF; // 2400bps @ 8.00MHz
    
       // I/O Ports
       DDRB = (1<<PB3) | (1<<PB0); // OC2 und GreenLED auf Ausgang
       DDRD = (1<<PD6) | (1<<PD2) | (1<<PD1); // FrontLED, RedLED und TXD auf Ausgang
    
       sei();
       FrontLED(ON);
    
       while(1)
       {
          StatusLED(RED);
          SerWrite("Hallo\r\n", 7);
          PrintChar(12345);
          SerWrite("\n\r", 2);
          PrintChar(PollSwitch());
          SerWrite("\n\n\r", 3);
          StatusLED(YELLOW);
          Msleep(500);
       }
       return(0);
    }
    /* uses timer2 (36kHz for IR communication */
    /* counts falling and rising edge => 36kHz*2 = 72kHz */
    SIGNAL (SIG_OUTPUT_COMPARE2)
    {
       count72kHz ++;
    }
    In diesem 803Bytes (14 Pages) großen Programm habe ich die wichtigsten Funktionen aus der asuro-Library zusammenkopiert:

    72kHz-Timer mit OCR
    USART
    Tasten
    einige LEDs

    Jetzt fehlt nur noch der RC5-Teil in der ISR. Das kann ja nimmer schwer sein. Beteiligung anderer asuro-Spezialisten erwünscht :)

    Gruß

    mic
    Bild hier  
    Atmel’s products are not intended, authorized, or warranted for use
    as components in applications intended to support or sustain life!

  4. #4
    Moderator Robotik Visionär Avatar von radbruch
    Registriert seit
    27.12.2006
    Ort
    Stuttgart
    Alter
    61
    Beiträge
    5.799
    Blog-Einträge
    8
    Hallo

    Zur besseren Übersicht habe ich eine Library erstellt und ein kleines Demo dazu geschrieben. Ohne Verwendung der asuro-Lib kann das kleine Programm z.B. die Tasterwerte einlesen und in binärer Darstellung an das Terminal senden:
    Code:
    #include "fernbedienunglib.c"
    
    int main(void)
    {
    	Init();
    	FrontLED(ON);
    
       while(1)
       {
          StatusLED(RED);
          SerWrite("Hallo\r\n", 7);
          PrintChar(12345);
          SerWrite("\n\r", 2);
          PrintBin(PollSwitch());
          SerWrite("\n\n\r", 3);
          StatusLED(YELLOW);
          Msleep(500);
       }
       return(0);
    }
    /* uses timer2 (36kHz for IR communication */
    /* counts falling and rising edge => 36kHz*2 = 72kHz */
    SIGNAL (SIG_OUTPUT_COMPARE2)
    {
       count72kHz ++;
    }
    Dazu passt dann diese Library die man als "fernbedienlib.c" speichern sollte:
    Code:
    #include <avr/io.h>
    #include <avr/interrupt.h>
    
    #define  OFF    0
    #define  ON     1
    
    volatile unsigned char count72kHz;
    
    /* uses 72kHz timer => Sleep(x) = x/72kHz [sec] */
    void Sleep(unsigned char time72kHz)
    {
       count72kHz = 0;
       while (count72kHz < time72kHz);
    }
    /* function to read out switches */
    unsigned char PollSwitch (void)
    {
       unsigned int i;
    
       DDRD |= (1 << PD3);            // Switches as Output
       PORTD |= (1 << PD3);                  // Output HIGH for measurement
       ADMUX = (1 << REFS0) | (1 << MUX2);   // AVCC reference with external capacitor
       Sleep(10);
    
       ADCSRA |= (1 << ADSC);         // Start conversion
       while (!(ADCSRA & (1 << ADIF)));// wait for conversion complete
       ADCSRA |= (1 << ADIF);         // clear ADCIF
       i = ADCL + (ADCH << 8);
    
       PORTD &= (1 << PD3);
    
       //return  ((unsigned char) ((( 1024.0/(float)i - 1.0)) * 63.0 + 0.5));
       return ((10240000L/(long)i-10000L)*63L+5000L)/10000;
    }
    /* function for serial communication */
    void SerWrite(unsigned char *data,unsigned char length)
    {
       unsigned char i = 0;
       UCSRB = 0x08; // enable transmitter
       while (length > 0) {
          if (UCSRA & 0x20) { // wait for empty transmit buffer
             UDR = data[i++];
             length --;
          }
       }
       while (!(UCSRA & 0x40));
       for (i = 0; i < 0xFE; i++)
          for(length = 0; length < 0xFE; length++);
    }
    // aus: https://www.roboternetz.de/phpBB2/ze...=328394#328394
    void PrintChar(unsigned int x)
    {
       char ergebnis[5]  = {'0','0','0','0','0'};
       while (x >=10000) { ergebnis[0]++; x -=10000; }
       while (x >= 1000) { ergebnis[1]++; x -= 1000; }
       while (x >=  100) { ergebnis[2]++; x -=  100; }
       while (x >=   10) { ergebnis[3]++; x -=   10; }
       ergebnis[4] +=x;
       SerWrite(ergebnis,5);
    }
    void PrintBin(unsigned int x)
    {
    	char bit=16;
    	char ergebnis[16];;
    	while(bit--)
    	{
       	ergebnis[15-bit]=0;
    		while (x >= (1<<bit)) { ergebnis[15-bit]++; x -= (1<<bit); }
       	ergebnis[15-bit] +='0';
    	}
    	SerWrite(ergebnis, 16);
    }
    /* Front LED */
    inline void FrontLED(unsigned char status)
    {
       PORTD = (PORTD &~(1 << PD6)) | (status << PD6);
    }
    /* Status LED (OFF,GREEN,YELLOW,RED)*/
    inline void StatusLED(unsigned char color)
    {
    #define GREEN   1
    #define RED      2
    #define YELLOW  3
    #define GREEN_LED   (1 << PB0)
    #define RED_LED     (1 << PD2)
    #define GREEN_LED_ON  PORTB |=  GREEN_LED
    #define GREEN_LED_OFF PORTB &= ~GREEN_LED
    #define RED_LED_ON    PORTD |=  RED_LED
    #define RED_LED_OFF   PORTD &= ~RED_LED
       if (color == OFF)    {GREEN_LED_OFF; RED_LED_OFF;}
       if (color == GREEN)  {GREEN_LED_ON; RED_LED_OFF;}
       if (color == YELLOW) {GREEN_LED_ON; RED_LED_ON;}
       if (color == RED)    {GREEN_LED_OFF; RED_LED_ON;}
    }
    void Msleep(int dauer)
    {
       int z;
       for(z=0;z<dauer;z++) Sleep(72);
    }
    void Init(void)
    {
       //-------- seriell interface programmed in boot routine and already running -------
       //  prepare 36kHz for IR - Communication
       TCCR2 = (1 << WGM21) | (1 << COM20) | (1 << CS20);
       OCR2  = 0x6E; // 36kHz @8MHz
       TIMSK |= (1 << OCIE2); // 36kHz counter for sleep
    
       // prepare RS232
       UCSRA = 0x00;
       UCSRB = 0x00;
       UCSRC = 0x86; // No Parity | 1 Stop Bit | 8 Data Bit
       UBRRL = 0xCF; // 2400bps @ 8.00MHz
    
       // I/O Ports
       DDRB = (1<<PB3) | (1<<PB0); // OC2 und GreenLED auf Ausgang
       DDRD = (1<<PD6) | (1<<PD2) | (1<<PD1); // FrontLED, RedLED und TXD auf Ausgang
    
       sei();
       StatusLED(GREEN);
    }
    Nun wieder zum eigentlichen RC5-Senden. Es tut sich die erste echte Hürde auf: Wie erkenne ich ob RC5 gesendet wird? Ohne einen RC5-Detektor kommt man erstmal nicht weiter. Deshalb hier ein kleines Programm mit dem der asuro RC5-Signale erkennen kann:
    Code:
    #include "fernbedienunglib.c"
    
    unsigned int count, temp; // Zaehler, IR-Kommando
    unsigned char daten[14], ir_status; // IR-datenspeicher, IR-Eingangsegel
    
    int main(void)
    {
       Init();
       FrontLED(ON);
    
       while(1)
       {
       StatusLED(YELLOW);
       temp=0;
       count=0;
       while (PIND & (1 << PD0)) //warten auf die Flanke des Startbits
          StatusLED(RED); // Alarmstufe ROT: ein Zeichen ist im Anflug
          for (count=0; count<13; count++) { // im Gesamten warten wir auf 14 bits
             Sleep(96); // Information einlesen nach 3/4 der Bitlaenge
             ir_status=(PIND & (1 << PD0)); // Pegel Speichern
             if (ir_status) daten[count]='1'; else daten[count]='0'; // und merken
             if (ir_status) temp |= (1 << (13-count)); // das MSB(=mostsuefikantbit) zuerst
             while (ir_status == (PIND & (1 << PD0))); // Bit gelesen, warten auf naechste Flanke
          }
          temp=temp/2; // Die Info steht in den Bits 1-4
          StatusLED(YELLOW); // Daten gelesen
          Msleep(1000); // Zeit um der IR-Transceifer ueber den asuro zu bringen
           SerWrite("\n\r",2);
          //SerWrite(daten,14); // Bitmuster zum PC senden
          //SerWrite("-",1);
          PrintBin(temp); // erkannte Daten zum PC senden
           SerWrite("\n\r",2);
            StatusLED(GREEN);
          Msleep(1000);
       }
       return(0);
    }
    /* uses timer2 (36kHz for IR communication */
    /* counts falling and rising edge => 36kHz*2 = 72kHz */
    SIGNAL (SIG_OUTPUT_COMPARE2)
    {
       count72kHz ++;
    }
    (Aus https://www.roboternetz.de/phpBB2/vi...=287750#287750 btw. kann auch die aktuelle Lib RC5 empfangen)


    Nach dem Programmstart startet man das Terminal und hält man den Transceiver über den asuro. Wenn man den IR-Empfänger auf dem asuro nun mit RC5-Signalen anblitzt erhält man in etwa so eine Ausgabe im Terminal:
    01000000010
    cæãæcÆãÆcÆãÆcÆãæÆœ˜Æ˜
    0001101000111100
    þþþ
    0001001000000001
    3ø3ø3øÆxÌf3ø
    0001101000000010
    cÆãÆcÆãÆcÆãÆ
    0001001000000011
    ó˜ó˜˜
    0001101000000100
    þþþ
    0001001000000101
    †ó†ó†
    0001101000000110
    cÆÆcÆÆ
    0001001000000111
    ÆÆxÌfÆ
    0001101000001000
    cÆ8þcÆþ
    0001001000001001
    3Æ3Æ
    0001101000000000
    (Das sind die Tasten 1-0 als IR-Code :)

    Immer im Wechsel eine Zeile RC5 per serielle Schnittstelle und die Daten vom asuro. Das Programm reagiert übrigends auf viele IR-Signale, man kann den asuro z.b. auch mit dem Tranceiver anblinken. Viel Spass beim Testen.

    Gruß

    mic
    Bild hier  
    Atmel’s products are not intended, authorized, or warranted for use
    as components in applications intended to support or sustain life!

  5. #5
    Danke erstmal für die ausführlichen Antworten! 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.

    Also nochmal DANKE
    Saskia

  6. #6
    Moderator Robotik Visionär Avatar von radbruch
    Registriert seit
    27.12.2006
    Ort
    Stuttgart
    Alter
    61
    Beiträge
    5.799
    Blog-Einträge
    8
    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;)
    Bild hier  
    Atmel’s products are not intended, authorized, or warranted for use
    as components in applications intended to support or sustain life!

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •  

Solar Speicher und Akkus Tests