- 3D-Druck Einstieg und Tipps         
Ergebnis 1 bis 7 von 7

Thema: PWM Signal von RC-Empfänger auswerten

  1. #1
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    29.11.2006
    Ort
    Geislingen a. d. Steige
    Alter
    33
    Beiträge
    344

    PWM Signal von RC-Empfänger auswerten

    Anzeige

    Praxistest und DIY Projekte
    Hi,
    ich möchte das PWM signal eines RC-Empfängers auswerten.
    Hat das schon jemand gemacht ? Hätte mir jemand einen beispielcode?
    In Google und in der Forum Suche hab ich nur was in Bascom und ASM gefunden.

    Mfg Martin

  2. #2
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    30.07.2005
    Beiträge
    569
    Jo, das hab ich schon mal gemacht ... nur halt in ASM ...
    Grundregeln des Forenpostings:
    1. Nutze niemals die Suchfunktion!
    2. Überprüfe niemals die Topics nach Ähnlichkeiten!
    3. Schreibe alles in hellgelb!

  3. #3
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    29.11.2006
    Ort
    Geislingen a. d. Steige
    Alter
    33
    Beiträge
    344
    Hat das auch schonmal jemand in C gemacht?

    MfG Martin

  4. #4
    Erfahrener Benutzer Robotik Einstein Avatar von wkrug
    Registriert seit
    17.08.2006
    Ort
    Dietfurt
    Beiträge
    2.214
    Ich hab erst kürzlich so ein Programmteil in ASM für C gemacht.
    Wenn ich heute nach Hause komme kann ich dir den Quellcode mal zuschicken wenn Du das möchtest. Der ist aber für CodeVision AVR!

    Im Prinzip läuft dabei der Timer1 frei.
    Die Servoimpulse werden auf einen Interrupteingang des AVR gelegt.
    Am Anfang steht die Interruptauslösung auf "steigende Flanke".
    Im Interrupt 0 wird dann der aktuelle Zählerwert in eine Variable eingelesen und die Interrupteinstellung auf fallende Flanke geändert (MCUCR).
    Bei der fallenden Flanke wird der Zählerwert des Timers 1 erneut ausgelesen und der Startwert davon abgezogen und die Interrupteinstellung wieder auf steigende Flanke für den nächsten Impuls gesetzt. Du kannst nach einer fertigen Messung noch ein Flag setzen (Bit Variable) das ein neuer Servoimpuls erkannt wurde (Zur Weiterverarbeitung im Hauptprogramm).
    Dadurch das der Timer 1 frei läuft können alle Interrupteingänge + der ICP Pin für die Servoimpulsauswertung verwendet werden. Du kannst somit bis zu 4 Servokanäle überwachen (ATMEGA 16) ohne dabei den Prozessor übermäßig zu belasten.

    Als Teilerfaktor für den Timer 1 würd ich 8 verwenden bei einem 8MHz Quarz, dann werden deine Servoimpulse im 1uS Bereich aufgelöst. Ein durchschnittlicher Servoimpuls (1,5ms) wird somit als 1500 dargestellt.
    Der gesamte Servoweg 1ms bis 2ms hat somit 1000 Schritte und sollte somit auch für anspruchsvollere Aufgaben geeignet sein.

    Wenns nicht reicht - Taktfrequenz erhöhen (16 MHz) oder Teilerfaktor des Timers 1 auf 1 setzen (würd ich bei 4MHz Taktfrequenz machen).

  5. #5
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    04.01.2004
    Beiträge
    317
    Hallo Martin,

    ich weiß nicht ob Du das Problem schon gelöst hast. Ich habe aufgrund dieses Beitrags hier mal einen Code zusammengebastelt (da ich das auch gesucht habe). Mit Hilfe des Forums habe ich dann auch noch kleine Probleme darin behoben.

    Hie mal die Codeteile die Relevant sind um erst einmal ein Grundgerüst zu haben. Ich habe das in einzelnen Funktionen gelöst, kann man sicher noch besser machen (bin aber selber noch nicht so fit in C).
    Das Beispiel läuft bei mir auf einem Mega16 mit 8MHz, es basiert auf der vorhergehenden Antwort.

    Interrupt auf INT0 initialisieren:
    Code:
    void init_interrupt(void)
    {
     MCUCR |= (1<<ISC00) | (1<<ISC01); //INT0 auf Steigende Flanke stellen (Löst Interrupt bei steigendet Flanke an INT0 aus
     GICR  |= (1<<INT0); //Interrupt von INT0 auf Enable
    }
    Timer initialisieren:
    Code:
    void init_timer(void)
    {
    //Timer 1 (16Bit)
     TCCR1B |= (1<<CS11);               //Vorteiler auf CPU Takt/8
    }
    PortB initialisieren (als Ausgang schalten):
    Code:
    void init_digital(void)
    /*Diese Funktion initialisiert die verwendeten Ports*/
    {
      DDRB |=  (1<<DDB1) | (1<<DDB2) | (1<<DDB3) | (1<<DDB4) | (1<<DDB5);  //Bit 1 bis Bit 5 an Port B als Ausgang belegen
    }
    Interrupt an INT0 auswerten:
    Code:
    ISR(INT0_vect)
    {
     if (flanke == 1)
      {
       start = TCNT1;
       MCUCR |= (1<<ISC01); //INT0 auf fallende Flanke stellen
       MCUCR &= ~(1<<ISC00);
       flanke = 0;
      }
       else
        {
    	 stop = TCNT1;
    	 impuls = stop - start;
         MCUCR |= (1<<ISC00) | (1<<ISC01); //INT0 auf Steigende Flanke stellen (Löst Interrupt bei steigendet Flanke an INT0 aus)
         flanke = 1;  
        } 
    }
    Testprogramm zur Visualisierung der Auswertung:
    Code:
    #include <avr/io.h>
    #include <avr/iom16.h>
    #include <avr/interrupt.h>
    #include "inttypes.h"
    
      init_digital();         // Ports initialisieren (eigene Funktion)  
      init_timer();           // Timer initialisieren (eigene Funktion)
      init_interrupt();      // Interrupt initialisieren
     
    
    int main(void)
    {
    
    int start;
    int stop;
    int32_t impuls;
    int flanke;
    
    sei(); //Interrupts aktivieren
    
    while(1)
    {
    
    //****************************************************************************   
      if (impuls < 1100)
      {
       PORTB |= (1<<PB3); //Bit3 auf High setzen
      }
      
      if (impuls > 1800)
      {
       PORTB |= (1<<PB4); //Bit4 auf High setzen
      }
      
      if ((impuls > 1490) & (impuls < 1550))
      {
       PORTB &= ~(1<<PB4); //Bit4 auf Low setzen
       PORTB &= ~(1<<PB3); //Bit3 auf Low setzen
      }
        
    //****************************************************************************
    
    }
    
    }
    In meinem Beispiel wird bei einem vollen Knüppelausschlag in eine Richtung PB3 gesetzt in nullstellung wieder zurückgesetzt und in die andere Richtung PB4 auf High und in Nullstellung ebenfalls wieder auf Low

    Ich hoffe das Hilft Dir weiter, falls Du noch keine Lösung hast.
    mfG Henry

  6. #6
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    29.11.2006
    Ort
    Geislingen a. d. Steige
    Alter
    33
    Beiträge
    344
    Hi,
    nein ich habe das problem noch nicht gelöst.
    Danke für den code ich werds gleich mal ausprobieren.

    MfG Martin

  7. #7
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    04.01.2004
    Beiträge
    317
    Dann konnte ich Dir ja evt. sogar damit helfen
    Viel weiter bin ich auch noch nicht, da ich jetzt erst einmal schauen muss wie ich meine Idee umsetzen kann.
    Da scheitert es zur Zeit noch an der Programmtechnischen Umsetzung
    mfG Henry

Berechtigungen

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

Labornetzteil AliExpress