- 3D-Druck Einstieg und Tipps         
Seite 2 von 4 ErsteErste 1234 LetzteLetzte
Ergebnis 11 bis 20 von 36

Thema: rc5 daten senden mit winavr

  1. #11
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    20.06.2004
    Beiträge
    1.941
    Anzeige

    Powerstation Test
    kannst du mal schauen , ob man nicht irgendwie von hand die 14 bytes senden kann. evtl als test in einer while-schleife über 36khz über den ocra1. man könnte ja pro halb-bit eine schleife machen von 889us und dann pind5 z.b beim AVR16 (ocra1) mit 36khz-pwm versehen und diese dann je nach bit aus oder einschalten und nach dem 14bit kommt ja wieder eine pause von 89ms weil ja die komplette sendezeit immer 114ms beträgt. die 36khz kann man doch mit dem mc-musterprogramm erzeugen, oder?

    mfg pebisoft

  2. #12
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    23.05.2004
    Ort
    Untersöchering(Bayern,Alpenvorland)
    Alter
    38
    Beiträge
    215
    Aber wieso denn den ganzen rc5 Code? Willst du Fernsehgeräte ansteuertn? Im rc5 Code sind ja auch nur die letzten 6Bit Befehlsbits d.h. man kann auch nur 64 Befehle senden.
    Gruß Muraad

  3. #13
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    23.05.2004
    Ort
    Untersöchering(Bayern,Alpenvorland)
    Alter
    38
    Beiträge
    215
    Pepisoft ich hab jetzt nochmal zwei Funktionen, mit denen man ein Byte, bitweise senden kann. Das 36kHz Signal wird immer noch mit PWM und Timer1 erzeugt. Timer2 wird für das senden und empfangen verwendet.
    Beide Funktionen benutzen die Timer so das sie nur währen der Funktion gebraucht werden. Man könnte also auch noch z.B. srf04 Messung auch mit Timer1 machen.
    Hier der Code:
    Code:
    // Wieder für 8 Mhz
    #include <avr/io.h>
    #include <avr/signal.h> 
    #include <avr/interrupt.h> 
    
    // Eins auswählen 
    
    #define send
    // #define receive
    
    // Wie lange die verschiedenen Signale dauern in X_SIGNAL*0,128us 
    #define START_SIGNAL    250          // z.B. 250*0,128us=32ms langes Start Signal
    #define HIGH_SIGNAL     200          //  25,6ms
    #define LOW_SIGNAL      100          //  12,8ms
    // Ein Byte zu senden dauert somit max. 32ms+8*25,6ms=236,8ms, für die Zahl 256
    
    // Pin an dem der TSOP Ausgang angeschlossen ist
    #define rc5_pin  // z.B. PINA
    #define rc5_bit   // z.B. PA1
    
    // Für PWM 36kHz Signal
    #define PWM_PORT       DDRD             // PWM Pin1 von Timer1, beim ATmega16 z.B. PD5
    #define PWM_BIT        PD5           
    
    #ifdef send
    
    void rc5_send(unsigned char byte)      
    {                                       
       volatile unsigned char byte_flag,x;
       
       // Timer1 Fast PWM Prescaler 1, 36kHz Träger, 
       TCCR1A = (1<<COM1A1) | (1<<COM1A0) | (1<<WGM11); 
       TCCR1B = (1<<WGM12) | (1<<WGM13) | (1<<CS10); 
       OCR1A = 111;                     
       ICR1 = 222;     
       byte_flag=0;
       
       /* Sendet Start Signal */
       
       // Lädt Timer2 Register mit 5 vor ein 250*128us=32ms langes Startsignal zu senden
       TCNT2 = 255 - START_SIGNAL;        
       // Prescaler 1024 Frequenz 7,8125kHz Tackt von 128us  , Timer an
       TCCR2= (1<<CS22) | (1<<CS21) | (1<<CS20); 
       PWM_PORT |= (1<<PWM_BIT);     // Der Pin mit dem 36kHz Siganl wird auf Ausgang geschaltet
       
       // Warten bis Overflow2 nach 32ms 
       while(!(TIFR & (1<<TOV2))) asm volatile ("nop");
       PWM_PORT &= ~(1<<PWM_BIT);            // 36kHz Signal aus   
       TCCR2= ~(1<<CS22) & ~(1<<CS21) & ~(1<<CS20);         // Timer2 aus
       
       for(x=0;x<=200;x++) asm volatile ("nop");    // Kleine Pause
       /* Sendet nun das byte, bitweise */
       
       // high=25,6ms lang, low=12,8ms lang
       for(byte_flag;byte_flag<=7;byte_flag++)
       {
          if(byte & (1<<byte_flag))      // Ist bit(byte_flag) in byte high
             TCNT2=255-HIGH_SIGNAL;             // Wenn ja TCNT2 vorladen für high senden
          else     
             TCNT2=255-LOW_SIGNAL;            
    	  TCCR2= (1<<CS22) | (1<<CS21) | (1<<CS20);      // Timer an
          PWM_PORT |= (1<<PWM_BIT);                               // 36kHz Signal an
          while(!(TIFR & (1<<TOV2))) asm volatile ("nop");     // Warten bis Overlow2, -> Bit gesendet
          PWM_PORT &= ~(1<<PWM_BIT);                                    // 36kHz Signal aus   
          TCCR2= ~(1<<CS22) & ~(1<<CS21) & ~(1<<CS20);         // Timer2 aus
    	  for(x=0;x<=200;x++) asm volatile ("nop");           // Kleine Pause
       }
       // Timer1 wieder aus, kein PWM mehr
       TCCR1A = ~(1<<COM1A1) & ~(1<<COM1A0) & ~(1<<WGM11); 
       TCCR1B = ~(1<<WGM12) & ~(1<<WGM13) & ~(1<<CS10); 
       OCR1A = 0;                     
       ICR1 = 0; 
    }   
    #endif
    
    #ifdef recieve
    unsigned char rc5_recieve(void) 
    { 
       volatile unsigned char byte,byte_flag,wert,x;
       x=0; 
       byte_flag=0;
       
       // Solange messen bis Startsignal empfangen, aber max. 9 mal damit nicht in endlosschleife 
       // galls garkein Signal
       do{      
       TCNT2=0;                   // Timerregister  auf 0
       // Warten bis rc5/tsop1736 Pin auf high
       while (!(rc5_pin & (1<<rc5_bit))) asm volatile ("nop");     
       TCCR2= (1<<CS22) | (1<<CS21) | (1<<CS20);         // Timer2 starten, Prescaler 1024 
       // Warten bis rc5/tsop1736 Pin auf low
       while (rc5_pin & (1<<rc5_bit)) asm volatile ("nop");    
       wert=TCNT2;               //  byte = Timer1
       TCCR2= ~(1<<CS22) & ~(1<<CS21) & ~(1<<CS20);         // Timer2 aus 
       x++;    
       // Wert nicht genau auf STAR_SIGNAL prüfen um eine Fehlertoleranz zu haben
       }while((!((wert > STAR_SIGNAL - 10)&&(wert < START_SIGNAL + 5)))|| x!=9);   
       
       // Wenn Startsignal empfangen
       if((wert > STAR_SIGNAL - 10) && (wert < START_SIGNAL + 5))
       {
          // Schleife um einzelne Bits zu empfangen
    	  for(byte_flag;byte_flag<=7;byte_flag++)
    	  {
    	     TCNT2=0;                   // Timerregister  auf 0
             // Warten bis rc5/tsop1736 Pin auf high
    		 while (!(rc5_pin & (1<<rc5_bit))) asm volatile ("nop");    
             TCCR2= (1<<CS22) | (1<<CS21) | (1<<CS20);         // Timer2 starten, Prescaler 1024 
             // Warten bis rc5/tsop1736 Pin auf low
    		 while (rc5_pin & (1<<rc5_bit)) asm volatile ("nop");    
             wert=TCNT2;               
             TCCR2= ~(1<<CS22) & ~(1<<CS21) & ~(1<<CS20);         // Timer2 aus
             
    		 // Wieder Fehlertoleranz für HIGH_SIGNAL und LOW_SIGNAL, diesmal +/- 20
    		 if((wert > HIGH_SIGNAL - 20) && (wert < HIGH_SIGNAL + 20))
                byte|=(1<<byte_flag);      // Bit ist high, entsprechendes bit in byte high setzen
             else if(wert>80 && wert<120)
    		    byte&= ~(1<<byte_flag);    // Bit low setzen
    	  }
          return byte;                
       }
       // Wenn kein Startsignal empfangen
       else
          return 0;                
    } 
    #endif
    Ist bisschen mehr dieses mal. Werden wahrscheinlich auch noch einige Fehler drin sein.
    Vielleicht kannst/musst du auch mal mit den Zeiten für die einzelnen SIGNALE rumspielen, und mit deren Toleranzen in der recieve Funktion.
    Und noch was zur rc5_recieve(), sie versucht erst neun mal ein Startsignal zu empfangen. Hat sie ein Startsignal empfangen beginnt sie mit dem empfang der einzelnen Bits. In der rc5_send(byte) ist nach dem Startsignal und nach jedem einzelnen Bit eine kleine Sendepause, mit
    for(x=0;x<=200;x++) asm volatile ("nop");
    Theoretisch müsste es funktionieren.
    Gruß Muraad

    EDIT: Hab schon wieder was verbessert

    EDIT: Ich hab nochmal was verändert. Vielleicht funktioniert er ja jetzt?!

  4. #14
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    20.06.2004
    Beiträge
    1.941
    hallo muradd, man kann auch die addressbit als daten dazunehmen. ich möchte den robby damit daten übersenden. dem tsop interessiert nicht was man mit den 11bit macht(address und comman), es werden 14bit übertragen und beim empfang kann man die bit address und command (11bit)zu einem 10bit-wert (1024) zusammensetzen z.b. und hat 1024 möglichkeiten und man hat noch 1bit über.
    senden würde ich gerne ohne timer, nur den pwm-port(oc1a z.b) je nach halb-bit mit 889us einschalten oder auschalten in einer schleife.
    mfg pebisoft

  5. #15
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    23.05.2004
    Ort
    Untersöchering(Bayern,Alpenvorland)
    Alter
    38
    Beiträge
    215
    Mein Code könnte man theoretisch auch auf 100 zu sendende Bits erweitern sogar ziemlich leicht.
    Nur mit nur einem Timer wird es schwer, mir fällt auch grad nichts konkretes ein wie ich das anstellen könnte.
    Ein genaues Timing, mit for() Schleifen, wird ohne zweiten Timer auch ziemlich schwer glaub ich. Wie wird das bei Bascom gemacht, auch mit nur einem Timer?

    Gruß Muraad

  6. #16
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    20.06.2004
    Beiträge
    1.941
    hallo muraad, bei Bascom ist es timer 1, da gibt es den befehl "rc5send togbit, adress, command".
    dies ist der anschluss " +5V <---[A Led K]---[220 Ohm]---> PD5 "
    bei bascom. pd5 ist beim AVR16 oc1a.


    ich habe mal ein beispiel mit us_889 und ms_89. oc1a ist bei mir am AVR16 pd5. der pd5 (oca1) wird je nach bit auf high oder low geschaltet. lieg ich hier verkehrt mit meiner ganzen theorie.

    Code:
    #include <stdio.h>
    #include <inttypes.h> 
    #include <avr/io.h> 
    #include <avr/delay.h> 
    #include <avr/interrupt.h> 
    #include <avr/signal.h>
    #include <string.h> 
    #include <stdint.h>
    
    
    uint16_t zaehler;
    uint32_t zaehler1;
    
    void us_889(void)
    {
    	
    	for (zaehler=0; zaehler<1185; zaehler++) 
    	asm volatile("nop");
    	
    }	
    		
    void ms_89(void)
    {
    	for (zaehler1=0; zaehler1<117105; zaehler1++) 
    	asm volatile("nop");
    }	
    
    void ir_init_send(void) {
    	//36kHz Träger
    	TCCR1A = (1<<COM1A1) | (1<<COM1A0) | (1<<WGM11);
    	TCCR1B = (1<<WGM12) | (1<<WGM13) | (1<<CS10);
    	OCR1A = 111;
    	ICR1 = 222;
    	//Timer-Interrupt alle 2,048ms zur Signalerzeugung --> 1/(8MHz/256/64)
    	TCCR0 = (1<<CS01) | (1<<CS00);    //Prescaler von 64
        TIMSK |= (1<<TOIE0);               //Timer0 Overflow Interrupt aktivieren
    }
     
    
    int main(void)
    {
    
    ir_init_send();
    DDRD=255; 
    PORTD=32;  // bit pd5
        
    	while (1)
    	{	
    		PORTD=32;
    		us_889();
    		PORTD=0;
    		us_889();
    		
    		PORTD=32;
    		us_889();
    		PORTD=0;
    		us_889();
    		
    		PORTD=32;
    		us_889();
    		PORTD=0;
    		us_889();
    		
    		PORTD=32;
    		us_889();
    		PORTD=0;
    		us_889();
    		
    		PORTD=0;
    		us_889();
    		PORTD=32;
    		us_889();
    		
    		PORTD=0;
    		us_889();
    		PORTD=32;
    		us_889();
    		
    		PORTD=32;
    		us_889();
    		PORTD=0;
    		us_889();
    		
    		PORTD=0;
    		us_889();
    		PORTD=32;
    		us_889();
    		
    		PORTD=0;
    		us_889();
    		PORTD=32;
    		us_889();
    		
    		PORTD=0;
    		us_889();
    		PORTD=32;
    		us_889();
    		
    		PORTD=32;
    		us_889();
    		PORTD=0;
    		us_889();
    		
    		PORTD=32;
    		us_889();
    		PORTD=0;
    		us_889();
    		
    		PORTD=0;
    		us_889();
    		PORTD=32;
    		us_889();
    		
    		PORTD=0;
    		us_889();
    		PORTD=32;
    		us_889();
    		
    		PORTD=32;
    		ms_89();
    	}
    }
    mfg pebisoft

  7. #17
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    23.05.2004
    Ort
    Untersöchering(Bayern,Alpenvorland)
    Alter
    38
    Beiträge
    215
    Also kann man mit Bascom richtige rc5 Befehle sende, und nicht einfach nur ein Byte?! Ich verstehe immer noch nicht was du mit dem rc5 Protokoll willst. Es ist vielleicht für Fernbedienungen gut aber für nen Roboter. Ich hab halt so zusagen ein eigenes Protokoll gemacht.
    Und zu deinem Code. Würde prinzipiell schon gehen, du musst das nur in ne Funktion packen und ihr eine unsigned int Variable übergeben. In der Funktion werden dann die ersten 14Bits der Variable überprüft ob sie low oder high sind und dementsprechend gesendet.
    Dann brauchst du noch nen Funktion die das Empfäng und auswertet.

    Gruß Muraad

  8. #18
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    20.06.2004
    Beiträge
    1.941
    hallo, muurad, guten tag.
    empfänger in winavr-c gibt es schon. ich kann von der fernbedienung alle signale mit dem winavr-c anzeigen lassen auf dem lcd-display oder pc-schirm (vom AVR über rs232). mich interessiert einfach , wie ich jetzt daten selber erzeugen kann in den 14bytes. dein programm läuft noch nicht, vielleicht liegt es am timer. die ausgabe habe ich schon in "ddrd" umgeschrieben. ich habe einen video-audio-sender auf dem robby, der vom robby zum arbeitstisch senden kann. der empfänger auf dem arbeitstisch kann über funk aber auch ein ir-signal zum sender schicken, damit man quasi den fernsehsender umschalten kann. ich möchte das jetzt dazu nutzen den robby steuerungsdaten für das verhalten per ir zu schicken. diese daten möchte ich aber selber erzeugen und nicht die fernbedienung. ich habe überall im internet schon geschaut, es gibt kein programm in winavr-c für das senden von rc5-code. das es unmöglich ist, glaube ich nicht. ist vielleicht eine schwierige aufgabe. obwohl der rc5-code und die erklärungen bestens sind, schaff ich es nicht umzusetzen.
    kein sende-empfangscode für den rc5 ist eigentlich so gut erklärt.
    mfg pebisoft

  9. #19
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    28.04.2004
    Ort
    Nähe Köln
    Alter
    58
    Beiträge
    247
    Hallo pebisoft

    RC5 Sender zu programmieren, ist eigentlich kein größeres Problem.

    Schau mal auf dieser Seite nach.

    http://home.t-online.de/home/holger....de/rc5send.htm

    Ist zwar für PIC, aber in C und somit mit nur wenigen Änderungen zu übernehmen. Ich habe das mal für einen Tiny12 übernommen
    und es läuft ohne Probleme. Da der Tiny12 jedoch mit interem Takt von 1.2 MHz lief, ist das Programm für deine Taktfrequenz nicht
    ohne weiteres zu übernehmen. Auch lief auf dem Tiny12 nichts anderes.

    MFG
    Dieter

  10. #20
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    20.06.2004
    Beiträge
    1.941
    ich habe obern mal was geschrieben, ganz einfach, funktioniert aber nicht.
    kannst du einmal schauen gestern 21:28 . was mache ich da verkehrt.
    mfg pebisoft

Seite 2 von 4 ErsteErste 1234 LetzteLetzte

Berechtigungen

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

12V Akku bauen