PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Unruhige Anzeige bei Drehzahlmesser für Zweitaktmotor



Searcher
03.06.2019, 08:45
Hallo,

ich habe eine Motorsense und eine Motorsäge. Beide mit einem Zweitakt Benzinmotor angetrieben. Die sind schon in die Jahre gekommen und nach einem Membran- und Dichtungstausch im Vergaser möchte ich die nun wieder einstellen bzw Einstellung kontrollieren.

Das geht für den Leerlauf indem man mit der L Schraube auf maximale Drehzahl im Leerlauf einstellt und dann das Gemisch noch eine Idee fetter einstellt. Mit Standgasschraube die Drehzahl senken bis auskuppeln plus Sicherheitsabstand. Problem ist die Maximaldrehzahl bei Vollgas richtig einzustellen. Dazu bräuchte man eigentlich einen Drehzahlmesser. Die sind heute gar nicht mehr so teuer aber warum nicht selber bauen?

Im Mikrocontroller.net fand ich eine Schaltung zur einfachen Zündimpulsabnahme mit einem Draht vom Zündkabel: https://www.mikrocontroller.net/topic/81838#685809

Nachgebaut (27k an Pin 12 gegen 47k getauscht und um eine Zenerdiode an Pin 8 erweitert -> mein Meßbereich damit 1000Upm bis ca. 17000Upm - 2700min bis 13500max benötigt) und zur Berechnung der Drehzahl einen ATtiny2313 über einen 1k Widerstand an Pin 3 des (TC)4093 angschlossen. Es soll später noch eine Siebensegmentanzeige angeschlossen werden. In der Testphase sende ich die gemessene Drehzahl über RS232 an einen PC.

Funktioniert soweit ABER die gemessenen Werte schwanken doch relativ stark um den angepeilten einzustellenden Wert. Bei einer neuen Maschine, noch vom Werk eingestellt auf hoffentlich auf 2700Upm messe ich zB 2500 bis 3100Upm. Das ist mir deutlich zu unruhig und kann damit keine befriedigende Einstellung vornehmen.

Blauäugig hatte ich zunächst per ICP mit dem, mit 1MHz laufenden 16Bit Timer die Zeit zwischen den Zündimpulsen auf 1µs genau gemessen, Drehzahl auf eine Minute hochgerechnet (Upm=60000000/Meßwert in µs) und die zur Displayupdatezeit (jede 1/2 Sekunde) den gerade aktuellen Wert angezeigt: Sehr, sehr unruhige Anzeige :-(

Nach ein paar Versuchen die angezeigte Drehzahl ruhiger zu bekommen, zB auch mit Zählung der Zündimpulse innerhalb einer feste Torzeit von zB einer Sekunde, bin ich nun bei folgender Lösung angelangt:
Displayupdate von etwas über einer Sekunde. Innerhalb dieser Sekunde werden die Zeiten zwischen den Zündimpulsen per ICP gemessen und aufaddiert. Mit der Anzahl der aufgetretenen ICP-Interrupts (Anzahl der Zünimpulse) wird dann der einfache Mittelwert ausgerechnet und zu Anzeige gebracht. Zu Beginn des nächsten Anzeigeintervalls sind alle Meßwerte gelöscht und es beginnt eine komplett neue Drehzahlmessung und Berechnung. Probeweise ist da noch eine SW-Hysterese aktiv, die eine veränderte Drehzahl von einer zur anderen Sekunde nur anzeigt, wenn sich der Wert um 10Upm gegenüber der vorherigen geändert hat.

Das Ganze ist mir aber immer noch zu unruhig. Nach vielen Versuchen mit der Abnahme des Zündimpulses würde ich ein Problem dort fast ausschließen. Timingfehler im Programm auch, da mit Frequenzgenerator überprüft und dort im Bereich von 1000Upm bis 16000Upm stabile Werte angezeigt werden. Die Motoren laufen im Leerlauf leicht unruhig (mit Oszi den Zündimpuls beobachtet) und mit der Messung über Sekundenintervalle auf Umdrehungen pro Minute umzurechnen erkläre ich mir die unruhige Anzeige des Drehzahlmessers.

So, Luftholen für die Fragen nach dem vielen Text:
Wie krieg ich eine ruhige aber doch aktuelle Anzeige für eine Vergasereinstellung hin? Wie wird das bei den professionellen Drehzahlmessern gemacht? Wird da einfach über einen größeren Zeitraum gemittelt und/oder Ausreißer ignoriert? Hat jemand konkrete Werte dazu?

Gruß
Searcher

gegenwärtiges Testprogramm:

$regfile = "ATtiny2313.DAT"
$framesize = 24
$swstack = 24
$hwstack = 34
$crystal = 8000000
$baud = 57600
$lib "mcsbyteint.lbx"

Dim Icr_new As Word
Dim Icr_old As Word
Dim Icr_difference As Word
Dim Upmd As Dword
Dim Upm As Word
Dim Tov_count As Byte
Dim Accumul_difference As Dword
Dim Averaged_ign_time As Dword
Dim Icp_events As Word
Dim Icp_alive As Byte
Dim Upm_o As Word 'Upm old
Dim Upm_h As Integer 'Upm Hysteresis

Print "Drehzahlmessung Upm"

Tccr1b = Bits(cs11 , Ices1) 'prescaler = 8, 1µs timer steps, icp event on rising edge

On Timer1 Update_display 'timer1 overflow
Enable Timer1

On Icp1 Get_icr 'ignition spark occured
Enable Icp1

Enable Interrupts

Do
Loop

Get_icr:
Icr_new = Icr1
Icr_difference = Icr_new - Icr_old
Icr_old = Icr_new
Accumul_difference = Accumul_difference + Icr_difference
Incr Icp_events
Icp_alive = 1
Return

Update_display:
Incr Tov_count
If Tov_count = 15 Then '15 makes about 1s display interval
Averaged_ign_time = Accumul_difference / Icp_events
Upmd = 60000000 / Averaged_ign_time 'Icr_difference
Upm_h = Upmd - Upm_o
If Abs(upm_h) > 10 Then 'SW-hysteresis
Upm_o = Upmd
If Icp_alive = 0 Then Upm_o = 0 'no ignition detected -> Upm=0
Print " " ; Chr(13) ; Upm_o ; Chr(13);
End If
Accumul_difference = 0
Tov_count = 0
Icp_events = 0
Icp_alive = 0
End If
Return

witkatz
03.06.2019, 19:58
Ich stelle mal eine Vermutung an.
Kann es sein, dass sich die beiden Interruptroutinen für Timer1 und Icp1 gegenseitig stören? Das Get_icr muss für exakte Messung auch immer die selbe Latenzzeit haben und darf nicht auf irgendwelche Display-Updates mit und Drehzahlberechnungen warten müssen.

Searcher
03.06.2019, 22:01
Kann es sein, dass sich die beiden Interruptroutinen für Timer1 und Icp1 gegenseitig stören

Hallo,
danke fürs Anschauen. Daß sich die Interrupts in die Quere kommen würde ich ausschließen. Ich weiß, daß es verpönt ist, Print-Ausgaben in einer ISR zu machen da eine ISR so schnell wie möglich gemacht werden soll. Bin das Risiko aber kalkuliert eingegangen und kann das später noch korrigieren. Der Tiny hat wenig SRAM und beim Programmieren hatte ich zwischendurch OUT OF SRAM Probleme wegen zu vieler zu großer Variablen beim Print in der Hauptschleife. Ist halt noch ein Testprogramm.

Bei vielen AVR, hier beim ATtiny2313 gibt es ein eigenes 16Bit ICR Register (Input Capture Register). Dort wird bei Auftreten eines Pegelwechsels am ICP Pin der Timerstand des 16Bit TIMER1 hineinkopiert. Gleichzeitig wird ein Interruptflag für den ICP Interrupt gesetzt. Ob die ISR zum ICR Register sichern sofort oder etwas später ausgeführt wird ist egal, da der Timerwert im ICR vorerst sicher ist. Die ISR muß jedoch vor dem nächsten Input Capture Event durchgeführt werden, da das ICR dann überschrieben wird. Bei PICs gibt es vermutlich Ähnliches.

Ich habe gerade nochmal die "Update_display" ISR im Simulator laufen lassen. Braucht 0,18075ms (1446 Zyklen). Die angepeilte, maximal zu messenden Drehzahl von 16-, 17000Upm entspricht einer Capture Frequenz von 17000/60=ca. 284Hz. 284Hz haben eine Periodendauer von 1/284=ca.3,5ms. Bei der höchsten zu messenden Umdrehungszahl bleiben also noch 3,5ms minus 0,18075ms = reichlich Luft. Ich weiß nicht, ob der Simulator das Senden der Zeichen mit dem Print richtig berechnet. Wenn 12 Zeichen (5 Leerzeichen, max. 5 Ziffern des Meßwertes und die beiden CR) mit 57600 Baud gesendet werden dauert das ca. 2ms. Plus der 0,18075ms Rechenzeit bleiben bis zu den 3,5ms immer noch reichlich "Luft". Bei den Messungen im Leerlauf der Motorsäge bei um die 2700Upm (45Hz Capture Frequenz) also noch gar kein Thema falls ich nicht doch etwas übersehen habe. Mit Testfrequenzen über Generator gibt es in der Hinsicht auch kein Problem.

Gruß
Searcher

wkrug
04.06.2019, 06:47
Leg doch einfach mal an den Eingang deiner Schaltung einen Frequenzgenerator an.
Wenn dann die Verhältnisse stabil sind werden eventuell über deinen Abgriff aus der Zündspule Fehlimpulse mitgezählt.
Irgendwo müsste in deiner Schaltung wohl auch eine Art Schmitt Trigger zu finden sein.
Die Impulse dahinter sollten sauber und gleichmässig sein ( Bei konstanter Drehzahl ).

Klebwax
04.06.2019, 09:03
Im Mikrocontroller.net fand ich eine Schaltung zur einfachen Zündimpulsabnahme mit einem Draht vom Zündkabel: https://www.mikrocontroller.net/topic/81838#685809

Nachgebaut (27k an Pin 12 gegen 47k getauscht und um eine Zenerdiode an Pin 8 erweitert -> mein Meßbereich damit 1000Upm bis ca. 17000Upm - 2700min bis 13500max benötigt) und zur Berechnung der Drehzahl einen ATtiny2313 über einen 1k Widerstand an Pin 3 des (TC)4093 angschlossen. Es soll später noch eine Siebensegmentanzeige angeschlossen werden. In der Testphase sende ich die gemessene Drehzahl über RS232 an einen PC.

Mit der Schaltung hab ich so meine Probleme. Eigentlich kann sie nicht funktionieren, eine Spannung kann man nicht mit einem Anschluß Messen bzw. weiterverarbeiten. Man braucht immer zwei Anschlüsse. Eine Spannung ist per Definition eine Potentialdifferenz, es gehören also zwei Potentiale dazu. Die Masse der Schaltung müsste mit der Masse des Motors verbunden werden, so wie auch der andere Anschluß der Zündspule. In Praxis kann es natürlich durch kapazitive Kopplung der Massen trotzdem gehen. Zum Zweiten enthält sie ein Monoflop. Diese sind nicht umsonst in professionellen Schaltungen verpönt bis verboten, da sie notorische Störimpuls-Verstärker und Verlängerer sind. Aber auch das muß im Einzelfall keine Rolle spielen.

Die professionellen Zündimpulsabnehmer, die ich kenne (ist aber schon eine Weile her), arbeiten Induktiv. Dazu wird ein geschlossener Ferritkern um das Zündkabel gelegt, auf dem eine Abnehmerspule ist. Für den praktischen Betrieb ist das ein Klappkern in einer Zange. Das Ganze hat den Vorteil, daß der Ausgang galvanisch vom Motor getrennt und niederohmig ist. Auch kann man ein abgeschirmtes Kabel verwenden, seine Kapazität würde bei einem kapazitiven Abnehmer das Signal kurzschließen. Zum Ausprobieren kann man eine Entstördrossel auf einem Ringkern nehmen, durch den das Zündkabel passt.

Wenn das Signal bei deinem Aufnehmer bei allen Drehzahlen auf dem Scope sauber aussieht, vergiss meinen Text wieder, dann ist alles gut.



Funktioniert soweit ABER die gemessenen Werte schwanken doch relativ stark um den angepeilten einzustellenden Wert. Bei einer neuen Maschine, noch vom Werk eingestellt auf hoffentlich auf 2700Upm messe ich zB 2500 bis 3100Upm. Das ist mir deutlich zu unruhig und kann damit keine befriedigende Einstellung vornehmen.

Blauäugig hatte ich zunächst per ICP mit dem, mit 1MHz laufenden 16Bit Timer die Zeit zwischen den Zündimpulsen auf 1µs genau gemessen, Drehzahl auf eine Minute hochgerechnet (Upm=60000000/Meßwert in µs) und die zur Displayupdatezeit (jede 1/2 Sekunde) den gerade aktuellen Wert angezeigt: Sehr, sehr unruhige Anzeige :-(

Nach ein paar Versuchen die angezeigte Drehzahl ruhiger zu bekommen, zB auch mit Zählung der Zündimpulse innerhalb einer feste Torzeit von zB einer Sekunde,

Das Signal ist für eine Torzeitmessung zu langsam. Die Einheit, um die es geht ist U/min. Um eine Auflösung von 10 Umdrehungen zu bekommen, muß man eine Torzeit von mindestens 1/10 Minute, also 6 Sekunden haben. In der Zeit kann sich aber die Drehzahl des Motors geändert haben, Es ist also prinzipiel keine stabile Anzeige möglich.


bin ich nun bei folgender Lösung angelangt:
Displayupdate von etwas über einer Sekunde. Innerhalb dieser Sekunde werden die Zeiten zwischen den Zündimpulsen per ICP gemessen und aufaddiert

Ich habe mal einen gebaut und das auch so gemacht. Ein kleines Problem dabei ist, daß der Timer ab und an mal überläuft. Das kann man bei der Bestimmung der Zeit berücksichtigen. Im ersten Versuch hab ich den Fall einfach ignoriert. Wenn also der aktuelle Timerwert kleiner als der vorige war, ein Überlauf aufgetreten ist, hab ich den Wert verworfen. Ich war zu faul mir zu Überlegen, wie das mit Überläufen mit unsigned Variablen (ich benutze C) so geht. Am Ende hab ich das nie korrigiert. Hier mal der Code (in C):



long Time = 1;
volatile int Tout;

void _ISR __attribute__((no_auto_psv)) _IC3Interrupt(void) {
static long old_timer = 0;
unsigned long new_timer;

_IC3IF = 0; // das Interruptflag muß händisch gelöscht werden
new_timer = IC3BUF; // das Inputcapture Register
if (new_timer > old_timer) { // kein Überlauf
Time = new_timer - old_timer;
}
if (Time <= 0) { // Time nie 0 werden lassen
Time = 1;
}
old_timer = new_timer;
Tout = 0;
}

Bei meinem µC hab ich einen 32-Bit Timer, daher long Variable. Falls beim Weiterverarbeiten mal durch Time geteilt wird, vermeide ich den Wert 0, reine Paranoia. Zur Variable Tout sag ich später noch was.



Mit der Anzahl der aufgetretenen ICP-Interrupts (Anzahl der Zünimpulse) wird dann der einfache Mittelwert ausgerechnet und zu Anzeige gebracht. Zu Beginn des nächsten Anzeigeintervalls sind alle Meßwerte gelöscht und es beginnt eine komplett neue Drehzahlmessung und Berechnung.
Das ist eigentlich suboptimal. Man muß viele Messwerte speichern und die Anzeige wird langsam. Eigentlich braucht man einen Tiefpass auf die Messwerte, so wie es früher analoge Anzeigen inherent hatten. In Software lässt sich das leicht realisieren. Man nimmt einfach den letzten Messwert, addiert den aktuellen und teilt durch zwei. Das Ergebniss zeigt man an und merkt es sich als letzten Messwert. Das geht sehr schnell (eine Addition und teilen durch zwei) und benötigt nur eine Variable. Ich bin nicht so der große DSP Experte, das nennt sich wohl IIR-Filter. Wenn ich Messwerte im Interrupt bekomme, rechne ich das häufig gleich mit und entscheide später, ob ich mit dem Originalwert oder dem geglätteten weiterarbeite. Das mal so als Pseudocode (in meinem Drehzahlmesser hab ichs nicht gebraucht)



int Messwert;
int Geglättet;

void Messinterrupt()
static AlterWert;

Messwert = GetMesswer();
Geglättet = (AlterWert + Messwert) / 2;
AlterWert = Geglättet;
}

Ich hab das bei meinem Drehzahlmesser nicht gebaucht, daher ist das ohne Gewähr aus dem Kopf aufgeschrieben. Aber hier der Rest meines Drehzahlmessers.



int TachoMain(){
Tout = 0;

while (1) {
Tout++;
if (Tout > 50) {
ShowValue(UNDEFINED, 0); // keine Drehzahl messbar
Time = 1;
} else {
ShowValue(INT, (int)(375300L / Time));
}
delay(50);
}
}

Gut, ShowValue() geht auf die Anzeige und ist hier nicht zu sehen, da beliebig HW-abhängig. Wenn lange kein Interrupt gekommen ist, läuft Tout hoch und zeigt, daß kein gültiger Messwer vorliegt. Als "undefined" zeige ich alle horizontalen Segmente, das kann man auch gut aus den Augenwinkel erkennen, wenn man gerade irgend etwas einstellt. Im Wert "375300L" stecken die CPU Clock und alle Prescaler. Den Wert müsste man ändern, wenn mehr als ein Puls pro Umdrehung kommt. Da der µC sonst nichts zu tun hat, hab ich einfach ein Delay von 50ms in die Mainloop gesetzt, Als Hardware benutze ich eine Reflexlichtschranke und weißes bzw. schwarzes Klebband.

Ich hoffe, ich konnte dir ein paar Anregungen geben.

MfG Klebwax

Ceos
04.06.2019, 09:12
Eine Sache, die ich bei dem beschriebenen Verfahren in den Kommentaren gesehen habe, war wohl dass bei niedriger Drehzahl logischerweise auch die Spannung sinkt und du eventuell Pulse verpasst!


Ein kleines Problem dabei ist, daß der Timer ab und an mal überläuft

hatte ich auch zuerst vermutet, aber er verwendet in seinem Code ja Datentypen die auf den Timer passen also unsigned int 16 und wenn ich 2 uint16 subtrahiere macht der überlauf garnichts aus, die differenz ist immer gleich und immer positiv, der Vorteil von uint halt :)

Klebwax
04.06.2019, 10:24
hatte ich auch zuerst vermutet, aber er verwendet in seinem Code ja Datentypen die auf den Timer passen also unsigned int 16 und wenn ich 2 uint16 subtrahiere macht der überlauf garnichts aus, die differenz ist immer gleich und immer positiv, der Vorteil von uint halt :)

Du wirst sicher recht haben. Aber mir gefällt es grundsätzlich nicht, daß ein Programm nur mit Sideeffects funktioniert. Das mag in Assenbler noch angehen, in anderen Sprachen gibt es unsigned gar nicht. Ich versuche alles so zu halten, daß ein int zwar mindestens 16 Bit hat, der Code aber auch funktioniert, wenn es mal 64 sind. Mir sind noch die Problem beim Übergang von 16-Bit auf 32-Bit Code in Erinnerung. "unsigned" heißt bei mir eigentlich immer, es ist das Abbild eines HW-Registers, und da ist die Anzahl der benutzten Bits fest im Silizium. 10/12/14 Bit ADCs kann man direkt in ein int16_t einlesen und weiterrechnen, obwohl sie nie negativ werden. Nur bei Timern, wie hier, werden häufig alle Bits genutzt.

Das sind aber meine persönlichen Vorlieben. Ich war hier einfach zu faul, das Ganze beim Überlauf mal durch den Debugger laufen zu lassen und alle Grenzwerte auszutesten. Wenn bei tausend Touren mal eine Umdrehung nicht gemessen wird, merkt man das in der Anzeige nicht und es ist halt so im Code geblieben.

MfG Klebwax

wkrug
04.06.2019, 13:10
Soweit Ich den Code verstanden habe benutzt er ja den ICP Interrupt für die Drehzahlmessung.
Das sollte im Prinzip auch gut funktionieren und auch relativ unabhängig vom Auslesezeitpunkt sein.
Ich vermute hier eher einen Fehler auf der Hardwareseite.
Es kommen da evtl. unerwünschte Impulse durch.
Bei so Magnetzündungen hab Ich auch schon mal einen unidirektionalen Hallsensor verbaut.
Der liefert ein sehr gutes Rechtecksignal?!

Die Mittelung der Werte kann man auch über einen Ringpuffer machen.

Ein Zeiger erhält den Wert 0...4 bei jedem neuen Messwert inkrementierend.
Jeder Messwert wird dann in das Array geschrieben, an den Platz auf den der Zeiger zeigt.
Bei der Auswertung werden dann alle 5 Werte zusammengezählt und durch 5 geteilt.

Nimmt man für das Array 2^n Werte gehts auch mit ner Schiebeoperation dann noch schneller.

Searcher
04.06.2019, 16:43
Also echt. Klebwachs. Und alle anderen. Ihr habt mir ja eine Menge Input gegeben. Das will erst mal verarbeitet werden. Vielen Dank.

Werde zunächst kurz die wichtigsten Fakten durchgeben:

- Die Schaltung zur Abnahme des Zündimpulses vom Zündkabel ist im Eröffnungspost verlinkt.
- Überlauf bei der Differenzbildung von zwei aufeinanderfolgenden Meßwerten aus dem ICR ist gewollt und von Ceos schon gut erklärt. Dort liegt das Problem nicht.
- @wkrug: Mittelung mit Array hatte ich mit 8 Werten schon ausprobiert. War mir noch zu unruhig.
- Frequenzgenerator hatte ich dran. Sinusgenerator an den 1µF aus dem verlinkten Schaltbild und GND Anzeige ist von 1020Upm bis 17000Upm (17Hz bis 283Hz) stabil.

Ich tendiere jetzt auch schon ein wenig auf die Unzuverlässigkeit der Signalgewinnung für den µC.
Oszi zeigte aber auch keine 100% stabile Zündfrequenz von der Maschine was aber auch normal ist. Die angezeigte große Abweichung von der mittleren Frequenz irritiert mich halt.

Ich werde euren Input in Ruhe durchgehen und schauen, daß ich ein paar Meßreihen und aussagekräftige Ozillogramme aufzeichne und hier zeigen. Leider hat mein Oszi keinen großen Speicher, so daß es nicht einfach ist, seltene Ausreißer festzuhalten.

@Klebwachs: Für Deinen Post muß ich mir nochmal extra Zeit nehmen.

Gruß
Searcher

- - - Aktualisiert - - -

PS: Noch zum Programm:

Es gibt zwei ISR. Die Hauptschleife (do Loop) ist leer.

Die "get_icr" wird aufgerufen, wenn am ICP-Pin eine steigende Flanke erkannt wird.
Innerhalb der ISR wird das ICR Register, in den der aktuelle Timer1 durch die Flanke gesichert wurde, ausgelesen und die Differenz zum vorherigen ICR-Wert gebildet. Die Differenz ist die Zeit in µs zwischen zwei Zündimpulsen. Die Zeiten werden in der ISR in Accumul_difference noch aufaddiert. In Icp_events werden noch die Anzahl der Zündimpulse gezählt. Wenn nach Einschalten des Drehzahlmessers der alte ICR-Wert noch Null ist, ist die erste Drehzahlanzeige falsch.


In der update_display, die ich einfach an den Timer1 angehangen habe, aber nur etwa einmal pro Sekunde wirklich was tun soll. Deshalb das "If Tov_count = 15 then" Hier werden dann die in "get_icr" gesammelten Werte für die Anzeige aufbereitet und über RS232 mit Print zum PC.
Sind in Accumul_difference zB 990000µs zusammengekommen und in icp_events 45events werden 990000/45=22000µs als mittlere Zeit zwischen zwei Zündungen ausgerechnet. Entspricht einer Frequenz von 1/0,022s = 45 Hz. Das auf eine Minute in der Variablen Upmd (d für Double Word - 4 Byte unsigned Variable) gerechnet: 60000000/22000 entspricht 2727Upm.

Sind 1000000µs bei 100 events zusammengekommen. 1000000/100=10000µs mittlerer Zündabstand, 60000000/10000=6000Upm

Searcher
06.06.2019, 18:23
Hallo,
ich habe mal ein paar Messungen gemacht. Zunächst die verwendete Schaltung, die den Zündimpuls für den µC aufbereitet. (Mittlerweile fand ich im MC net weitere Kritiken dazu, die auch gar nicht gut aussehen).

https://www.roboternetz.de/community/attachment.php?attachmentid=34189&d=1559840673

Abblockkondensatoren sind am 4093er und ATtiny2313 vorhanden. Versorgungsspannung ist sauber.

Das Programm wurde nur dahingehend verändert, daß man vom PC Terminal die Messungen untereinander geschrieben werden und wurden von dort kopiert. SW Hysterese testet auf >-1 statt auf >10, so das von einer Sekunde zur anderen jede Änderung geschrieben wird. Außerdem wird am Anfang einer Zeile eine Meßsequenznummer ausgegeben und am Ende einer Zeile steht die Anzahl der Zündimpulsabstände, die innerhalb einer Sekunde addiert wurden und durch die dann zur Mittelwerterzeugung geteilt wurde. Zum Start einer Meßreihe wurde die Versorgungsspannung für den stromlosen Drehzahlmesser eingeschaltet.

Hier die Meßwerte mit dem Sinusgenerator (alter analoger Pegelsender von Siemens, ein W2040).
Anhang 45Hz_Sinus_1Min_lang_60Updates.txt
Anhang 283Hz_Sinus_1Min_lang_60Updates.txt

Und Oszillogramme:
45Hz_Sinus_Pin8.png, Kanal 1 - Generatorsignal wie in Schaltung an C3, Kanal 2 - von Pin 8 des CD4093
https://www.roboternetz.de/community/attachment.php?attachmentid=34185&d=1559840627

45Hz_Sinus_µC.png, Kanal 1 - Generatorsignal wie in Schaltung, Kanal 2 - rechte Seite von R4
https://www.roboternetz.de/community/attachment.php?attachmentid=34186&d=1559840635

283Hz_Sinus_Pin8.png
https://www.roboternetz.de/community/attachment.php?attachmentid=34187&d=1559840644

283Hz_Sinus_µC.png
https://www.roboternetz.de/community/attachment.php?attachmentid=34188&d=1559840656


Hier Messungen an einer Motorsäge im Leerlauf, die vom Werk auf 2700Upm eingestellt ist. Dazu muß man sagen, daß je nach Temperatur die Leerlaufdrehzahl anders ist. Abweichungen davon sind also normal. Ich wüßte nur zu gerne in welchem Maße die Drehzahl zB im Sekundentakt abweicht. Im Oszi erkennt man deutlich Abweichungen von einem Zündungsabstand zum anderen. Der Zündimpuls wurde einmal einadrig mit Krokoklemme am Zündkabel abgenommen und an C2=220pF angeschlossen. Bei den beiden anderen Meßreihen wurde der Draht mit 3 Windungen um das Zündkabel gelegt und mit C2=220pF und mit C2=1nF gemessen. (Meßreihe mit Kroko an 1nF ist verschwunden :-( )

Anhang Kroko_220pF.txt
Anhang 3Wdg_220pF.txt
Anhang 3Wdg_1nF.txt

Die Oszillogramme zeigen Kanal 1 an Pin 8 vom CD4093, Kanal 2 an rechter Seite von R4, also das Signal daß zum µC geht. Kanal 1 ict AC gekoppelt. +5V Gleichspannungsanteil dazu rechnen.

Kroko_220pF.png
https://www.roboternetz.de/community/attachment.php?attachmentid=34190&d=1559840693

Kroko_1nF.png
https://www.roboternetz.de/community/attachment.php?attachmentid=34191&d=1559840699

3Wdg_220pF.png
https://www.roboternetz.de/community/attachment.php?attachmentid=34192&d=1559840708

3Wdg_1nF.png
https://www.roboternetz.de/community/attachment.php?attachmentid=34193&d=1559840713

Und noch das Zündabnahmedrahtsignal Kanal 1 (Kein Gleichstromanteil) direkt vor C2 und Kanal 2 nach R4.

raw.png
https://www.roboternetz.de/community/attachment.php?attachmentid=34199&d=1559841693

Alles erstmal ohne Kommentar, da selbst noch nicht genauer analysiert. Jedoch sind die Schwankungen geringer als bei meinen ersten Versuchen - warum auch immer? Subjektiv funktioniert es mit Wicklung um das Zündkabel besser..


Gruß
Searcher

wkrug
06.06.2019, 20:41
Eeventuell entstehen die Schwankungen auch durch schwankende / fehlerhafte Teilerfaktoren?!

Probier mal pro sekunde nur 8 aufeinanderfolgende Messwerte aufzuaddieren und das Ergebnis duch 8 zu teilen.
Das funzt dann runter bis 500 U/min.
Wenn die Anzeige dadurch stabiler wird hab ich vermutlich mit meiner Annahme recht.

Searcher
07.06.2019, 04:39
Probier mal pro sekunde nur 8 aufeinanderfolgende Messwerte aufzuaddieren und das Ergebnis duch 8 zu teilen.

Ich glaub, so etwas hab ich schon gemacht und verworfen. Bevor ich die Säge wieder anschmeiße und Meßreihen dazu aufnehme :-) :meintest Du es so? ...

In einem Ringpuffer mit 8 Plätzen ( Middle( 8 ) ) werden 8 aufeinanderfolgende ICP Meßwerte, also der Abstand von einer Zündung zur anderen reihum abgespeichert.
Ist nach etwa einer Sekunde ein Update der Anzeige dran, wird der Mittelwert der letzten 8 Meßwerte gebildet und angezeigt. Siehe Code.


$regfile = "ATtiny2313.DAT"
$framesize = 24
$swstack = 24
$hwstack = 34
$crystal = 8000000
$baud = 57600
$lib "mcsbyteint.lbx"

Dim Icr_new As Word
Dim Icr_old As Word
Dim Icr_difference As Word
Dim Upmd As Dword
Dim Upm_o As Word
Dim Tov_count As Byte

Dim Middle(8) As Word
Dim Ar_idx As Byte
Dim Idx As Byte
Dim Diff As Dword
Dim Icp_alive As Byte
Dim Disp_upd As Byte
Dim Icp_events As Word

Print "Drehzahlmessung"

Tccr1b = Bits(cs11 , Ices1) 'prescaler = 8, input capture event on rising edge

On Timer1 Update_display
Enable Timer1

On Icp1 Get_icr
Enable Icp1

Enable Interrupts

Do
Loop

Get_icr: 'called by an ICP event
Incr Icp_events
Icr_new = Icr1 'save ICR register
Icr_difference = Icr_new - Icr_old
Icr_old = Icr_new
If Idx < 8 Then Incr Idx Else Idx = 1 'value into 8 elements ring buffer
Middle(idx) = Icr_difference 'value into 8 elements ring buffer
Icp_alive = 1
Return

Update_display:
Incr Tov_count
If Tov_count >= 15 Then 'display update in about 1s interval
Incr Disp_upd 'sequence number for display update
For Ar_idx = 1 To 8
Diff = Middle(ar_idx) + Diff 'add last 8 values before display upd
Next
Upmd = 480000000 / Diff 'calculate rpm 60.000.000/(diff/8)
Upm_o = Upmd
If Icp_alive = 0 Then Upm_o = 0
'Remark Print " " ; Chr(13) ; Upm_o ; Chr(13);
Print Disp_upd ; ": " ; Upm_o ; " " ; Icp_events
Tov_count = 0
Diff = 0
Icp_alive = 0
Icp_events = 0
End If
If Disp_upd = 60 Then Disp_upd = 0
Return

wkrug
07.06.2019, 05:27
In einem Ringpuffer mit 8 Plätzen ( Middle( 8 ) ) werden 8 aufeinanderfolgende ICP Meßwerte, also der Abstand von einer Zündung zur anderen reihum abgespeichert.
Ist nach etwa einer Sekunde ein Update der Anzeige dran, wird der Mittelwert der letzten 8 Meßwerte gebildet und angezeigt. Siehe Code.
Genau so hatte Ich das gemeint.
Aber wenn Du das schon probiert hast und es nichts gebracht hat...

Ich dachte, das Du z.B. 40 Messwerte aufaddiert hast, dann aber durch z.B.41 geteilt hast, weil evtl. schon wieder ein neuer Zündimpuls gekommen ist, der aber noch nicht verrechnet war - bzw. Umgekehrt.
Das hätte dann die Drehzahlsprünge erklären können.

Wenn es tatsächlich an der Abnahme des Zündsignals liegt ( auch wenn Ich mir das an Hand der Oszillogramme nicht vorstellen kann ) könntest Du trotzdem noch mal über die Abnahme über einen Magnetfeldsensor ( z.B. TLE4905 ) direkt am Magneten der Schwungscheibe nachdenken.
Wenn man da gut ran kommt.


Oder aber Du versuchst mal eine Induktive Abnahme ( Mehrere Wicklungen über das Zündkabel - Ein Anschluss auf Masse, der andere an den Eingang Deiner Schaltung.
Das funktioniert dann wie ein Trafo. Der Stromfluss im Zündkabel bewirkt einen Spannungsstoß in der Wicklung.

Searcher
07.06.2019, 06:13
Ich dachte, das Du z.B. 40 Messwerte aufaddiert hast, dann aber durch z.B.41 geteilt hast, weil evtl. schon wieder ein neuer Zündimpuls gekommen ist, der aber noch nicht verrechnet war - bzw. Umgekehrt.
Das hätte dann die Drehzahlsprünge erklären können.


Sollte nicht passieren, da ja alles im Interrupt stattfindet und die Daten konsistent sein sollten. Kleine Ungenauigkeiten passieren beim Dividieren, da dort gerundet wird. Grob bleiben die Rundungsfehler aber unter 10 Upm.


Wenn es tatsächlich an der Abnahme des Zündsignals liegt ...
Ich werde da auch noch experimentieren. Wenn ich da was zusammenbringe, werd ich nochmal Meßreihen hier zeigen. Auch noch die mit dem 8er Ringpuffer. Ich versuche die lauten und qualmigen Versuche schnell hintereinander zu machen. Vollgas hab ich noch nicht probiert, da ich dann auch noch Abwehrmaßnahmen gegen das Kettenöl treffen muß. das von der laufenden Kette verspritzt wird. :-) (Könnte man abbauen, würde aber dann ohne Last die Messung verfälschen)

Gruß
Searcher

Searcher
07.06.2019, 18:31
Ich habe jetzt erst noch mit der kapazitiven einadrigen Zündimpulsabnahme experimentiert. Eine einadrige, 1,5m lange, ca. 0,75mm² dicke Kupferlitze ist mit zwei Windungen um das Zündkabel einer Husqvarna 445 Motorsäge gelegt. Das andere Ende zur gestern geposteten Schaltung. C2 ist jedoch 1nF und R2 = 110kOhm.

https://www.roboternetz.de/community/attachment.php?attachmentid=34203&d=1559928066

Kanal 1 des Oszis ist wieder an Pin 8 des CD4093B angeschlossen. Die Impulse erreichen für mich klar die Schaltschwellen des der Schmitttriggereingänge ds CD4093. Kanal zeigen die Pulse die generiert werden und die der µC zur Verarbeitung bekommt. Bei längeren Beobachtungen des Oszis konnte ich keine Ausfälle oder Mehrfachimpulse auf Kanal 2 erkennen. Wenn auch die Impulsabnahme nicht ideal erscheint und vielleicht bei der nächsten Maschine nicht mehr sauber funktioniert, möchte ich damit erstmal weitermachen.

Die "unruhige" Anzeige ist immer noch da. Sie kann meines Erachtens nur vom unruhigen Lauf des Zweitakters herrühren. Ich habe dazu 2 Meßreihen über je eine Minute (60 Anzeigen) gemacht und in Excelgraphiken dargestellt. Programme (jeweils ohne SW-Hysterese) weiter oben im thread zu finden.

1. Upm errechnet mit ICR Differenzwerten über eine Anzeigeperiode. (Mittelwert über die 60 Werte= 2681Upm)
https://www.roboternetz.de/community/attachment.php?attachmentid=34201&d=1559928049

2. Upm errechnet mit den letzten 8 Differenzwerten vor der Anzeige. (Mittelwert über die 60 Werte= 2694Upm)
https://www.roboternetz.de/community/attachment.php?attachmentid=34202&d=1559928059

Ich möchte jetzt weiter versuchen, die Anzeige per Programm zu "smoothen". Werd mir Deinen Beitag, Klebwax, mal intensiver zu Gemüte führen. Vielleicht einen riesengroßen Ringpuffer - aber der Tiny2313 hat so wenig SRAM. Oder innerhalb einer Anzeigeperiode 8 verdeckte Mittelwerte bilden und die im Ringpuffer über eine Anzeigenperiode mitführen. Daraus dann den Anzeigewert mitteln. Die Reaktion wird dann zäher. Aber alles zusammen geht wohl nicht :-) , scheitert an dem Zweitakter.

Gruß
Searcher

Siro
08.06.2019, 07:43
Guten Morgen Searcher,

dein Oszilloskopbild habe ich mal vergrößert und ausgedruckt und mit dem Lineal gemessen.
34204
Hier ist eindeutig zu erkennen, dass die Messwerte erheblich schwanken.
Da Du anscheinend wenig RAM zur Verfügung hast, wäre ein Softwarefilter (Tiefpass) angebracht.

Ich hab mal in mühsamer Kleinarbeit einen Tiefpass geschrieben, der ohne Floats auskommt
und auch keinen Puffer benötigt, da er in Echtzeit (Samplegenau) funktioniert.

Der Code ist absolut trivial, aber entspricht exakt einem RC-Tiefpass und lässt sich sehr einfach anpassen.

Zunächst mal einige Erläuterungen dazu:
Das Entscheidende ist die Abtastrate (Samplerate) also wieviele Messwerte kommen pro Sekunde
und die Centerfrequenz (Fc) des Filters.

Beispiel bei mir:
Mein ADU liefert 1000 Messwerte pro Sekunde, das ist also die Abtastrate
Die Centerfrequenz (Fc) ist die Frequenz an dem die Amplitude um 3 Dezibel fällt wenn man eine
Sinusschwingung durch den Filter schickt.

Um sich unnötige (komplizierte) Berechnungen zu ersparen, kann mein Controller eh nicht
habe ich "vorab" einen Faktor benannt mit "D" berechnet.
Dieser Wert wird nur einmal (extern, Taschenrechner) berechnet und abgelegt.
Da ich keine floats habe, wird der Wert vorher noch mit 65536 multipliziert
So kann ich auch Nachkommastellen berücksichtigen

Ich habe den Code inzwischen in Pascal und C implementiert, aber ich denke das sollte kein Problem sein
ihn nach (sieht aus wie Basic ?) zu konvertieren.

Die Funktion ist für 32 Bit Integer ausgelegt
In Basic musst Du vermutlich den Typ long nehmen für 32 Bit

Dreh und Angelpunkt ist die Vorabberechnung bzw. der Wert von "D"
D:=1-exp(-(2*pi*Fc) / Samplerate);
Hier kannst Du aber auch ganz experimentell Werte probieren und schauen wie es sich verhält.


Die "C" Variante

/*---------------------------------------------------------------------------*/
/* Siro's Spezialfunktion für einen Softwarefilter Tiefpass */
/* simuliert exakt ein ganz normales R/C Glied */
/* D:=1-exp(-(2*pi*Fc) / Samplerate); */
/* Fc ist die Centerfrequenz, der -3dB Punkt */
/* dann den Wert noch mit 65536 multiplizieren, wegen Integer Berechnungen < 0 */
/* Bezogen auf eine Abtastrate von 1000 Hz (1KHz) ergeben sich folgende Werte */
/* D = 21 ==> Fc = 0.05 Hz */
/* D = 41 ==> Fc = 0.1 Hz */
/* D = 206 ==> Fc = 0.5 Hz */
/* D = 410 ==> Fc = 1 Hz */
/* D = 818 ==> Fc = 2 Hz */
/* D = 2026 ==> Fc = 5 Hz */
/* D = 3991 ==> Fc = 10 Hz */
/* D = 7739 ==> Fc = 20 Hz */
/* D = 17668 ==> Fc = 50 Hz */
/* D = 30573 ==> Fc = 100 Hz */
/* D = 46884 ==> Fc = 200 Hz */
/* D = 62704 ==> Fc = 500 Hz */

S32 flowFilter(S32 value)
{ const S32 d = 206; // LowPassFilter Fc=0.5 Hz at 1000 Hz Samplerate

static S32 n = 0;
static S32 rest = 0;
S32 xx;

value = value - n;
xx = value * d;

rest = (xx+rest) % 65536; // % ist MOD Modulo (Divisionsrest) in "C"
xx = (xx+rest) / 65536;
n = n + xx;

return n;
}
/*---------------------------------------------------------------------------*/


Die "Pascal" Variante:

{------------------------------------------------------------------------------}
// !!!!! die mit const deklarierten Variablen
// müssen "statisch lokal" sein oder "global"
// sie müssen also erhalten bleiben nach dem Verlassen der Funktion
// in Pascal kann man das mit Const erzwingen.

Function FilterTP(value:Integer):Integer; // Tiefpass
const d : Integer = 206; // LowPassFilter Fc=0.5 Hz at 1000 Hz Samplerate
const n : Integer = 0;
const rest : Integer = 0;
var xx : Integer = 0;
begin
value:= value - n;
xx := value * d; // d ist ja schon mit 65536 multipliziert
rest := (xx + rest) MOD 65536; // wir muessen jetzt durch 65536 teilen
xx := (xx + rest) DIV 65536; // und den jeweiligen rest uns merken
n := n + xx;
result:=n;
end;
{------------------------------------------------------------------------------}

Der Aufruf erfolgt mit

Messwert:=FilterTP(Messwert); // durch den Filter jagen

Ausgabe(Messwert); // hier dann anzeigen

Du kannst einfach mit dem Wert für "D" herum experimentieren,
je kleiner der Wert wird, umso ruhiger wird auch deine Anzeige, aber auch träger.

PS.: Die Variablen innerhalb der Funktion solltest Du vermutlich "GLOBAL" definieren, ich hab nicht gefunden dass Basic statische lokale Variablen kann...
Einfach mal den D Wert irgendwie setzen und vor deiner Anzeige des Messwertes diesen durch den Filter schicken.

Siro

Hier mal ein Beispiel was er aus meinem verrauschten Signal macht: die grüne Kurve ist die gefilterte mit obigen Code.
34205

Hier habe ich den D-Wert vergößert: es wird etwas unruhiger, aber dafür schnellere Reaktionszeit
34206

Searcher
08.06.2019, 11:25
Tach Siro,



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

Klebwax
08.06.2019, 21:09
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.

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

wkrug
09.06.2019, 08:26
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-filter-einfach-erklaert-teil-1
https://www.cbcity.de/das-kalman-filter-einfach-erklaert-teil-2
https://www.cbcity.de/das-extended-kalman-filter-einfach-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!

Searcher
09.06.2019, 09:26
... 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

wkrug
09.06.2019, 12:41
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

Klebwax
09.06.2019, 16:52
Oder aber Du versuchst mal eine Induktive Abnahme ( Mehrere Wicklungen über das Zündkabel - Ein Anschluss auf Masse, der andere an den Eingang Deiner Schaltung.
Das funktioniert dann wie ein Trafo. Der Stromfluss im Zündkabel bewirkt einen Spannungsstoß in der Wicklung.

Das funktioniert so nicht. Der Strom im Zündkabel erzeugt ein Magnetfeld, dessen Feldlinien das Kabel umschließen. Die Windungen einer Spule, die um das Kabel gewickelt wird, sind parallel zu den Feldlinien, da wird also nichts induziert. Alles was man da misst, geht über die kapazitive Kopplung zwischen dem dem Leiter im Zündkabel und dem (beliebig geformten) Leiter außen. Da die Fläche eines aufgewickelten Draht größer und dichter am Innenleiter ist, ist die Kapazität dieses Kondensators größer als die einer Krokodilklemme. Das Signal wird also ebenfalls größer, bleibt aber kapazitiv abgenommen.

Für einen induktiven Abnehmer bräuchte man eine Rogowsky-Spule. Da gehen die Feldlinien durch die Sensorspule. Oder einen Kern, der das Zündkabel umschließt und auf den die Sekundärwicklung gewickelt ist. Das wird für den praktischen Einsatz gern als Klappkern ausgeführt. Man kann aber das Zündkabel auch durch den Ringkern einer Drossel stecken oder einen fertigen Stromtrafo mit Loch zum Durchstecken nehmen.

MfG Klebwax

Searcher
10.06.2019, 21:49
Und wie Du in deiner Signatur schreibst:
Hoffentlich liegt das Ziel auch am Weg
______________________________________:pray::pray: :pray:



Jetzt habe ich schon mal einen Simulator gebastelt um die Zündimpulse nachzubilden. Ist ein ATmega88pa auf dem folgendes Programm läuft.


$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

Klebwax
12.06.2019, 08:59
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

Ceos
12.06.2019, 09:37
Also wenn ich mir die Daten ansehe, wäre ein Extremwertfilter eine bessere Lösung!

Außerdem sollte man Timerüberläufe mit aufzeichnen um mehr Konsistenz in die Daten zu bekommen!

Ich komme im Schnitt auf 800 Digits wenn ich die Extremwerte ignoriere

Das Bild das mir der Graph in Excel über deine Daten zeigt, sagt mir dass du einen systematischen Fehler bei der Messung hast, alle ~10 Samples hast du einen systematischen Ausreißer + ein paar zufällige, welche aber auch das Problem hindeuten!

Ich vermute dein Problem immernoch beim Messaufnehmer oder eventuell im "debounce"

Wenn du nochmal Daten sammeln kannst und zusätzlich eine Info ob und wieviel Überläufe zwischen den Samples liegen? (eventuell einfach den Zeitwert nehmen und die unteren beiden Bits maskieren und überschreiben, Bit 1 für timer einmal übergelaufen und Bit 0 für Timer mehr als einmal übergelaufen)

Dann kann man zumindest schonmal einschränken dass wir ganze dekaden an signalen verpassen (das vermute ich nämlich aktuell)

Ungewöhnlich ist auch dass der Timerwert immer relativ stabil um die 20k herum eiert und es sprünge gibt sobald man <13k oder >27k im timer hat, eventuell haben wir eine Schwebung!?

auch wenn ich jetzt 2700 rpm nehme machen 5 Sekunden eher 225 Samples .. bei 3000rpm mit 250 schon eher wahrscheinlich (aber wäre auch logisch wenn er kalt ist)

Klebwax
12.06.2019, 09:45
Ich vermute dein Problem immernoch beim Messaufnehmer oder eventuell im "debounce"

ACK

MfG Klebwax

Searcher
12.06.2019, 13:03
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

Hab ich jetzt gemacht. Die ISR "Isr_get_icr" zum Sichern des ICR-Werte verändert, so daß jetzt der echte Inhalt aufgezeichnet wird. siehe Code. Der Rest des Simulatorprogramms von weiter oben im thread ist unverändert. Samples wieder im Anhang.

Isr_get_icr:
Incr Ignition_seq
Firing_interval(ignition_seq) = Icr1
If Ignition_seq >= Sample_count Then 'array full, stop recording
Disable Icp1 'disable ICP1
Tccr1b = 0 'init, stop timer1
Flag_rec_complete = 1
Ignition_seq = 0
End If
Return




Ich vermute dein Problem immernoch beim Messaufnehmer oder eventuell im "debounce"
Wenn du nochmal Daten sammeln kannst und zusätzlich eine Info ob und wieviel Überläufe zwischen den Samples liegen? (eventuell einfach den Zeitwert nehmen und die unteren beiden Bits maskieren und überschreiben, Bit 1 für timer einmal übergelaufen und Bit 0 für Timer mehr als einmal übergelaufen)


Es sollten eigentlich kein Meßfehler vorliegen. Der Debounce Befehl in Bascom nutzt keinen Interrupt. Wenn die Hauptschleife dort vorbeikommt, wird erst nur der Pin auf gedrückte Taste, in diesem Fall nur einmal auf LOW-Pegel getestet. Wenn kein Tastendruck, also kein Low-Pegel erkannt wird, wird sofort in der Haupschleife weitergemacht. Während der Aufzeichnung ist keine Taste gedrückt. Wenn auf gedrückte Taste erkannt wurde, kann die Hauptschleife, wenn nichts anderes konfiguriert wurde, bis zu 25ms aufgehalten werden. Sprung zu Interrupts würden dadurch aber nicht behindert werden. Im Dateianhang "icr_werte.txt" sind die ICR Werte abgelegt. Man kann dort die Überläufe erkennen wenn nach einem hohen Wert ein kleinerer auftaucht. Falls noch mehr Daten gebraucht werden - kein Problem ...

An der Impulsaufnahme zweifle ich auch nicht, da mehrfach direkt am Abnahmedraht und mehreren Stellen in der CD4093 Schaltung mit Oszi überprüft. Halte meine Augen aber trotzdem auch in der Richtung noch offen.

Ich denke, der Motor läuft wirklich so wie die Daten es zeigen. Das Laufgeräusch im Leerlauf bei Standgas ist alles andere als rund und "schnurrend". Typisches Zweitaktergeräusch; scheint normal zu sein. Ganz am Anfang vom Video https://youtu.be/d9_J9TI6dx8 läuft auch eine im Standgas. Anwerfen und Laufgeräusch meiner Säge als MP3 mit 7zip in der zip Datei im Anhang.

Gruß
Searcher

Ceos
12.06.2019, 14:06
mhhh ... ändert leider nicht viel am ergebnis

kannst du mal ein paar bits opfern um den timerüberlauf mit zu erfassen wie ich es oben beschrieben habe?!

Klebwax
12.06.2019, 14:17
mhhh ... ändert leider nicht viel am ergebnis

kannst du mal ein paar bits opfern um den timerüberlauf mit zu erfassen wie ich es oben beschrieben habe?!

Die kann man doch aus den Werten rauslesen. Wenn der neue Wert kleiner als der vorherige Wert ist, ist der Timer übergelaufen. Anders kann das der Interupthandler auch nicht rausfinden.

MfG Klebwax

Ceos
12.06.2019, 14:22
Anders kann das der Interupthandler auch nicht rausfinden
Overflow sollte einen eigenen interrupt haben

nur vom vorherigen wert auszugehen birgt das risiko einen vollen durchlauf zu verpassen

(ich bin nicht firm in bascom und versteh den code nur ansatzweise!!!)

Worum es mir geht ist eine inkonsistenz deiner werte alle ~10 messungen, irgendwas passiert da dass das timing durcheinanderbringt!

Kannst du mir mal aufschlüsseln wie dein capture timer konfiguriert hast?! 8Mhz F_CPU sehe ich ja aber bei der timer init komm ich ins schleudern

Searcher
12.06.2019, 15:31
Overflow sollte einen eigenen interrupt haben
Hat Timer1. Erklärung s.u.


kannst du mal ein paar bits opfern um den timerüberlauf mit zu erfassen wie ich es oben beschrieben habe?!

Kannst du mir mal aufschlüsseln wie dein capture timer konfiguriert hast?! 8Mhz F_CPU sehe ich ja aber bei der timer init komm ich ins schleudern

Die Programmteile stammen aus dem Simulator Programm.

On Timer1 Check_icp_alive 'on timer1 overflow -> ISR Check_icp_alive
On Icp1 Isr_get_icr 'on icp1 interrupt -> ISR isr_get_isr


Start_record:
Tccr1a = 0 'init timer1
Tcnt1 = 0
Ignition_seq = 0
Flag_rec_complete = 0
Tifr1.tov1 = 1 'reset eventually set TOV1 Flag
Enable Timer1 'enable timer1 overflow interrupt
Icr_old = Icr1 'not nessecary. artifact ?
Enable Icp1 'enable ICP1 Interrupt
Tccr1b = Bits(cs11 , Ices1) 'prescaler=8 timer1 clocked with 1MHz, ICP Interrupt on rising edge
Portc.pc4 = 1 'rec LED on
Return



Isr_get_icr:
Incr Ignition_seq
Word_variable = Icr1 / 10
Firing_interval(ignition_seq) = Word_variable * 10 'letzte Dezimalstelle auf Null
If Ignition_seq >= Sample_count Then 'array full, stop recording
Disable Icp1 'disable ICP1
Tccr1b = 0 'init, stop timer1
Flag_rec_complete = 1
Ignition_seq = 0
End If
Return



Check_icp_alive:
Firing_interval(ignition_seq) = Firing_interval(ignition_seq) + 1 'bei timer1 überlauf wird zum letzten gespeicherten ICR wert Eins addiert
If Ignition_seq_old = Ignition_seq Then
Flag_icp_dead = 1
Else
Ignition_seq_old = Ignition_seq
End If
Return
Mit zB "on timer1 check_icp_alive" werden die Interrupt Vektoren initialisiert

Die "Start_record" ist ein Unterprogramm und wird mit Drücken der Record Taste aufgerufen.
Dort wird der Timer1 initialisiert und mit Vorteiler 8 gestartet. Läuft bei Systemtakt von 8MHz dann mit 1MHz, Periodendauer = 1µs. Vorteil: Den ausgelesenen Wert aus ICR1 kann man mit Einheit µs versehen. Hab noch ein paar Remarks im Code eingefügt. Mit den Interrupts scharf machen (enable) und Starten des Timers beginnt die Meßwertaufnahme.

Die ISR_get_icr ist eine ISR und wird durch den ICP Interrupt aufgerufen. Dort wird jetzt die letzte Dezimalstelle auf Null gesetzt. Wenn 256 Werte aufgenommen sind wird Timer1 gestoppt mit tccr1b=0 und der ICP Interrupt wieder disabled.

Die ISR Check_icp_alive wurde und wird bei Timer1 Überlauf aufgerufen und dient eigentlich dazu festzustellen, ob überhaupt ICP Interrupts (Zündimpulse) auftreten. Aussetzen kann passieren, wenn zB das Impulsabnehmerkabel nichts liefert. In dieser ISR wird jetzt zusätzlich dem letzten, vor dem Overflow gespeicherten ICR Wert, Eins aufaddiert. Falls sich da was verschluckt müßte an der letzten Stelle mal eine Zwei auftauchen. Eine Eins immer dann, wenn nach einer großen Zahl eine kleinere auftauscht.

Im Anhang die Werte mit diesem Programm.


Worum es mir geht ist eine inkonsistenz deiner werte alle ~10 messungen, irgendwas passiert da dass das timing durcheinanderbringt!
Ich glaube, daß die Meßwerte stimmen. Die Ausreißer könnten von der Drehzahlregelung der Maschine kommen: Die Drehzahl sinkt langsam ab. Dann wird schnell auf höhere Drehzahl geregelt. Ein Ausreißer ist die Zündung auf dem Weg nach "oben". Dann sinkt die schnelle Drehzahl wieder langsam ab bis das Spiel von vorne beginnt.

Gruß
Searcher

Searcher
20.06.2019, 22:02
Hallo,
nach einer Pause habe ich mir heute wieder den Drehzahlmesser vorgenommen. Um ein paar neue Daten für den Simulator zu bekommen wurde der Zweitakter mal auf ca. 4500Upm mit Hochdrehen der Standgasschraube eingestellt. Mitteln der Drehzahl per Auge am PC Bildschirm mit den hüpfenden Ausgaben.

256 Meßwerte mit Simulator aufgenommen und über den eigentlichen Drehzahlmesser gemessen. Gegenwärtige Glättung noch durch Aufaddieren der ICR Meßwerte in einem Anzeigeinterval (etwa eine Sekunde). Im Anzeige-Interrupt wird die Summe zusammen mit der zugehörigen Anzahl der Summanden in einem Array abgespeichert. Im Augenblick gibt es nur zwei Arrayelemente, die zyklisch überschrieben werden. Aus diesen Elementen wird dann noch ein einfacher Mittelwert gebildet und die Einerstelle auf Null gesetzt. Also wird der Wert aus dem vorherigen Anzeigeinterval mit dem aktuell auszugebenden verrechnet. In diesem Drehzahlbereich von ca. 4500Upm laufen etwa 160 Werte pro Anzeigeinterval auf. Das reicht um eine relativ ruhige Anzeige hinzubekommen. Der Motor läuft hier auch viel runder wie man in der grafischen Darstellung der einzelnen Zeiten zwischen den Zündungen sehen kann. Das Muster wie bei 2700Upm gibt es nicht mehr; die Meßpunkte sind viel zufälliger wie es scheint. Allerdings greift die Kupplung in diesem Drehzahlbereich, was auch wieder eine Störung hervorrufen könnte.

Ich wollte noch weitere Glättungen ausprobieren aber irgendwie hatte ich zwischen den umgerechneten Werten des Simulators im Excel und der gemessenen Drehzahl mit dem Drehzahlmesser immer etwa 60, 70 Upm zu wenig. Die Fehlersuche hat mich fast den ganzen Nachmittag beschäftigt. Oszi zeigte richtige Pulslänge vom Simulatorausgang an. Letzten Endes kam heraus, daß der Quarz am Drehzahlmesser um 100kHz zu schnell lief, also 8,1Mhz statt 8,0MHz. Das Ding hatte ich zuletzt ohne zu überprüfen ausgetauscht. Einen anderen 8.0MHz Quarz rein und alles war gut. Die RS232 zum PC hatte nichts gemerkt.

Gruß
Searcher

Searcher
02.07.2019, 18:51
Ich bin immer noch nicht viel weiter. Allerdings ist die Schaltung des Drehzahlmessers jetzt auf eine Platine gebracht und ein Gehäuse ist auch gefunden; von einem HP-Druckernetzteil. Strom gibt es über einen 7805 vom Akkupack mit 6 NiMh AA-Akkus. Wär nicht unbedingt nötig, hatte ich aber gerade hier herumliegen. Es täte auch ein 9V-Block. Wird ersetzt wenn ein Display im Deckel den Platz braucht. Als Display fungiert im Augenblick mein altes IC-Grab (http://www.roboternetz.de/community/threads/51654-4x7-Seg-mit-3-Ader-SW-SPI-Einstieg-mit-BASCOM-u-ATtiny45?p=518565&viewfull=1#post518565) über einen Klinkenstecker am UART angeschlossen. Ist vierstellig und Drehzahlen über 9999Upm werden zur Zeit mit Doppelpunkt signalisiert. Über die Klinke kann man natürlich auch Daten zum PC laufen lassen, um dort erweiterte Auswertungen vorzunehmen. Baudrate ist von 57600 auf 115200 erhöht.

Da hat mir BASCOM noch einen Streich gespielt. Es verwendet nicht das U2X Bit zur Einstellung der Baudrate und bei dem 8MHz quarzgetakteten ATtiny2313 ist der Baudratenfehler dann 8,5%. Keine lesbaren Zeichen mehr am PC. "Manuelle" Nachbesserung mit U2X Bit bringt den Fehler laut Datenblatt auf -3,5%. Auf jeden Fall wieder guten Empfang.

https://www.roboternetz.de/community/attachment.php?attachmentid=34242&d=1562088748

Weiter gibt es noch eine blitzende LED, die ans Abschalten erinnern soll. Das Programmierkabel steckt noch und das blaue, zweiadrige Kabel geht rechts zum Simulator auf dem Steckbrett. Das Abnehmerkabel zum Zündkabel wird mit Minibananenstecker über die rote Buchse, rechts vom Ein-/Ausschalter verbunden.

Bevor ich einige der tollen Vorschläge zur Beruhigung der Anzeige von weiter oben im thread ausprobiere, möchte ich noch eine Umschaltung während einer Messsitzung probieren. So etwas wurde oben auch schon erwähnt. Allerdings möchte ich nicht zwischen Messung mit festem Zeitintervall und Impulsdauermessung umschalten, sondern nur bei niedrigen Drehzahlen die einfache Mittelwertberechung über einen längeren Zeitraum durchführen.

Bei höheren Drehzahlen, probiert habe ich mal 4500Upm, läuft der Zweitakter wesentlich ruhiger. Die letzte Methode mit Mittellung über ca. zwei Sekunden (zwei Anzeigezyklen) ist da schon gar nicht so schlecht. Die Ablesung im Leerlauf bei 2700Upm ist fast akzeptabel, wenn nur alle zwei Sekunden die Anzeige aktualisiert wird mit Mittellung über acht Sekunden. Die Reaktion auf Drehzahländerung ist dann natürlich echt zäh. Man hat beim Leerlauf allerdings auch nicht so ein Streß wie bei Vollgas und kann sich beim Einstellen Zeit lassen. Falls doch ein rechenintensiver Filter angewendet werden muß, dann nur bei niedrigen Drehzahlen. Das Programm ist dann auch nicht so zeitkritisch als wenn der Filter auch bei hohen Drehzahlen bis 16000Upm arbeiten muß.

Gruß
Searcher