-
        

Seite 1 von 2 12 LetzteLetzte
Ergebnis 1 bis 10 von 19

Thema: Umdrehungsmessung mit Timer

  1. #1
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    05.01.2004
    Alter
    29
    Beiträge
    121

    Umdrehungsmessung mit Timer

    Anzeige

    SMARTPHONES & TABLETS-bis zu 77% RABATT-Kostenlose Lieferung-Aktuell | Cool | Unentbehrlich
    Hallo, ich weiß es gibt hier schon viele Threads zu diesem Thema aber ich werd daraus irgendwie nicht schlau.
    Ich habe einen Taster an einer Drehenden Achse, der jede Umdrehung einen Impuls gibt. Jetzt möchte ich eigentlich nur wissen wieviele Impulse es in einer bestimmten Zeit gibt. Die Impulse zähle ich mit einer Schleife, ohne Interrupts da die Drehzahl sehr gering ist. Nun bräuchte ich eine Sub Routine die immer nach einer bestimmten Zeit (jede Sekunde würde schon reichen) aufgerufen wird, die Umdrehungen speichert und wieder auf Null setzt. Aber wie mache ich das mit dem Timer?
    Hab mit den Timern jetzt schon viel rumprobiert aber irgendwie funktioniert das bisher noch nicht...
    Kann mir da bitte nochmal jemand helfen?

  2. #2
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    01.03.2004
    Ort
    Bielefeld (JA, das gibt es!)
    Alter
    29
    Beiträge
    1.614
    was hastn fürn quarz???

    Martin

    (dieser Text steht hier wegen den 30 Zeichen min.)
    Ich will Microsoft wirklich nicht zerstören. Das wird nur ein gänzlich unbeabsichtigter Nebeneffekt sein.
    Linus Torvalds, Entwickler von Linux

  3. #3
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    09.06.2004
    Ort
    Aachen
    Beiträge
    2.674
    Also um genau zu sein, brauchst du nur einen Timer, der jede Sekunde einen Interrupt auslöst, oder?
    In der Interruptroutine wird dann der zuvor gespeicherte Wert bearbeitet, wie, dass ist dann deine Aufgabe. Hier mal ein wenig Code von mir:

    Code:
    $regfile = "m8def.dat"
    $crystal = 8000000
    Dim Zaehlerstand As Byte                                    '255 Werte in der Sec. sollte nicht überschritten werden, ansonsten eine Word-varaible verwenden oder so.
    Const Timervorgabe = 34286                                  '65536-31250 = 34286
    Config Timer1 = Timer , Prescale = 256
    On Timer1 Timer1_isr
    Timer1 = Timervorgabe
    Enable Timer1
    Enable Interrupts
    
    Do
    'Bestimmung von Zaehlerstand (deine Aufgabe ;-) )
    Loop
    
    End
    
    Timer1_isr:
    Timer1 = Timervorgabe
    'Hier passiert jetzt was mit deinem Zaehlerstand
    Zaehlerstand = 0
    Return
    Der Code ist schon getestet, da ich weder weiß, welchen Controller du verwendest, noch wie dein uC getaktet ist, überlasse ich dann die anpassung der Werte dir, oder du sagst mir halt, wie es aussieht.

    MFG Moritz

  4. #4
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    05.01.2004
    Alter
    29
    Beiträge
    121
    Danke, genau das meinte ich RCO. Sorry das ich das vergessen hab ich benutzen einen Mega32 der mit 16Mhz getaktet ist.
    Das Prescale bestimmt doch nach wievielen Takten der Timer ausgelöst werden soll, oder?
    Den Code hab ich soweit verstanden bis auf diese Rechnung:
    Const Timervorgabe = 34286 '65536-31250 = 34286
    Die Timervorgabe legt den Startwert des Timers fest, 31250 mal würde der Timerinterrupt in einer Sekunde ausgelöst bei einem Prescale von 256, aber wo kommen die 65536 her?
    Also: Wie müste das bei 16Mhz aussehen ?

  5. #5
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    01.03.2004
    Ort
    Bielefeld (JA, das gibt es!)
    Alter
    29
    Beiträge
    1.614
    $regfile = "m32def.dat"
    $crystal = 16000000

    Config Timer1 = Timer, Prescale = 256
    On Timer1 Timer_irq
    Const Timervorgabe = 3036

    Enable Timer1
    Enable Interrupts

    Do
    'Dein Part
    Loop

    Timer_irq:
    Timer1 = Timervorgabe
    Return
    Ich will Microsoft wirklich nicht zerstören. Das wird nur ein gänzlich unbeabsichtigter Nebeneffekt sein.
    Linus Torvalds, Entwickler von Linux

  6. #6
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    09.06.2004
    Ort
    Aachen
    Beiträge
    2.674
    Ja, also der Timer ist eingentlich ein Counter hört sich zwar blöd an, ist aber so, deshalb spricht man oft von "Timer/Counter".

    Er zählt alle Takt/Prescaler +1, Timer1 ist also selber eine Variable, die immer erhöht wird. wenn Timer 1 voll ist, bzw. überläuft, dass heißt den Wert 2^16 erreicht (16-Bit Timer) löst er einen Interrupt aus. Unser Ziel ist es jetzt, dass der Timer immer genau jede Sekunde überläuft.

    Wenn wir den Timer mit 34286 vorladen, bleiben 31250 Impulse des Prescalers, bis der Timer überläuft.
    31250 entspricht in unserem Fall:
    8000000 [Takt meines uCs] / 256 [Prescaler]
    Also genau einer Sekunde.
    Ziehen wir nun von dem Überlaufwert den Wert für eine Sekunde ab, läuft der Timer1 genau jede Sekunde über, dann sollten wir ihn natürlich möglichst schnell wieder beladen, damit keine Fehler entseht.

    In deinem fall würde ich einen größeren Prescaler nehmen (1024) weil der uC dann etwas entlastet wird. (Ich habe 256 gewählt, weil ich mit 1024 auf eine Komma-Zahl kam)
    Mit 16000000/1024 kommen wir auf 15625. Nun Muss Timervorgabe
    2^16-15625 sein, also 49911.

    Alles klar?

    Müsste mit Timervorgabe 49911 und Prescaler 1024 bei 16 Mhz genau auf eine Sekunde kommen. Kannst ja mal eine Diode toggeln, um es zu prüfen.

    Natürlich entstehen aufgrund von Quarzungenauigkeiten etc. immer Fehler, aber da es sich ja nciht um eine Langzeituhr handelt, sollte das kein Problem sein. Bei anderen sind schonmal auf einen Tag einige Sekunden Differenz entsatnden, kannste ja runterrechnen.

    Noch fragen?

    MFG Moritz

  7. #7
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    05.01.2004
    Alter
    29
    Beiträge
    121
    Vielen Dank für die erklärung. Hab wie du sagtest eine Led damit getriggered und es funktioniert Allerdings ist der Timer mit einem Anfangswert von 4991 ungefähr auf 3, 4 Sekunden eingestellt. 16 bit sind nämlich 2^17 und nich 2^16 . Also wär der richtige Startwert 115447, mit dem blinkt die Led jetzt im 1 Sekundentakt.

  8. #8
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    05.01.2004
    Alter
    29
    Beiträge
    121
    Könnte ich das dann auch mit Timer0 machen? Der Timer1 wird ja beim RN-Control Board für die Motorensteuerung benutzt und ich will die Drehzahl dieser Motoren messen.
    Der Timer0 ist ja ein 8Bit Counter. 2^9 sind ja bloß 512 da würde ich auf einen Startwert von -15113 kommen, funktioniert aber leider nicht

  9. #9
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    09.06.2004
    Ort
    Aachen
    Beiträge
    2.674
    16 bit sind nämlich 2^17 und nich 2^16
    Das ist mir neu, bis jetzt waren 16 Bit bei mir immer 65536!
    Ein Bit hat ja auch nur 2^1 also 2 und nicht 2^2 also 4 Zustände.

    4991
    Wie kommst du nun jetzt auf diesen Wert? Ich hab doch 49911 geschrieben.

    ungefähr auf 3, 4 Sekunden eingestellt
    Ja mit 4991 kommt man auf 3,1306 sec.

    Aber mit 49911 Meiner Meinung nach immer noch auf 1.

    Schön, wenn es läuft, mir allerdings total unverständlich.

    MFG Moritz

    EDIT: könnte es sein, dass 4991 tatsächlich nicht nur ein Schreibfehler war?

    Denn: wenn du sagst, das du 2^17 verwendet schreibst du ja in ein 17 nicht mehr in dieser Variable existierendes Bi und schreibst somit also nur 49911 in die Varaible. Was dann meinem Wert entsprechen würde

    MFG Moritz

  10. #10
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    05.01.2004
    Alter
    29
    Beiträge
    121
    Hmmm, naja ka es ging jedenfalls lol. Die größte Zahl die man mit 16Bits darstellen kann ist doch 2^17 dachte ich? So haben wir das jedenfalls gelernt lmao. Das 16. Bit ist ja für 2^16, aber wenn man alle anderen Bits auchnoch setzt hat man ja insgesamt 2^17 (2^1+2^2+2^3+2^4....+2^16).
    Weiß nich ob das damit zusammenhängt habs auch nur ausprobiert. Kann gut sein das ich mich verschrieben hatte, bin jetzt allerdings auf Timer2 umgestiegen der nur 8Bit hat also kann ich das jetzt leider nicht so schnell ausprobieren.

    Frag mich allerdings immernoch wie man das nun mit einem 8Bit Timer macht. Ich fange jetzt bei 0 an, da er leider nicht im negativen anfangen kann lol. Da heißt er läuft 30,51 mal in der Sekunde über. Da das viel zu schnell wäre schalte ich die Lampe nur jedes 31. mal an bzw. aus damit ich wieder auf ~1 sek kommen. Aber irgendwie ist das ein bisschen aufwändig lol. Geht das auch irgendwie besser?

Seite 1 von 2 12 LetzteLetzte

Berechtigungen

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