- LiFePO4 Speicher Test         
Seite 1 von 3 123 LetzteLetzte
Ergebnis 1 bis 10 von 27

Thema: Servoimpulse vom RC-Empfänger auswerten fehlgeschlagen

  1. #1
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    04.01.2004
    Beiträge
    317

    Servoimpulse vom RC-Empfänger auswerten fehlgeschlagen

    Anzeige

    Powerstation Test
    Hallo,

    ich habe hier im Forum in verschiedenen Beiträgen Ansätze zum Auswerten eines Servosignals vom Empfänger gelesen. Nun habe ich versucht mir daraus mal einen eigenen Versuch zu programmieren um ein solches Signal auszulesen.

    Mein Versuch sieht wie folgt aus:
    Ich habe mein Signal auf den Eingang INT0 gelegt. Den Timer 1 habe ich mit dem Teiler CPU/8 gestartet (CPU-Takt 8MHz).
    Nun wird bei der steigenden Flanke an INT0 ein Interrupt ausgelöst, da setze ich eine Variable, versuche den Counter TCNT1 in eine andere Variable abzulegen und setze den Interrupt auf fallende Flanke.
    Bei der fallenden Flanke passiert das selbe in ähnlicher Weise.
    Code:
    void init_timer(void)
    {
    // Timer0 (8Bit)
     TCCR0 |= (1<<CS00) | (1<<CS01);  //Vorteiler auf CPU Takt/64
    
     TIMSK |= (1<<TOIE0);             //Interupt für Timer0 Overflow einschalten
     
    //Timer 1 (16Bit)
     TCCR1B |= (1<<CS11);               //Vorteiler auf CPU Takt/8 
    }
    
    
    void init_interrupt(void)
    {
     MCUCR |= (1<<ISC00) | (1<<ISC01); //INT0 auf Steigende Flanke
     GICR  |= (1<<INT0); //Interrupt von INT0 auf Enable
    }
    
    
    ISR(INT0_vect)
    {
     if (flanke == 1)
      {
       start = TCNT1;
       MCUCR |= (1<<ISC01);
      }
     
     if (flanke == 0)
      {
       stop = TCNT1;
       MCUCR |= (1<<ISC00) | (1<<ISC01); //INT0 auf Steigende Flanke
       flanke = 0;
      } 
    }
    Mein µC (zur Zeit Mega16 später auch im Mega scheint auch auf die Impulse vom Empfänger zu reagieren, also ein Interrupt wird ausgelöst.
    Mit dem Timer0 lasse ich einen Zähler hochzählen der mir dann durch If anweisungen Ausgänge setzt oder rücksetzt.

    Mein Problem:
    Sobald ich den Empfängerimpuls anschließe wird nur noch der Interrupt ausgeführt, das restliche Programm läuft nicht mehr ab.
    Da ich hier schon öfter davon gelesen habe, meine ich das auch mehrere Impulse ausgewertet werden können und trotzdem noch komplexe Programme ausgeführt werden.

    Was mache ich falsch?
    Ist der Code im Interrupt zu Zeitaufwendig? (Frequenz ist 50Hz Impulslänge von 1ms bis 2ms)
    Ist mein auslesen des Counterregisters richtig? (beim 8Bit Timer ging es so)


    Ich hoffe ich habe mein Problem ausführlich genug beschrieben, sonst bitte einfach nachfragen. Bin noch am Anfang mit der C-Programmiererei.
    Danke schon einmal im voraus für die Hilfe
    mfG Henry

  2. #2
    Erfahrener Benutzer Robotik Visionär Avatar von Hubert.G
    Registriert seit
    14.10.2006
    Ort
    Pasching OÖ
    Beiträge
    6.220
    Wo setzt du "flanke" auf 1, wenn "flanke" auf 0 ist warum setzt du sie anschließend wieder auf 0? Ausserdem ist das sicher nicht der ganze Code denn der macht ja wenig Sinn.

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

    nein das ist nicht der ganze Code. Ich dachte die entscheidenen Teile wären die oben genannten.
    Code:
    //Einbinden der Funktionen aus den anderen Dateien
    extern void init_digital (void);
    extern void init_timer(void);
    extern void init_interrupt(void);
    extern void lcd_writetext(char *text);
    extern void lcd_ini(void);
    extern void lcd_gotopos (uint8_t zeile, uint8_t spalte);
    
    //Globale Variable
    volatile int Zaehler;
    volatile int Zaehler2;
    volatile int start;
    volatile int stop;
    volatile int impuls;
    volatile int flanke;
    volatile char impuls1;
    
      
    int main(void)
    //Hauptprogremm
    {
    //Variablen der Steuerwelle 0 bis Reset
     int LED1 = 0; 
     int LED2 = 250;
     //int LED3 = 50;
     //int LED4 = 100;
     //int LED5 = 0;
     //int LED6 = 0;
     //int LED7 = 0;
     //int LED8 = 0;
     //int LED9 = 0;
     //int LED10 = 0;
     //int LED11 = 0;
     int test = 300;
     int Reset = 500;
    // Ende LED Steuerwellenvorgabe 
     
      init_digital();         // Ports initialisieren (eigene Funktion)
      init_timer();           // Timer initialisieren (eigene Funktion)
      init_interrupt();
      lcd_ini();
      
      flanke = 1; //Flankenmerker
      
     sei(); //Interupts aktivieren
    
    while(1)
     {
    if (Zaehler2 == test) 
    {
     impuls = stop - start;
     itoa(impuls, impuls1,10);
     lcd_gotopos(2,1);
     lcd_writetext("Impd: " + impuls1);
    }
    
     if (PIND & (1<<PIND5))
      {
       PORTC |= (1<<PC5); //Bit1 auf High setzen 
      }
       
     
    // Blaulicht (Blitzer) Transistor T1
      
      if (Zaehler == LED1)
      {
       PORTB |= (1<<PB1); //Bit1 auf High setzen
      }
      
      if (Zaehler == LED1 + 50)
      {
       PORTB &= ~(1<<PB1); //Bit1 auf Low setzen
      }
      
      if (Zaehler == LED1 + 120)
      {
       PORTB |= (1<<PB1); //Bit1 auf High setzen
      }
      
      if (Zaehler == LED1 + 170)
      {
       PORTB &= ~(1<<PB1); //Bit1 auf Low setzen
      }
      
    //ENDE Blaulicht (Blitzer) Transistor T1
    
    //****************************************************************************
      
    // Blaulicht (Blitzer) Transistor T2
    
      if (Zaehler == LED2)
      {
       PORTB |= (1<<PB2); //Bit2 auf High setzen
      }
      
      if (Zaehler == LED2 + 50)
      {
       PORTB &= ~(1<<PB2); //Bit2 auf Low setzen
      }
      
      if (Zaehler == LED2 + 120)
      {
       PORTB |= (1<<PB2); //Bit2 auf High setzen
      }
      
      if (Zaehler == LED2 + 170)
      {
       PORTB &= ~(1<<PB2); //Bit2 auf Low setzen   
      }
    //ENDE Blaulicht (Blitzer) Transistor T2
    
    
    //Zähler Reset  
      if (Zaehler >= Reset)
      {
       Zaehler = 0;
      }  
      
    //Zähler2 Reset  
      if (Zaehler2 >= Reset)
      {
       Zaehler2 = 0;
      }  
    //****************************************************************************
      
      if (!(PIND & (1<<PIND5)))
      {
       PORTC &= ~(1<<PC5);
      }
     } //while
    
    } //ENDE main
    
    
    ISR(TIMER0_OVF_vect)
    //Interrupt bei Timer0 Overflow
    {
     Zaehler++;
     Zaehler2++;
    }
    
    
    ISR(INT0_vect)
    {
     if (flanke == 1)
      {
       start = TCNT1;
       MCUCR |= (1<<ISC01);
      }
     
     if (flanke == 0)
      {
       stop = TCNT1;
       MCUCR |= (1<<ISC00) | (1<<ISC01); //INT0 auf Steigende Flanke stellen (Löst Interrupt bei steigendet Flanke an INT0 aus
       flanke = 0;
      } 
    }
    Das ist jetzt der ganze. Ist ja auch nur ein Testprogrämmchen.
    Flanke wird beim ersten Start des Controllers auf 1 gesetzt und dient nur dazu im Interrupt in die richtige Schleife zu sprinngen.
    mfG Henry

  4. #4
    Erfahrener Benutzer Robotik Visionär Avatar von Hubert.G
    Registriert seit
    14.10.2006
    Ort
    Pasching OÖ
    Beiträge
    6.220
    Wenn du das Signal direkt vom Empfänger auswerten willst weiss ich nicht was du mit Flankenumschalten willst. Die Zeit für das Servo liegt doch im Abstand der Impulse die der Empfänger ausgibt also nur auf steigende oder fallende Flanke setzen.
    Von dem Abgesehen sehe ich nicht wo du auf "flanke =0" stellst.

  5. #5
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    04.01.2004
    Beiträge
    317
    Ich möchte ja die Impulszeit haben, sonst habe ich ja immer unverändert die 50 Hz.
    Wichtig ist Zeit zwischen der steigenden und fallenden Flanke des Impulses
    mfG Henry

  6. #6
    Erfahrener Benutzer Robotik Visionär Avatar von Hubert.G
    Registriert seit
    14.10.2006
    Ort
    Pasching OÖ
    Beiträge
    6.220
    Dann willst du die bereits dekodierten Impulse für das Servo auswerten. Das ist was anderes.
    Ich sehe nicht wo du deinen INT0 initialisierst, nehme an er steht auf steigende Flanke, die steigende Flanke löst den ISR aus, startet den Timer, stellt den INT0 auf fallende Flanke, setzt "flanke" auf 0. Die nächste fallende Flanke löst ISR aus, stoppt den Timer, Timer auslesen,INT0 auf steigende Flanke, "flanke" auf 1. usw.
    Ich weiss nicht ganz wo da das Problem liegt.
    Hubert

  7. #7
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    04.01.2004
    Beiträge
    317
    Ja, die steigende Flanke lege ich beim Initialisieren des Interrups fest.
    Mein Proglem liegt darin, das die anderen Befehle (If) die mir ein paar LED's zum blinken bringen sollen nicht mehr ausgeführt werden. Die LED's hören auf zu blinken.

    Also mein Code sollte demnach funktionieren, oder verstehe ich dich da falsch?
    mfG Henry

  8. #8
    Erfahrener Benutzer Robotik Visionär Avatar von Hubert.G
    Registriert seit
    14.10.2006
    Ort
    Pasching OÖ
    Beiträge
    6.220
    Dein ISR(INT0_vect) kann nicht funktionieren, ausser du sagst mir wo du auf "flanke =0" umschaltest.

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

    Du hast Recht, ich habe vergessen auf Flanke 0 zu schalten. Ich probiere es mal aus ob es dann klappt.
    Melde mich dann noch einmal hier
    mfG Henry

  10. #10
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    04.01.2004
    Beiträge
    317
    Hmm,

    das hatte ich wohl versehendlich gelöscht beim testen. Das Programm wird immer noch nicht weiter abgearbeitet wenn ein Impuls anliegt.
    Code sieht jetzt so aus:
    Code:
    //Einbinden der Funktionen aus den anderen Dateien
    extern void init_digital (void);
    extern void init_timer(void);
    extern void init_interrupt(void);
    extern void lcd_writetext(char *text);
    extern void lcd_ini(void);
    extern void lcd_gotopos (uint8_t zeile, uint8_t spalte);
    
    
    //Globale Variable
    volatile int Zaehler;
    volatile int Zaehler2;
    volatile int start;
    volatile int stop;
    volatile int impuls;
    volatile int flanke;
    volatile int z1;
    volatile char impuls1;
    volatile char z11;
      
    int main(void)
    //Hauptprogremm
    {
    //Variablen der Steuerwelle 0 bis Reset
     int LED1 = 0; 
     int LED2 = 250;
     //int LED3 = 50;
     //int LED4 = 100;
     //int LED5 = 0;
     //int LED6 = 0;
     //int LED7 = 0;
     //int LED8 = 0;
     //int LED9 = 0;
     //int LED10 = 0;
     //int LED11 = 0;
     int test = 300;
     int Reset = 500;
    // Ende LED Steuerwellenvorgabe 
     
      init_digital();         // Ports initialisieren (eigene Funktion)
      init_timer();           // Timer initialisieren (eigene Funktion)
      init_interrupt();
      lcd_ini();
      
      flanke = 1; //Flankenmerker
      z1 = 0;
      
     sei(); //Interupts aktivieren
    
    while(1)
     {
    if (Zaehler2 == test) 
    {
     impuls = stop - start;
     itoa(impuls, impuls1,10);
     itoa(z1, z11,10);
     lcd_gotopos(2,1);
     lcd_writetext("Impd: " +impuls1);
     lcd_gotopos(3,1);
     lcd_writetext(z11);
    }
    
     if (PIND & (1<<PIND5))
      {
       PORTC |= (1<<PC5); //Bit1 auf High setzen 
      }
       
     
    // Blaulicht (Blitzer) Transistor T1
      
      if (Zaehler == LED1)
      {
       PORTB |= (1<<PB1); //Bit1 auf High setzen
      }
      
      if (Zaehler == LED1 + 50)
      {
       PORTB &= ~(1<<PB1); //Bit1 auf Low setzen
      }
      
      if (Zaehler == LED1 + 120)
      {
       PORTB |= (1<<PB1); //Bit1 auf High setzen
      }
      
      if (Zaehler == LED1 + 170)
      {
       PORTB &= ~(1<<PB1); //Bit1 auf Low setzen
      }
      
    //ENDE Blaulicht (Blitzer) Transistor T1
    
    //****************************************************************************
      
    // Blaulicht (Blitzer) Transistor T2
    
      if (Zaehler == LED2)
      {
       PORTB |= (1<<PB2); //Bit2 auf High setzen
      }
      
      if (Zaehler == LED2 + 50)
      {
       PORTB &= ~(1<<PB2); //Bit2 auf Low setzen
      }
      
      if (Zaehler == LED2 + 120)
      {
       PORTB |= (1<<PB2); //Bit2 auf High setzen
      }
      
      if (Zaehler == LED2 + 170)
      {
       PORTB &= ~(1<<PB2); //Bit2 auf Low setzen   
      }
    //ENDE Blaulicht (Blitzer) Transistor T2
    
    
    //Zähler Reset  
      if (Zaehler >= Reset)
      {
       Zaehler = 0;
      }  
      
    //Zähler2 Reset  
      if (Zaehler2 >= Reset)
      {
       Zaehler2 = 0;
      }  
    //****************************************************************************
      
      if (!(PIND & (1<<PIND5)))
      {
       PORTC &= ~(1<<PC5);
      }
     } //while
    
    } //ENDE main
    
    
    ISR(TIMER0_OVF_vect)
    //Interrupt bei Timer0 Overflow
    {
     Zaehler++;
     Zaehler2++;
    }
    
    
    ISR(INT0_vect)
    {
     if (flanke == 1)
      {
       start = TCNT1;
       MCUCR |= (1<<ISC01); //INT0 auf fallende Flanke stellen
       flanke = 0;
      }
     
     if (flanke == 0)
      {
       stop = TCNT1;
       MCUCR |= (1<<ISC00) | (1<<ISC01); //INT0 auf Steigende Flanke stellen (Löst Interrupt bei steigendet Flanke an INT0 aus
       flanke = 1;
       z1++;  
      } 
    }
    mfG Henry

Seite 1 von 3 123 LetzteLetzte

Berechtigungen

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

Labornetzteil AliExpress