- 3D-Druck Einstieg und Tipps         
Ergebnis 1 bis 10 von 33

Thema: Unruhige Anzeige bei Drehzahlmesser für Zweitaktmotor

Hybrid-Darstellung

Vorheriger Beitrag Vorheriger Beitrag   Nächster Beitrag Nächster Beitrag
  1. #1
    Erfahrener Benutzer Robotik Einstein Avatar von Searcher
    Registriert seit
    07.06.2009
    Ort
    NRW
    Beiträge
    1.715
    Blog-Einträge
    133
    Tach Siro,

    Zitat Zitat von Siro Beitrag anzeigen
    Da Du anscheinend wenig RAM zur Verfügung hast, wäre ein Softwarefilter (Tiefpass) angebracht.
    Wenn ich meine, ohne mehr RAM geht es nicht, würde ich auch einen größeren µC nehmen. Ein bißchen betrachte ich es auch als Sport mit dem kleinen zurecht zu kommen. Deine Idee mit dem Tiefpaß hört sich gut an. Versuch ich auch mal umzusetzen und eventuel Dein Programm für mich umzuschreiben. Filter hab ich noch nicht gemacht. Danke!

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

  2. #2
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    07.03.2011
    Beiträge
    1.899
    Zitat Zitat von Searcher Beitrag anzeigen
    Filter hab ich noch nicht gemacht.
    Doch, sicher. Einen Buffer mit Messwerten füllen und daraus den Mittelwert bilden, ist ein Filter. Ich hatte in meinem vorigen Beitrag schon ein einfaches Tiefpassfilter angedeutet. Ich will das hier noch mal etwas ausführlicher beschreiben.

    Damit das folgende besser verständlich ist, erläutere ich hier mal die von mir verwendeten Begriffe. Erstens der Messwert. Dieses ist das ungefilterte Ergebnis einer Messung: ein ADC-Wert (Spannung), der Temperaturwert aus einem digitalen Sensor, die Messwerte aus einem Accelerometer oder Gyrosensor oder, wie hier, die Zeit aus einem Input Capture. Und zweitens der Anzeigewert. Dies ist der Wert nach dem Filter und hat die selbe Einheit und Skalierung wie der Messwert. Der Messwert wird regelmäßig ermittelt, hier im Capture-Interrupthandler. Es könnte genausogut ein ADC im Timerinterrupt sein.

    Die allgemeine Formel für einen Tiefpass ist: (neuer) Anzeigewert = k * (alter) Anzeigewert + (1 - k) * Messwert

    k ist ein Koeffizient zwischen 0 und 1. Da einmal mit k und einmal mit 1-k multipliziert wird, bleibt die Skalierung von Messwert und Anzeigewert gleich. Der neue Anzeigewert ist also ein gewichtetes Mittel aus dem alten Anzeigewert und dem aktuellen Messwert.

    Zur Abschätzung, was diese Formel bewirkt, kann man mal Extremwerte für k wählen: für k = 0 erhält man immer den aktuellen Messwert, das Filter hat keine Wirkung. Für k = 1 erhält man den Anzeigewert und der bleibt konstant. Zusammen mit der Frequenz, mit der die Messungen erfolgen, gibt k die Grenzfrequenz des Filters. Siro hat das dargestellt und ausgerechnet, ich kneife mir typisch die Rechnung und probiere einfach.

    Wie kann man die Rechnung eines solchen Filters für einen µC leicht gestalten? Nun man verwendet Intergermathematik. Damit kann man k im Bereich 0 - 1 aber nicht darstellen. Wenn ich die Formel aber so schreibe : (k * Anzeigewert + (k - 1) * Messwert) / 1, kann man diesen Bruch so erweitern, daß sich sowohl das erweiterte k als auch (erweitert) 1 - k als Integer darstellen lassen. Wenn ich dann auch noch mit einer Potenz von 2 erweitere, wird aus dem Teilen ein Rightshift. Ein besonders einfacher Fall egibt sich für k = 0,5: (Anzeigewert + Messwert)/2. Ähnlich einfach ist auch k = 0,75: (3 * Anzeigewert + Messwert) / 4. Wobei man für µC, die keine HW-Multiplikation haben auch (Anzeigewert + Anzeigewert + Anzeigewert + Messwert) / 4 schreiben kann. Wie man hier auch erkennen kann, tragen bei k = 0,75 die alten Messwerte stärker zum Ergebnis bei als der neue Wert. Die Grenzfrequenz liegt also tiefer.

    Da bei diesem Filter alle alten Messwerte (hier Anzeigewert genannt) zum neuen Wert beitragen, nennt man diese Filter IIR (Infinite Impulse Response). Infinite daher, weil jeder Messwert "für immer" mit im Anzeigewert steckt, jedoch entsprechend gering gewichtet. Wenn man im Gegensatz dazu auf einem Buffer rechnet, nennt man das ein FIR (Finite Impulse Response) Filter. Dabei kann der Buffer gleitend oder hintereinander gefüllt werden. Die Filtertypen haben unterschiedliche Eigenschaften. Ich zeig mal ein Bild, das ich aus dem Mikrocontroller.net Forum habe. Da hat Yalu X, der von digitaler Signalverarbeitung viel mehr Ahnung als ich hat, den Frequenzgang der beiden Filter mal geplottet.

    Klicke auf die Grafik für eine größere Ansicht

Name:	iir-gm-tiefpass.png
Hits:	2
Größe:	34,9 KB
ID:	34208

    In der roten Kurve erkennt man den klassischen Tiefpass, das IIR Filter. Den gleitenden Mittelwert (grüne Kurve) benutzt man gerne, um feste Störfrequenzen wie 50Hz auszublenden. Man dimensioniert es dann mit Bufferlänge und Samplingrate so, daß z.B. das erste Minimum auf diese 50Hz fällt und diese Störsignal nur sehr gering zum Ergebnis beiträgt. Da ein solcher Fall hier nicht vorliegt, sind die aufwändigere Rechnung und der größere Speicher für ein FIR nicht nötig.

    Mit der Anzeige der Messwerte hat das nichts zu tun. Wenn die serielle Ausgabe kürzer ist, als die Zeit zwischen zwei Capture-Interrupts, wie du berechnet hast, kann die Ausgabe aus dem Capture-Interrupt selbst erfolgen. Das vermeidet jeglichen Konflikt. Da der Mensch nicht mehr als ca. 5 Werte pro Sekunde wirklich erfassen kann, muß man die Anzeige nicht bei jedem Interrupt updaten.

    MfG Klebwax

    P.S. irgendwie ist das Bild nicht angekommen, versuche es nochmal
    Geändert von Klebwax (09.06.2019 um 10:19 Uhr)
    Strom fließt auch durch krumme Drähte !

  3. #3
    Erfahrener Benutzer Robotik Einstein Avatar von wkrug
    Registriert seit
    17.08.2006
    Ort
    Dietfurt
    Beiträge
    2.242
    Da die Impulsaufnahme anscheinend gut funktioniert geht es nun an die Auswertung.
    Tiefpassfilterung hast Du ja im Prinzip schon gemacht.

    Ich würde die Refreshrate auf 3 neue Anzeigen / Sekunde ändern bzw. umschaltbar machen.
    Das gibt dann noch eine "lesbare" Anzeige und ist trotzdem "schnell".

    Ich bin hier bestimmt nicht der große Mathematiker vor dem Herrn, aber für solche Aufgaben wird immer wieder gerne mal das Kalman Filter empfohlen.
    Ich hab mich da früher schon mal reingelesen, konnte es aber nicht anwenden, da ich die Varianz der Messwerte nicht bestimmen konnte.

    https://www.cbcity.de/das-kalman-fil...rklaert-teil-1
    https://www.cbcity.de/das-kalman-fil...rklaert-teil-2
    https://www.cbcity.de/das-extended-k...nfach-erklaert

    Das ist bei Dir durch deine Messreihen anders.
    Eventuell kann Dir jemand, der in Mathe besser drauf ist, mal gucken ob das hier funktionieren würde?!

    Ich meine auch, anhand Deiner Messreihen, das dein Verfahren innerhalb einer festen Messperiode die Impulse zu verarbeiten zu der genauesten Messung führen wird.
    Allerdings ist dadurch die Anzahl der Messwerte variabel und wird zu höheren Drehzahlen hin weniger.
    Ich hab das früher mal so gelöst, das Ich ab einer bestimmten Drehzahl auf die Impulszählung mit fester Torzeit umgeschaltet habe.
    Denn wenn die Pin Change Werte zu klein werden steigen die Rundungsfehler massiv an und eine Torzeitmessung bringt dann genauere Ergebnisse.

    So hab's Ich gemacht:
    Im ersten Moment werden dabei die Impulse pro fester Zeiteinheit ermittelt.
    Sind die zu gering wird auf Impulsdauermessung ( das Verfahren, das Du jetzt benutzt ) umgeschaltet.
    Bei mir war das Nötig, weil Ich an mehrblättrigen Propellern mit Drehzahlen bis 20000 U/min messen wollte und Ich deshalb stellenweise 4 Impulse pro Umdrehung bekommen habe.
    Da kam dann der Pinchange Interrupt nicht mehr mit, außerdem waren da ja noch die Rundungsfehler!

  4. #4
    Erfahrener Benutzer Robotik Einstein Avatar von Searcher
    Registriert seit
    07.06.2009
    Ort
    NRW
    Beiträge
    1.715
    Blog-Einträge
    133
    Zitat Zitat von wkrug Beitrag anzeigen
    ... wird immer wieder gerne mal das Kalman Filter empfohlen.
    Uff, ich hoffte, der Kelch wird an mir vorbeigehen Ich wollte doch nur die Zweitakter einstellen

    Für den Drehzahlmesser möchte ich jetzt erst wieder klein weiter machen und mal sehen wie die Grafik mit der von Klebwax erwähnten Methode aussieht. Die, die zwei Meßwerte addiert und durch zwei teilt und dann zum Ergebnis den nächsten Meßwert addiert und wieder durch zwei teilt usw.

    Das ist für mich überschaubar und danach geht es weiter ...

    Zu allererst muß aber ein Simulator her, also ein Impulsgeber, der anstelle der CD4093 Schaltung mit angehängter Motorsäge die Rechteckimpulse zum ICP Eingang gibt. Dazu sollte ein ATmega88, der hier tatenlos rumschlummert, in der Lage sein.

    Kostet mich sonst zuviel Sprit, verpestet unnötig die Luft und immer Gehörschutz aufsetzen ist auch noch lästig.

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

  5. #5
    Erfahrener Benutzer Robotik Einstein Avatar von wkrug
    Registriert seit
    17.08.2006
    Ort
    Dietfurt
    Beiträge
    2.242
    Uff, ich hoffte, der Kelch wird an mir vorbeigehen. Ich wollte doch nur die Zweitakter einstellen.
    ... na ja, wenn dann aber mit der Qualität der Messergebnisse nicht zufieden ist muss man da halt eben doch ran!

    Und wie Du in deiner Signatur schreibst:
    Hoffentlich liegt das Ziel auch am Weg

  6. #6
    Erfahrener Benutzer Robotik Einstein Avatar von Searcher
    Registriert seit
    07.06.2009
    Ort
    NRW
    Beiträge
    1.715
    Blog-Einträge
    133
    Zitat Zitat von wkrug Beitrag anzeigen
    Und wie Du in deiner Signatur schreibst:
    Hoffentlich liegt das Ziel auch am Weg
    ______________________________________



    Jetzt habe ich schon mal einen Simulator gebastelt um die Zündimpulse nachzubilden. Ist ein ATmega88pa auf dem folgendes Programm läuft.
    Code:
    $regfile = "m88pdef.dat"
    $framesize = 32
    $swstack = 32
    $hwstack = 38
    $crystal = 8000000
    $baud = 57600
    
    
    Const Sample_count = 256                                    'number of samples to take
    
    Dim Icr_old As Word
    Dim Icr_new As Word
    
    Dim Ignition_seq As Word
    Dim Ignition_seq_old As Word
    Dim Ocr1a_calc As Word
    
    Dim Idx As Word
    Dim Firing_interval(sample_count) As Word
    Dim Intervals(sample_count) As Eram Word                    'EEPROM variable
    
    Dim Flag_rec_complete As Byte
    Dim Flag_playback_running As Byte
    Dim Flag_icp_dead As Byte                                   'indicates no pulses at ICP1 pin while recording
    
    Config Portb.pb1 = Output                                   'OC1A pulse output
    Config Portc.pc5 = Output                                   'green playback led
    Config Portc.pc4 = Output                                   'red record led
    
    Config Portd.pd5 = Output                                   'red led for playback
    
    Portd.pd6 = 1                                               'pullup for "playback" button
    Portd.pd7 = 1                                               'pullup for "start record" button
    Portb.pb0 = 1                                               'pullup icp1 pin - stable level
    
    On Timer1 Check_icp_alive
    On Icp1 Isr_get_icr                                         'icp interrupt vector
    On Compare1a Isr_send_pulses
    
    Enable Interrupts
    
    Print "Simulator start"
    
    
    
    Do
      Debounce Pind.pd7 , 0 , Start_record , Sub                'record ignition intervals
      Debounce Pind.pd6 , 0 , Play_intervals , Sub              'start - stop playback
      If Flag_rec_complete = 1 Then
          For Idx = 1 To Sample_count
            Intervals(idx) = Firing_interval(idx)               'copy sram variable to eeprom variable
          Next
          Print "samples copied to eram"
          Flag_rec_complete = 0
          Portc.pc4 = 0
          Tccr1b = 0
      End If
      If Flag_icp_dead = 1 Then Gosub No_record
    Loop
    
    Start_record:
      Tccr1a = 0                                                'init timer1
      Tcnt1 = 0
      Ignition_seq = 0
      Flag_rec_complete = 0
      Tifr1.tov1 = 1
      Enable Timer1                                             'enable timer1 overflow interrupt
      Icr_old = Icr1
      Enable Icp1
      Tccr1b = Bits(cs11 , Ices1)                               'prescaler=8 timer1 clocked with 1MHz
      Portc.pc4 = 1                                             'rec LED on
    Return
    
    
    No_record:
      Disable Icp1
      Tccr1b = 0                                                'stop timer1
      Print "No pulses on ICP pin"
      Portc.pc4 = 0
      Flag_icp_dead = 0
    Return
    
    
    Play_intervals:
      If Flag_playback_running = 1 Then                         'button operated and playback running -> stop playback
          Disable Compare1a
          Tccr1b = 0                                            'stop timer1
          Flag_playback_running = 0
          Portc.pc5 = 0
        Else
          For Idx = 1 To Sample_count
            Firing_interval(idx) = Intervals(idx)               'copy eeprom variable to sram variable
          Next
          Ignition_seq = 1
          Ocr1a = Firing_interval(ignition_seq)
          Print Ignition_seq ; "   " ; Firing_interval(ignition_seq)
          Tccr1a = Bits(com1a0)                                 'toggle oc1a on ocr1a compare match
          Tcnt1 = 0
          Tifr1.ocf1a = 1                                       'clear eventually set compare1a flag
          Enable Compare1a
          Tccr1b = Bits(cs11)                                   'start timer1, presacaler = 8
          Flag_playback_running = 1                             'green playback led on
          Portc.pc5 = 1
      End If
    Return
    
    Isr_send_pulses:
      If Pinb.pb1 = 1 Then                                      'if pin is high make pulse length
          Ocr1a = Ocr1a + 4000                                  'pulse length 4ms
        Else                                                    'else make time until next ignition
          Incr Ignition_seq
          Ocr1a_calc = Firing_interval(ignition_seq) - 4000
          Ocr1a = Ocr1a + Ocr1a_calc
          Print Ignition_seq ; "   " ; Firing_interval(ignition_seq)       'visualise time in termial
      End If
      If Ignition_seq >= Sample_count Then Ignition_seq = Rnd(sample_count)       'continue playback with random start    '
    Return
    
    Isr_get_icr:
      Incr Ignition_seq
      Icr_new = Icr1
      If Icr_old = 0 And Ignition_seq = 1 Then
          Ignition_seq = 0
        Else
          Firing_interval(ignition_seq) = Icr_new - Icr_old
      End If
      Icr_old = Icr_new
      If Ignition_seq >= Sample_count Then
        Disable Icp1
        Tccr1b = 0                                              'init, stop timer1
        Flag_rec_complete = 1
        Ignition_seq = 0
      End If
    Return
    
    Check_icp_alive:
      If Ignition_seq_old = Ignition_seq Then
          Flag_icp_dead = 1
        Else
          Ignition_seq_old = Ignition_seq
      End If
    Return
    Das Programm kann 256 Zündimpulsabstände (limitiert durch die Größe des internen EEROMs mit 512Byte), die von der CD4093B Schaltung kommen können, aufzeichnen. Gemessen wie gehabt mit der Input Capture Funktion in µs Auflösung.

    Abspielen der Impulse geschieht über den OC1A Pin. Die Impulslänge ist auf 4ms eingestellt, ähnlich wie in der CD4093B Schaltung.

    Es gibt eine "Record" Taste, die die Aufzeichnung der 256 Werte startet und die rote Rec-LED einschaltet. Die ICR Daten werden erst in einem Array im RAM abgelegt. Ist das Array voll, wird es in den internen EEPROM geschrieben. Das Ende der Aufzeichnung wird durch das Erlöschen der Rec-LED angezeigt.

    Über die "Playback" Taste werden die Impulse über den OC1A Pin elektrisch nachgebildet und der Impulsabstand in µs als Zahl auch über RS232 ausgegeben. Eine grüne LED leuchtet während des Abspielens. Nachdem der letzte Wert aus dem Speicherarray abgespielt wurde, wird eine Zufallszahl erzeugt, die als Index für ein Element aus dem Array als Startelement dient um wieder die restlichen Werte der Reihe nach aus dem Array auszugeben. Nochmaliges Drücken der Playback stoppt das Abspielen.

    Im Anhang noch 256 Zündimpulsabstände (Einheit = µs) mit Ordnungsnummer, die bei noch kalter Maschine über etwa 5 Sekunden aufgezeichnet wurden. In einem Graph dargestellt ergab sich ein echt unerwartet interessantes Bild

    Gruß
    Searcher
    Angehängte Dateien Angehängte Dateien
    Geändert von Searcher (11.06.2019 um 10:46 Uhr) Grund: PRG berichtigt: 4ms Pulslänge verrechnet
    Hoffentlich liegt das Ziel auch am Weg
    ..................................................................Der Weg zu einigen meiner Konstruktionen

  7. #7
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    07.03.2011
    Beiträge
    1.899
    Zitat Zitat von Searcher Beitrag anzeigen
    Im Anhang noch 256 Zündimpulsabstände (Einheit = µs) mit Ordnungsnummer, die bei noch kalter Maschine über etwa 5 Sekunden aufgezeichnet wurden. In einem Graph dargestellt ergab sich ein echt unerwartet interessantes Bild
    Das ist tatsächlich interessant. Das könnte sowohl aus der Messung kommen als auch einen Effekt des Motors (läuft unrund) darstellen.

    Leider sind in der Tabelle die schon verrechneten Werte. Schöner wäre es gewesen, wenn du einfach die Werte des Capture Register aufgezeichnet hättest. Die Differenz, die Zeit kann man auf dem PC leicht daraus berechnen und man könnte sehen, wann ein Overflow auftritt und ob er einen Einluß hat (ich vermute mal nicht, aber sicher ist sicher). Man könnte dann auch die Messwerte über der Zeitachse zeigen. Alle Rechnungen eingeschlossen den Tiefpass kann an dann am PC z.B. mit Excel machen ohne den Motor anzuwerfen. Da kann man auch alle Berechnungen in float machen und Probleme mit Overflow oder Underflow vermeiden. Dann kann man später entscheiden, ob man für den µC auf Integer umsteigt und wie man dafür die Formeln aufbaut, um das zu vermeiden.

    MfG Klebwax
    Strom fließt auch durch krumme Drähte !

Ähnliche Themen

  1. Drehzahlmesser
    Von -Hurricane- im Forum Basic-Programmierung (Bascom-Compiler)
    Antworten: 2
    Letzter Beitrag: 18.08.2014, 22:33
  2. Drehzahlmesser
    Von highcom im Forum Elektronik
    Antworten: 4
    Letzter Beitrag: 05.05.2010, 10:58
  3. Drehzahlmesser
    Von vohopri im Forum Vorstellungen+Bilder von fertigen Projekten/Bots
    Antworten: 24
    Letzter Beitrag: 14.03.2010, 08:08
  4. Drehzahlmesser
    Von derdaswar im Forum Controller- und Roboterboards von Conrad.de
    Antworten: 10
    Letzter Beitrag: 17.07.2009, 16:45
  5. Drehzahlmesser
    Von TheHawk im Forum Elektronik
    Antworten: 13
    Letzter Beitrag: 14.12.2007, 20:04

Berechtigungen

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

12V Akku bauen