-         

Ergebnis 1 bis 6 von 6

Thema: Messung des Servopules mit mega328/20MHz über Timer1 läuft nicht

  1. #1
    Erfahrener Benutzer Robotik Visionär Avatar von oberallgeier
    Registriert seit
    01.09.2007
    Ort
    Oberallgäu
    Beiträge
    7.588

    Messung des Servopules mit mega328/20MHz über Timer1 läuft nicht

    Anzeige

    Bitte um Hilfe.

    Stand:
    Der Timer2 generiert mir den Heartbeat - einen 20 kHz-Interrupt bzw. 50µs, mit dem alle 20 000 Interrupts, also sekündlich, die Heartbeat-LED getoggelt wird. Dieser Timer (nicht jedes Mal Timer2) dient mir auch anderswo, z.B. bei Drehzahlen, für Zeitmessungen. Die Nutzung ist problemlos.
    Zum Auslesen eines Servopulses ist eine Genauigkeit von 50µs ungenügend, die Auflösung der Pulse, 1ms bis 2ms beträgt ja grad mal 200 bis 400 Schritte. Daher wurde eine Zeiterfassung direkt mit dem 16bittigen Timer1 geplant.

    Plan:
    Es wird der Timer1 zum Messen der Pulszeit benutzt. Initialisierung auf normal operation, TOP 0xFFFF, clk/1 = kein Prescaling.
    Die Pulse werden von einem PCINT0 am PIN PB5 eingelesen. Die entsprechend geschaltete LED zeigt mit Dimmgrad optisch die eingelesenen Servopulse eines potentiometergesteuerten Servotesters - funktioniert.
    Die Zeit vom Pulsstart bis zum Pulsende, PB5=hig bis PB5=low wird in der ISR von PCINT0 ausgelesen: bei Pulsanfang <=> PB5=high, wird OCR1A auf Null gesetzt, bei Pulsende <=> PB5=low, wird der Stand von OCR1A in eine Variablen tPULS (volatile int16/int16_t/ tPULS;x) übernommen. Die Variable tPULS ist aus Kompatibilitätsgründen signed integer.
    Zur Funktionskontrolle wird der Wert tPULS alle Sekunden über UART ausgegeben. Die betreffenden Codezeilen sind hier :

    Code:
    // ============================================================================= =
    // ===  Initialisierung v Timer1 mega328/20 MHz zur Messung Impulsdauer Servo
    //              Dokumentation ATmega328P_8271I_10/2014.pdf, siehe Seitenangaben
    // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
      void TC1TMR_init(void)        // Init Tmr/Cntr 1, 8-Bit auf 20 kHz = 50 µs
     {                            //
      TCCR1B    |= (1<<CS10);       // No Prescaler  Clock <- CPU               DOC 134
    //TCCR1B    |= (1<<WGM12);      // WGM00:13=0=> normal operation, TOP 0xFFFF   132
      TIMSK1    &= ~(1<<OCIE1A);    // Tmr/Cntr2 CompareA interrupt disabled
      TIMSK1    &= ~(1<<OCIE1B);    // Tmr/Cntr2 CompareB interrupt disabled
                                    //
     }              // Ende void TC1TMR_init(void)
    // ============================================================================= =

    Code:
    // ============================================================================= =
      ISR(PCINT0_vect)              // PCINT0 triggert bei ANY edge => bei PB5=high
     {                              //  Start der Messung, bei PB5=low Wert übernehmen
    // - - - - - - - - - - - - - - - -
      if ( (IsBitSet ( PINB, 5)))   // WENN der ServoPULS beginnt, dann OCR1A nullen
      {                             //
        OCR1A       =       0;      // Timer zurücksetzen
        SetBit ( PBLED, LBb );      // blLED an, PORTB, blLED auf PB2
      }                             // weiter mit if ( (IsBitSet ( PORTB, 5))
      else                  //
      {                             //
        tPULS       = OCR1A;        // Übernimm den Wert
        ClrBit ( PBLED, LBb );      // blLED aus, PORTB, blLED auf PB2
      }                     // Ende if/else ( (IsBitSet ( PINB, 5)))
                                    //
     }              // Ende ISR(PCINT0_vect)
    // ============================================================================= =

    Code:
    // ============================================================================= =
    // . . . .
      s16           wOCR1A;         // Wert von OCR1A zum Ausgeben, 16 Bit
    // . . . .
      while ( 1 )                   //
      {                             //
        wms ( 1000);                //
        cli(); wOCR1A = tPULS; sei();       // Wert des Servopulses auslesen
        uputs0 ("\r\tOCR1A ist aktuell "); uputs0i ( wOCR1A );
      }             // Ende   while ( 1 )
    // ============================================================================= =
    Aktuell:
    Der Stand von OCR1A/tPULS wird stets mit "0" ausgegeben, da funktioniert also keine Zeitmessung. Die LED zeigt durch die ISR(PCINT0_vect) die Potentiometerbewegung des Servotesters korrekt an (fade-in bzw. fade-out). Der Wert tPULS ist aus Kompatibilitätsgründen signed integer; ein Überlauf >32767 würde ja trotzdem per UART angezeigt

    Problem:
    Irgendwo steckt ein Programmierfehler, ich sehe den nicht. Oder stimmt die Timernutzung so nicht ?
    Danke im Voraus für die Hilfe
    Ciao sagt der JoeamBerg

  2. #2
    Erfahrener Benutzer Roboter Genie Avatar von Searcher
    Registriert seit
    07.06.2009
    Ort
    NRW
    Beiträge
    1.434
    Blog-Einträge
    104
    Wodurch wird denn OCR1A hochgezählt?

    Man könnte TCNT1 bei Pulsbeginn speichern und bei Pulsende die Differenz des aktuellen TCNT1 zum gespeicherten ausgeben.

    Gruß
    Searcher
    Hoffentlich liegt das Ziel auch am Weg
    ..................................................................Der Weg zu einigen meiner Konstruktionen

  3. #3
    Erfahrener Benutzer Robotik Visionär Avatar von oberallgeier
    Registriert seit
    01.09.2007
    Ort
    Oberallgäu
    Beiträge
    7.588
    Zitat Zitat von Searcher Beitrag anzeigen
    .. Wodurch wird denn OCR1A hochgezählt? .. Man könnte TCNT1 bei Pulsbeginn speichern ..
    Danke. Hols der Geier, steht ja klar in der Dokumentation, S. 114:
    Code:
    /* Read TCNT1 into i */
    i = TCNT1;
    Und ich D...ussel lese dauernd das OCR1A. Nun steht stattdessen TCNT1 . . und alles läuft bestens. Danke Searcher!
    Ciao sagt der JoeamBerg

  4. #4
    Erfahrener Benutzer Robotik Visionär Avatar von oberallgeier
    Registriert seit
    01.09.2007
    Ort
    Oberallgäu
    Beiträge
    7.588
    Zu allem Übel kann ich jetzt aber den Weg nicht mehr finden, wie dieses Thema als [Erledigt] markiert wird :-/
    Ciao sagt der JoeamBerg

  5. #5
    Erfahrener Benutzer Roboter Genie Avatar von Searcher
    Registriert seit
    07.06.2009
    Ort
    NRW
    Beiträge
    1.434
    Blog-Einträge
    104
    Hols der Geier ...
    nicht schlecht.

    Wen es einmal trifft ... Ganz oben, zwischen der Threadüberschrift mit "Thema:" und Deinem ersten Text gibt es eine Menüleiste unter anderem mit "Themen-Optionen". Aufklappen und unten sollte es die Auswahl "Markiere dieses Thema als erledigt ..." geben.

    Ob die Auswahl zur Verfügung steht scheint jedoch abhängig vom Forum zu sein, ob man eingeloggt ist oder nicht und eventuell weiteren Unbekannten.

    Gruß
    Searcher
    Hoffentlich liegt das Ziel auch am Weg
    ..................................................................Der Weg zu einigen meiner Konstruktionen

  6. #6
    Erfahrener Benutzer Robotik Visionär Avatar von oberallgeier
    Registriert seit
    01.09.2007
    Ort
    Oberallgäu
    Beiträge
    7.588
    .. Wen es einmal trifft .. Ob die Auswahl zur Verfügung steht scheint jedoch abhängig vom Forum zu sein .. und eventuell weiteren Unbekannten ..
    Genau. Ich habs eingeloggt probiert, als Gast, nicht eingeloggt, mit oder ohne Adblock, bei mir kommt unter [Themen-Optionen] (da hatte ich auch alle möglichen Forums-log-on-Versionen getestet) immer nur das Flyout
    Code:
    Druckbare Version zeigen
    Thema weiterempfehlen…
    Thema abonnieren…
    Egal, denn ansonsten ist diese Woche, diesen Monat, bei mir eher das Winner-Flag gesetzt *ggg*

    Trotzdem danke ich Dir.
    Ciao sagt der JoeamBerg

Ähnliche Themen

  1. [ERLEDIGT] I2C-Kommunikation läuft nicht über längere Zeit (Atmega644PA)
    Von addi241 im Forum C - Programmierung (GCC u.a.)
    Antworten: 6
    Letzter Beitrag: 06.08.2014, 21:06
  2. LCD an PCF8574 über I2C - 2*16 läuft / 4*20 LCD nicht?
    Von stfan1409 im Forum Basic-Programmierung (Bascom-Compiler)
    Antworten: 6
    Letzter Beitrag: 15.04.2012, 16:06
  3. Schrittmotor läuft nicht - L297/L298 über LTP
    Von TobiasBlome im Forum PC-, Pocket PC, Tablet PC, Smartphone oder Notebook
    Antworten: 4
    Letzter Beitrag: 14.02.2011, 17:17
  4. Temperaturmessung über I2C und LM75 läuft nicht
    Von michaelkoemm im Forum Basic-Programmierung (Bascom-Compiler)
    Antworten: 3
    Letzter Beitrag: 16.10.2007, 19:50
  5. Timer1 Läuft nicht richtig
    Von DeltaEx im Forum C - Programmierung (GCC u.a.)
    Antworten: 2
    Letzter Beitrag: 23.01.2006, 17:19

Berechtigungen

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