- MultiPlus Wechselrichter Insel und Nulleinspeisung Conrad         
Seite 2 von 3 ErsteErste 123 LetzteLetzte
Ergebnis 11 bis 20 von 27

Thema: Servoimpulse vom RC-Empfänger auswerten fehlgeschlagen

  1. #11
    Erfahrener Benutzer Robotik Einstein Avatar von wkrug
    Registriert seit
    17.08.2006
    Ort
    Dietfurt
    Beiträge
    2.232
    Anzeige

    E-Bike
    Ich würd sagen, Du hast da einen Denkfehler im Programm.

    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++;

    Wenn die flanke 1 ist wird die if Anweisung ausgeführt und am Ende flanke=0 gesetzt.
    dadurch wird aber sofort wieder die zweite if anweisung für flanke == 0 ausgeführt.
    Du müsstest also von der ersten if anweisung aus die zweite überspringen, sonst wird ser Interrupt immer nur bei der steigenden Flanke ausgeführt.

    Mal ne Frage - Testet ihr sowas nicht mit dem AVR - Studio aus ?
    Da wär Dir das sofort aufgefallen.
    Ich halt auch die Verwendung des Timers 0 für gefährlich.
    Wenn der Interrupt 0 kurz vor einem Überlauf des Timers 0 aktiv wird, kann der Timer 0 schon wieder auf 0 stehen, ohne aber das externe Überlauf register zu erhöhen. Was dann einen Messfehler von 0,256 ms zur Folge hat.
    Ich würd den Timer 1 frei laufen lassen, solange du nicht am TCNT 1 register rummanipulierst, kannst Du diesen Timer sogar noch für andere Aufgaben verwenden und du hast eine zuverlässige 16Bit Auswertung.
    Die Impulswerte können durch subtraktion in der INT 0 Routine ermittelt werden.

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

    da mmuss ich Dir Recht geben. Das hatte ich nicht gesehen.
    Hatte unabhängig davon gerade mal das zweite If durch ein Else ausgetauscht, das sollte doch dieses Problem ebenfalls beheben, oder?

    Mein Problem wird dadurch allerdings nicht gelöst, funktioniert trotzdem nicht.
    Mein Programm wird trotzdem nicht weiter ausgeführt und die Ausgaben zeigen auch nur Müll auf dem Display, kann aber natürlich das selbe Problem mit der Abarbeitung sein.

    Und nein ich teste nicht im AVR Studio, ich teste direkt im Controller
    Für AVR-Studio war ne Registrierung notwendig, oder?

    Mein ISR sieht jetzt so aus:
    Code:
    ISR(INT0_vect)
    {
     if (flanke == 1)
      {
       start = TCNT1;
       MCUCR |= (1<<ISC01); //INT0 auf fallende Flanke stellen
       flanke = 0;
       }
       else
        {
         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

  3. #13
    Erfahrener Benutzer Robotik Einstein Avatar von wkrug
    Registriert seit
    17.08.2006
    Ort
    Dietfurt
    Beiträge
    2.232
    Für AVR-Studio war ne Registrierung notwendig, oder?
    Nö, soweit ich weiß ist da keine Registrierung nötig.
    Müsste was Neues sein.
    Der Vorteil ist halt, du kannst im Simulator vom Studio einzelne Eingänge von Hand setzen oder löschen, Du hast ne Uhr und nen Zyklenzähler drin, Du kannst alle Speicherinhalte auslesen usw.

    Dadurch kannst Du dann virtuell auch alle Register anschauen und auch austesten, ob die gewünschten Routinen auch wirklich wie gewünscht ausgeführt werden.

    Lediglich mit Zeitschleifen ist das immer ein kleines gerödel, weil die im Studio halt sehr lange brauchen für nen Durchlauf.

    Was auch immer ein wenig problematisch ist, wenn der AVR mit anderen Chips interagieren muss. Alle Leitungen zum richtigen Zeitpunkt zu setzen ist immer ein kleineres Problem. Standard LCD's zu simulieren ist auch immer etwas schwierig.

    Aber für so ne popelige Servoroutine klappt das allemal.

  4. #14
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    04.01.2004
    Beiträge
    317
    Dann muss ich mir das auf der Webseite noch einmal anschauen, ich meine letztens gesehen zu haben das man da Name und Adresse usw. angeben mußte um den Download zu starten.

    Aber auch ohne muss es ja eigentlich Laufen, kann ja nicht sein das der Controller (ob nun Mega8 oder, 16 oder 32) schon bei der Auswertung von einem Signal überfordert ist. Sonst laufen zur Zeit ja nur einfache Zähler hoch die dann über If ein paar Ausgänge setzten und rücksetzen.
    Das ist eigentlich das was mich etwas wundert
    mfG Henry

  5. #15
    Erfahrener Benutzer Robotik Einstein Avatar von wkrug
    Registriert seit
    17.08.2006
    Ort
    Dietfurt
    Beiträge
    2.232
    Da hast Du schon recht,

    So ein AVR langweilt sich mit so einer Servoauswerteroutine, aber wenn ein Programm- (Denk-) fehler drin ist, hilft halt die ganze Geschwindigkeit nichts.

    Ich wollte Dich mit dem Hinweis auf das Überlaufproblem der 8 Bit Timer nicht schocken, dieser Fehler wird sicherlich in den seltensten Fällen zum tragen kommen.

    Da das Timing aber in diesem Fall von einer externen Quelle stammt, kann das Problem halt hin und wieder mal auftreten.

  6. #16
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    04.01.2004
    Beiträge
    317
    Leider will er aber trotzdem noch nicht so wie ich. Ich habe nun schon den Timer0 deaktiviert und immer noch kein Erfolg.
    Sooooo dämlich kann ich mich doch auch nicht angestellt haben
    mfG Henry

  7. #17
    Erfahrener Benutzer Robotik Einstein Avatar von wkrug
    Registriert seit
    17.08.2006
    Ort
    Dietfurt
    Beiträge
    2.232
    Ich kann leider dein Prog nicht austesten weil ich nicht mit Win AVR arbeite.
    Wie ist das ?
    Wird ein gesetztes Byte durch die Anweisung beim MCUCR Register zurückgesetzt ?
    Wenn das nicht so ist müsstest Du das Register mit & und einem Wert der alle Bits auf 1 setzt, bis auf das zu löschende Bit z.B. 0b11111110 .
    Dieser Befehl müsste das Letzte Bit eines Wertes löschen.

    Im MCUCR sind doch das ISC01 und das ISC00 Bit gesetzt
    Wenn Du also das ISC01 mit dem Inhalt des MCUCR veroderst, bleibt doch das ISC00 gesetzt, und der Controller reagiert wieder auf die steigende Flanke ?
    Wie wärs, wenn du Assembler Befehle zum setzen und löschen der Bytes verwenden würdest

    #asm
    sbi MCUCR,ISC01; ASSEMBLER Befehl zum setzen eines Bits in einem I/O Register
    sbi MCUCR,ISC00
    #endasm

    bzw.

    #asm
    cbi MCUCR,ISC00; ASSEMBLER Befehl zum löschen eines Bits in einem I/O Register
    sbi MCUCR,ISC01
    #endasm

    Die ASM Einbindung geht bei CodeVision so, wie es bei Win AVR geht weiß ich nicht.

    if (flanke == 1)
    {
    start = TCNT1;
    Diese Zeile in Deinem Quellcode meine ich ->MCUCR |= (1<<ISC01); //INT0 auf fallende Flanke stellen
    flanke = 0;

  8. #18
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    04.01.2004
    Beiträge
    317
    Das mit dem Sttzen des Bits auf null kann ich noch einmal versuchen.
    Könnte ein Problem sein, ich dachte halt das es dann auf Null gesetzt ist. Aber wenn ich mir das recht überlege, woher sollte es null sein

    Ich probier es mal.
    mfG Henry

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

    ich habe noch ein wenig expirimentiert und habe es geschafft ersteinmal meine Impulsdauer in ms anzuzeigen. Da hatte ich die Variable falsch deklariert (statt int32_t als int).
    Das Prinzip funktioniert also schon einmal.

    Nun habe ich aber immer noch das Problem das meine blinkenden LED's durcheinander kommen.
    Es steht also nicht mehr das ganze Programm, sondern das blinken ist unregelmäßig (nicht so wie programmiert).
    Das möchte ich jetzt gern noch als nächstes lösen.

    Wo könnte da noch mein Fehler liegen, denn wie schon geschrieben, nur wegen dem einen Signal was ich auwerten möchte (lieber noch 1-2 andere zusätzlich) kann ja der µC noch nicht an der Leistungsgrenze sein.
    und sas lächerliche LED blinken ist mit Sicherheit auch nicht so rechenintensiv

    Hier noch einmal der Programmcode wie er jetzt ist:
    Code:
    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
    
      impuls = 0;
      
     sei(); //Interupts aktivieren
    
    while(1)
     {
     
     lcd_gotopos(1,1);
     lcd_writezahl(impuls,1,0);
    
    
     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;
      }  
      
    
    //****************************************************************************
      
      if (!(PIND & (1<<PIND5)))
      {
       PORTC &= ~(1<<PC5);
      }
     } //while
    
    } //ENDE main
    
    
    ISR(TIMER0_OVF_vect)
    //Interrupt bei Timer0 Overflow
    {
     Zaehler++;
    }
    
    
    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;  
         } 
    }
    Ich danke zwischendurch mal allen die mir hier schon mit Tips geholfen haben
    mfG Henry

  10. #20
    Erfahrener Benutzer Robotik Visionär Avatar von Hubert.G
    Registriert seit
    14.10.2006
    Ort
    Pasching OÖ
    Beiträge
    6.220
    Versuche es mal ohne LCD-Anzeige, wenn du darin hängst funktionieren zwar die ISR aber das andere nur mit verzögerung.

Seite 2 von 3 ErsteErste 123 LetzteLetzte

Berechtigungen

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

LiFePO4 Speicher Test