Hallo,
ich möchte mit einem induktiven sensor eine Drehzahl ausgeben. Der
Sensor ist ein PNP-Sensor, der mit 12V betrieben wird, welche dann über
einen Transistor in 5 V für einen Atmega 8 mit 16Mhz umgewandelt werden
und an den INT0 Pin gelegt werden.
Ich hab im Moment keine Möglichkeit die Software zu testen, könnt ihr
bitte mal drüberschauen, ob das so funktionieren wird ?
zur Funktionsweise: Es werden 5 Zeitmessungen zwischen den Impulsen
gemacht und daraus dann ein Mittelwert gebildet. Daraus wird dann die
Drehzahl berechnet und auf einem Lcd ausgegeben.
Hier die Auswertung des Interrupteinganges:
1
ISR(INT0_vect)
2
{
3
staticunsignedcharErsteFlankeErkannt=TRUE;
4
staticunsignedinti=0;
5
6
if(ErsteFlankeErkannt==TRUE)// Es wurde eine erste Flanke erkannt
7
{
8
Timer_01ms=0;// Timer für die Messung auf 0 setzen
9
ErsteFlankeErkannt==FALSE;
10
}
11
else
12
{
13
for(i=0;i<MAXVALUE;i++)
14
{
15
Messungen[i]=Timer_01ms;// für Zehn Impulse die jeweilige Zeit in Liste abspeichern
Thomas schrieb:> Ich hab im Moment keine Möglichkeit die Software zu testen, könnt ihr> bitte mal drüberschauen, ob das so funktionieren wird ?
Nein, sie wird nicht funktionieren.
Teste sie und beheb erst mal die offensichtlichen Fehler. Dann reden wir
weiter.
zb
1
for(i=0;i<MAXVALUE;i++)
2
{
3
Messungen[i]=Timer_01ms;// für Zehn Impulse die jeweilige Zeit in Liste abspeichern
4
ErsteFlankeErkannt==TRUE;
5
}
welchen Sinn soll es haben, den immer gleichen Messwert zb 5 mal
abzuspeichern? Du willst 5 verschiedene Messwerte abspeichern, die du
erhältst indem die ISR 5 mal aufgerufen wurde jeweils einzeln
abspeichern.
1
for(i=0;i<MAXVALUE;i++)
2
{
3
Summe=Messung+Messungen[i];
4
}
das ergibt aber keine Summe.
Wie gesagt: teste das alles mal. Zur Not geht das auch ohne µC, indem du
Computer spielst und dein Programm abarbeitest :-) Ganz im Gegenteil
sind solche Simulationen sehr erhellend.
Da sind so viele Fehler drin, da weiss man ja gar nicht wo man anfangen
soll. Als erstes wäre es ja mal schön, wenn du ein ohne Fehler
compilierendes Programm einstellen würdest ...
Danke für die Antworten.
Sorry für die Fehler, aber ich habe im Moment nur Notepad
hier...........
Also ich hab da mal die beiden Fehler berichtigt, jetzt müsste das so
passen:
Es wird besser, aber mit neuen Fehlern.
Aber mal grundsätzlich: Dein ISR(INT0_vect) wird andauernd getriggert.
Deine Hauptschleife erwartet aber eine sich nicht während der
Mittelwertberechnung verändernde Datenstruktur. Das wird aber passieren!
Du möchtest doch eine Drehzahl messen und einen gemittelten Drehzahlwert
ausgeben, nicht?
Am einfachsten wäre das, wenn du in deiner ISR einfach 5 Impulse
abwartest und die Zeit dazwischen misst. Voila, ein Mittelwert.
Nur wenn du einen gleitenden Mittelwert mitführen möchtest (und
brauchst du das wirklich?), nur dann brauchst du einen Array als
Zwischenspeicher. Dann aber in Form eines Ringpuffers mit
synchronisiertem Zugriff.
Überdenk noch mal deinen Ansatz.
LG, Sebastian
Was ist denn, wenn ich während der Berechnung des Mittelwertes die
Interrupts nicht zulasse, dass für die Zeit der Berechnung auch wirklich
nur die Berechnung und Ausgabe auf dem Display durchgeführt wird.
Sonst kann man dann doch genausogut zwischen 2 impulsen messen und
daraus dann die Drehzahl berechnen...
Das Problem in deinem code ist nicht nur, die Interrupts nicht
zuzulassen. Es ist ja gar nicht garantiert, dass der Array an der Stelle
schon vollständig gefüllt ist bzw. nicht gerade schon wieder begonnen
wurde ihn zu füllen.
Dazu kommt, dass mir nicht so klar ist, was du eigentlich abspeichern
willst. Die Zeit seit der ersten Flanke? Oder die Zeit seit dem letzten
Impuls?
Also ich möchte die Zeit seid dem letzten Impuls abspeichern. Also um
die korrekte Befüllung zu gewährleisten kann man ja einen Merker setzen,
dass die Messung voll ist und dieser Merker wird erst von der
Auswertfunktion wieder zurückgesetzt.
Das mag doch so gehen oder ?
Ja, das kann man so machen.
Und solange der Merker von der Auswertung nicht zurückgesetzt wird, hält
sich die ISR zurück und schreibt keine Messwerte ins Array.
Über welche Drehzahlen reden wir eigentlich?
Also Drehzahlen von 500 bis max 4000 Umdrehungen.
Ich hab den Code noch mal überarbeitet, wenn da jetzt noch mal jemand
drübergucken kann. Hab den auch ohne Fehler kompilieren können.
gefahr läufst, während der Berechnung in einen Overflow zu laufen.
Moment.
Die ganze Berechnung sieht komisch aus. Das kann nicht stimmen
Mittelwert * .......
Drehzahl = ----------------------------
Mittelwert
da kürzt sich der Mittelwert weg und übrig bleibt nur das, was sich aus
deinen Konstanten ergibt. Nochmal zurück an den Block und die Formel
noch mal neu herleiten. Die stimmt sicher nicht.
Umdrehungen pro Jahr?
for( i=0; i<MAXVALUE; i++) ist in der ISR schon wieder zurück -- das
hatten wir doch schon :(
Und dann diese vielen Variablen (MessungVorhanden, ErsteFlankeErkannt,
i) und der komplexe Code dadurch ... phew.
Wenn du schon die einzelnen Zeiten vorhalten willst, warum dann nicht
einfach:
ISR(INT0_vect) {
if (AnzahlMessungen<MAXVALUE) {
Messungen[AnzahlMessungen] = Timer_01ms;
AnzahlMessungen++;
}
}
Und dann baust du alles andere darum herum.
if(MessungVorhanden==TRUE)// Es liegt eine komplette Messung vor
2
{
3
cli();
4
startMeasure();// Starten der Drehzahlmessung
5
sei();
6
printMeasure();// Ausgabe der Drehzahl auf dem Lcd
7
MessungVorhanden=FALSE;// Es kann wieder eine neue Messung beginnen
8
}
Kann man so machen(*). Hauptsächlich weil dein Progrqamm nicht sehr
zeitkritisch ist. Bei 4000 U/min langweilt sich dein µC sowieso.
Aber grundsätzlich: Die ISR könnte bereits wieder mit dem Sammelnb von
Werten beginnen, wenn der Mittelwert berechnet ist. Während das Ergebnis
für die Ausgabe aufbereitet und ausgegeben wird, gibt es keinen Grund
das Messarray zu sperren.
(*) nein, kann man nicht.
DIe Interrupts sperren ist keine gute Idee. Denn Interrupts werden
deswegen ja nicht ignoriert, sondern sie werden nur solange verzögert,
bis die Interrupts wieder freigegeben werden. :-)
Und das bedeutet bei dir: du misst dann eine falsche Zeit.
OK. spielt insofern keine Rolle, weil du mit MessungVorhanden sowieso
die Messaufnahme gestoppt hast. Aber: Wenn die sowieso gestoppt ist und
daher sicher gestellt ist, dass die ISR das Array nicht beschreiben
wird, gibt es auch keinen Grund die Interrupts zu sperren.
-> Das ist ein komplexes Zusammenspiel von 8 Merker Variablen, 12
Countern, 78 Hilfsvariablen. Ein deutliches INdiz, dass man gerade drauf
und drann ist, sich selbst auszutricksen mit unnötiger Komplexität
Ok, Ok danke für die vielen Anregungen.
Also mit den Interrups sperren hab ich verstanden, die amch ich raus.
Was ist denn mit der itoa Funktion, die wandelt doch einen int in einen
String um oder nicht ?
Die for Schleife habe ich geändert, warum die da noch drin war .....ka
;-)
Mh mit der Berechnung werd ich noch mal gucken:
Ich habe 2 Impulse pro Umdrehung. der Timer zählt alle 0,1ms hoch.
Nach Bilden des Mittelwertes habe ich die Zeit zwischen 2 Impulsen, also
den Wert * 2 ist die zeit pro komplette Umdrehung.
Also den Wert * 10 habe ich den Wert in ms. Dann muss ja die Umrechnung
in s gemacht werden, also 1000ms durch den vorher berechneten Wert und
dann noch mal 60 für U/min
Thomas schrieb:> Ich habe 2 Impulse pro Umdrehung. der Timer zählt alle 0,1ms hoch.> Nach Bilden des Mittelwertes habe ich die Zeit zwischen 2 Impulsen, also> den Wert * 2 ist die zeit pro komplette Umdrehung.
Ok.
> Also den Wert * 10 habe ich den Wert in ms. Dann muss ja die Umrechnung> in s gemacht werden, also 1000ms durch den vorher berechneten Wert und> dann noch mal 60 für U/min
Ähem. Wenn ich 100 0,1ms-Impulse zähle, dann sind das 100*10=1000 ms???
Thomas schrieb:> Ich habe 2 Impulse pro Umdrehung. der Timer zählt alle 0,1ms hoch.> Nach Bilden des Mittelwertes habe ich die Zeit zwischen 2 Impulsen, also> den Wert * 2 ist die zeit pro komplette Umdrehung.>> Also den Wert * 10 habe ich den Wert in ms.
Fast.
> Dann muss ja die Umrechnung> in s gemacht werden, also 1000ms durch den vorher berechneten Wert
Du dividierst aber nicht durch 'den vorher berechneten Wert'
Mh da muss ich noch mal nachrechnen.......
Stimmen die Timer denn so, weil ich hab das Programm grade geflasht und
mit nem taster an INT0 die Drehzahl simuliert und da kommt nur Mist.
Gebe da immer die Mittelwerte mal die Polpaarzahl aus....
if(ErsteFlankeErkannt==TRUE)// Es wurde eine erste Flanke erkannt
7
{
8
Timer_01ms=0;// Timer für die Messung auf 0 setzen
9
ErsteFlankeErkannt=FALSE;
10
}
11
else...
12
}
Zweiter Aufruf:
1
if(MessungVorhanden==FALSE)
2
{
3
if(ErsteFlankeErkannt==TRUE)// Es wurde eine erste Flanke erkannt
4
...
5
else
6
{
7
if(AnzahlMessungen<MAXVALUE)// Kontrolle, ob nicht die max Anzahl der Werte überschritten wurde
8
{
9
Messungen[AnzahlMessungen]=Timer_01ms;// aktuelle Zeit abspeichern
10
ErsteFlankeErkannt=TRUE;
11
AnzahlMessungen++;// Zähler für nächste Messung erhöhen
12
}
13
else
14
...
15
}
16
}
Dritter Aufruf:
1
if(MessungVorhanden==FALSE)
2
{
3
if(ErsteFlankeErkannt==TRUE)// Es wurde eine erste Flanke erkannt
4
{
5
Timer_01ms=0;// Timer für die Messung auf 0 setzen
6
ErsteFlankeErkannt=FALSE;
7
}
8
else...
9
}
Vierter Aufruf wieder wie zweiter Aufruf.
Du misst also die Zeit von Drehzahlimpuls 1 bis Drehzahlimpuls 2, dann
die Zeit von Drehzahlimpuls 3 bis Drehzahlimpuls 4, dann 5-6, 7-8, 9-10.
Aber warum misst du nicht 1-2, 2-3, 3-4, 4-5, 5-6?
Das erwartet man so nicht. Ist das wirklich so gewollt?
Thomas schrieb:> Stimmen die Timer denn so, weil ich hab das Programm grade geflasht und> mit nem taster an INT0 die Drehzahl simuliert und da kommt nur Mist.
a) ist der Taster entprellt
b) kannst du schnell genug tasten damit keine Überläufe entstehen?
if(Summe==0)// Wenn keine Werte abgespeichert wurden
10
{
11
Drehzahl=0;// Es wurde keine Drehzahl gemessen
12
returnDrehzahl;
13
}
14
else
15
{
16
Mittelwert=Summe/MAXVALUE;// Bildung des Mittelwertes der Messungen
17
Drehzahl=Mittelwert*POLANZAHL/1000;// Zeit zwischen den Impulsen mal Pole mal 10 (Umrechnung 0,1ms in 1ms) mal 1000/Mittelwert (1ms in 1s) mal 60 (1s in 1m)
18
returnDrehzahl;
19
20
Summe=0;// Summe für nächste Messung wieder zurücksetzen
21
AnzahlMessungen=0;
22
}
23
24
}
ist auch noch ein Fehler drinn.
Das 0 setzen der Summe wird nicht erreicht, weil vorher der return
stattfindet.
Warum setzt du nicht die Summe ganz einfach 0, BEVOR du in der Schleife
dann die Einzelteile darin aufsummierst?
Und welchen Sinn soll es haben die Variable ANzahlMessungen static zu
machen? Das ist eine ganz einfache lokale Variable, deren einziger Zweck
es ist, dir als Laufvariable in der for Schleife zu dienen. Die muss
nicht static sein!
Lerne mit deinem Debugger um zugehen! Das kann doch nicht ewig so
weitergehen, dass dir hier die Leute deine Fehler zeigen. Es ist schon
ok, wenn man am laufenden µC nur sieht, dass die Sache nicht
funktioniert. Aber dazu hast du deinen Debugger, damit du deinem
Programm (in der Simulation) während der Arbeit zusehen kannst, dir
Variablen ansehen kannst, die Logik kontrollieren kannst.
Moin,
dann werde ich mich heute mal um den Debugger kümmern. Sollte man da
lieber AVR Studio zum Simulieren nehmen oder mit Eclipse arbeiten ?
Und noch was zum Entprellen: Also normale Eingangspins zu entzprellen
wurde ja schon oft beschrieben, aber wie muss man denn einen
Interrupteingang entprellen, wenn man es softwaremäßig und nichr
hardwaremäßig entprellen möchte ?
Thomas schrieb:> Und noch was zum Entprellen: Also normale Eingangspins zu entzprellen> wurde ja schon oft beschrieben, aber wie muss man denn einen> Interrupteingang entprellen, wenn man es softwaremäßig und nichr> hardwaremäßig entprellen möchte ?
Wenn man einen Interrupt Eingang entprellen muss, dann macht man etwas
grundsätzlich falsch. Denn die beiden Dinge beißen sich.
Einen Interrupt Eingang benutzt man, wenn man unbedingt so schnell wie
möglich auf ein externes Ereignis reagieren muss. Punkt.
Entprellen hingegen bedeutet, dass man irgendeine Form der Zeitsteuerung
hat, um alle Pinbewegungen unterhalb einer gewissen zeitlichen Schwelle
als 'falsche Alarme wegen Prellens' zu unterdrücken.
D.h. man hat hier kontradiktorische FOrderungen. Auf der einen Seite 'so
schnell wie möglich', auf der anderen Seite 'lass uns ein wenig warten
um zu sehen, ob es falscher Alarm ist'. Das geht nicht zusammen.
Daraus folgt: Taster einzulesen, indem man sie an einen Interrupt
klemmt, ist Nonsense. Regelmässiges Pollen durch zb einen Timer tut es
auch und erledigt das Entprellen im selben Aufwasch gleich mit.
Du hast jetzt natürlich einen Sonderfall, indem du den Taster als
Simulation deines richtigen Eingangs benutzt. Gut, bei denen Zahlen
hätte es Pollen genauso zuverlässig getan - dafür müsste man keinen
Interrupt benutzen, aber seis drum. Da der Taster nur zum Testen ist,
würde ich mir ansehen, ob Prellen momentan überhaupt ein Problem ist.
Wenn deine Taster einigermassen neu und von guter Qualität sind, stehen
die Chancen nicht schlecht, dass sie NOCH NICHT prellen. Für die paar
Tage, die sie noch für die Entwicklung gebraucht werden, ist das schon
ok.
Allerdings: Ich würde mir da überhaupt keinen Taster anschliessen. Ich
sag dir auch wieso. Eines der Um und Aufs der Entwicklung bzw. des
Programmtestens bzw. des Debuggens ist es, dass man REPRODUZIERBARE
Testbedingungen hat. Das ist das ein. Das andere ist, dass man im
Vorfeld schon weiß, was (welche Zahlenwerte) das Programm eigentlich
errechnen müsste. D.h. in deinem Fall: Anstatt da mit einem Taster
rumzumachen schnapp ich mir eine bekannte Frequenz, zb mit einem 555
erzeugt oder zb aus den 50Hz der 230V abgeleitet (zb mit der
Schreibtischlampe die mit ihren 50Hz einen Phototransistor schaltet).
Oder aber, warum nicht?, ich lass mir vom µC selber an einem Pin mittels
Timer eine Frequenz erzeugen, die das restliche Programm messen soll :-)
Aber egal wie, ich hab dann reproduzierbare Bedingungen von einem Test
Durchgang zum nächsten.
Hallo Thomas,
du hast meine Frage zu deiner ISR noch nicht beantwortet :)
Noch ein paar generelle Hinweise zu deinem code:
* Variablen, die nur in einer Prozedur benutzt werden, sollten auch nur
in dieser einen Prozedur lokal deklariert werden. Du machst das in der
ISR gut mit ErsteFlankeErkannt und AnzahlMessungen. Summe zum Beispiel
sollte aber auch lokal nur in startMeasure bekannt sein.
* Lokale Variablen sollten nur static deklariert werden wenn der Wert
zwischen Prozeduraufrufen erhalten werden muss. AnzahlMessungen in
startMeasure sollte also nicht static sein.
* Konstrukte wie if (ErsteFlankeErkannt == TRUE) bzw. if
(MessungVorhanden == FALSE) sind unschön. Wahrheitswerte sind
Wahrheitswerte, sie sollten nicht mit TRUE bzw. FALSE verglichen werden.
Ich finde if (ErsteFlankeErkannt) bzw. if (not MessungVorhanden) auch
viel lesbarer.
* Prozedurnamen sollten immer den Zweck der Prozedur erklären.
startMeasure startet aber gar nicht die Messung.
* startMeasure() liefert einen Wert zurück. Zusätzlich verändert
startMeasure() aber die global Variable Drehzahl. Ent oder weder.
* Deine Drehzahlberechnung ist immer noch falsch. Sieh mal, wenn der
Mittelwert, also die gemittelte Zeit zwischen den Impulsen, steigt,
dann steigt auch deine Drehzahl. Dass kann nicht sein.
Nimm dir mal etwas Zeit, überarbeite das Programm entsprechend, und dann
sehen wir weiter ob noch kleinere Macken drin sind.
LG, Sebastian
Hallo,
in deinen Berechnungen ist auch noch ein Fehler, wenn du die korrekten
Werte haben möchtest, musst du mit float arbeiten, da dir dann auch die
genauen Kommawerte berechnet werden und keine gerundeten Werte.
Die Berechnung der drehzahl müsste außerdem folgendermaßen aussehen:
1000ms
--------------------------- * 60 U/min
Drehzahl = Mittelwert * POLZAHL
------------
10ms
Gruß
Karl Heinz Buchegger schrieb:> Daraus folgt: Taster einzulesen, indem man sie an einen Interrupt> klemmt, ist Nonsense. Regelmässiges Pollen durch zb einen Timer tut es> auch und erledigt das Entprellen im selben Aufwasch gleich mit.
Da widerspreche ich Dir, denn nicht jeder mechanische Schaltkontakt wird
per Finger ausgelöst (Reedrelais), prellt dennoch und will schnell
erkannt werden. Ich will es hier aber nicht weiter ausführen.
Ich hatte vor einiger Zeit das Schaltverhalten von zwei
unterschiedlichen Tastern aufgezeichnet und auch gezeigt, wie man per
Interrupt entprellen kann.
Beitrag "Re: Entprellen von Schalter mit Interrupt und PinChange"
Danke für die vielen Antworten / Verbesserungsvorschläge.
Ich hab den Code so angepasst, wie ich meine, wie ihr es meint:
Fazit: Beim tastendrücken werden vernünftige Werte angezeigt. Heute
Abend werde ich es mit einem Sensor mal ausprobieren.
In der ISR werden jetzt auch immer der 1-2 2-3 3-4 4-5 5-6 Zeitabstand
gemessen, wie ich es auch eigentlich wollte ;-)
Ist das mit meinen float Werten bei der Berechnung denn so richtig, da
bei der Berechnung eine fehlende Kommastelle doch schon eine große
abweichung bewirken würde.
Gruß
Du hast noch nicht alles berücksichtigt, es sieht aber schon besser aus.
Was noch zu tun wäre:
volatile unsigned int Summe = 0;
-> kann oben wegfallen
unsigned char MessungAuslesen = 0;
-> verschieben nach Measure()
unsigned char lcdDrehzahlString[8];
-> verschieben nach printMeasure()
float AktuelleDrehzahl = 0;
-> verschieben nach main()
ErsteFlankeErkannt
-> umbenennen in erwarteErsteFlanke
unsigned int Measure()
-> unsigned float Measure ()
-> return Drehzahl; ans Ende der Funktion. Wo immer möglich sollte eine
Funktion am Ende einen return-Ausgang haben. Hier ist es sehr einfach
möglich und spart auch noch eine Zeile ein.
printMeasure(float Drehzahl)
-> Du ruft utoa mit einem float auf. Solche versteckten Typwandlungen
könnnen oft zu fiesen Fehlern führen.
LG, Sebastian
Hallo,
ich habe den ausgabewert fürs Display wieder auf int gekastet, dann
werden die Kommastellen eben aufgerundet.
Habe grade eben mit dem Drehzahlsensor ausprobiert und vorher mit einem
anderen die Drehzahl vorgemessen zwecks Vergleich.
Der PNP induktive sensor ist über einen Spannungsteiler(da12V) an den
INT0 angeschlossen.
Es werden Drehzahlen angezeigt, jedoch um bis zu 1000Umdrehungen
schwankend. obwohl die drehzahl konstant anliegt. Fuses ist ein externer
High Frequenty Quarz eingestellt, am Atmega 8 ist dann der 16Mhz Quarz
angeschlossen.
Wodran kann das jetzt noch liegen ?
Code noch mal im Anhang mit den Verbesserungen noch mal danke dafür
Oszilloskop oder Logikanalysator an INT0, da könnten ja Störungen drauf
liegen, oder die Flanke ist nicht sauber, was dann natürlich massiv die
Messung beeinflusst.
Wenn öfters zwei Impulse fehlerhaft ganz kurz hintereinander auflaufen,
dann könntest du das im Programm recht einfach abfangen dadurch dass du
deine ISR verlässt falls Timer_01ms einfach zu klein ist um Sinn zu
machen.
Schau dir die falschen Werte mal genauer an, und/oder protokolliere in
Measure() die gemessenen rohen Zeiten auf Messungen[] auf die serielle
Schnittstelle. Kann es sein dass die Falschmessungen dadurch entstehen
dass die fünf Impulse in der Zeit einlaufen die bei korrekter Messung
vier Impulse brauchen würden?
Ein kleiner Kinken ist auch noch im Programm: return Drehzahl; in float
Measure() muss hinter den else-Block.
LG, Sebastian
Mh,
also Logikanalysator oder Oszzi hab ich leider net :-(. Ausgaben auf der
seriellen schnittstelle könnte ich wohl einrichten.
Aber eig müsste das mit den 5 Messungen egal sein, ob nun 5 oder 4, weil
wenn die Drehzahl, welche anliegt konstant ist, sich auch die werte alle
konstant verhalten sollten. Außerdem sind die Pole genau 180°
verschoben, also können da keine fehler auftreten.
Vll sollte man echt lieber erst einen Filter davorsetzen. welchen sollte
ich den nehmen, so einen Hoch oder Tiefpass, wie aus dem Tut hier ?
Hallo,
ich habe jetzt einfach mal mit einem taster(neu, nicht entprellt, weil
ich dafür keine Bauteile hab)
Folgende Werte konnte ich aufzeichen beim ziemlich gleichmäßigem drücken
des Tasters. Diese Werte zeigen deutlich die Nicht Entprellung des
tasters oder ist da noch in der Software was falsch ?
Ach ja die Werte sind immer die 5 Messwerte zwischenden Impzlsen, welche
danach gemittelt werden.
Wert: 1179
Wert: 14
Wert: 6
Wert: 8
Wert: 4
Wert: 3131
Wert: 3075
Wert: 2989
Wert: 12553
Wert: 170
Wert: 2587
Wert: 3756
Wert: 4
Wert: 0
Wert: 8
Wert: 337
Wert: 191
Wert: 2366
Wert: 3206
Wert: 688
Wert: 42
Wert: 42
Wert: 2989
Wert: 6
Wert: 191
Wert: 3
Wert: 69
Wert: 2961
Wert: 1
Wert: 13
Welchen Filter kann ich am einfachsten und mit vauteilen realisieren,
welche ich auch hoffentlich zu Hause habe ?
Gruß
Thomas schrieb:> Ach ja die Werte sind immer die 5 Messwerte zwischenden Impzlsen, welche> danach gemittelt werden.
Also sind das jetzt die Werte wie sie in Messungen[] drinstehen? Also
die Anzahl der 100μs-Impulse seit dem letzen Impuls? Und die Ausgabe auf
die serielle Schnittstelle ist wirklich in Measure() und nicht in der
ISR?
Also die Ausgabe über uart ist in der measure Funktion. Und da werden
genau die 5 zwischenwerte ausgegeben.
Können solche Schwankungen wirklich vom prellen kommen ?
Thomas schrieb:> Welchen Filter kann ich am einfachsten und mit vauteilen realisieren,> welche ich auch hoffentlich zu Hause habe ?
Geschickterweise bewertet man die fallenden Flanken bei der Messung.
Für erste, einfache Versuche reicht Folgendes:
Aktiviere den Pullup zum INT-Eingang und schalte von diesem Eingang
100nF gegen GND. Im Ruhezustand ist der Kondensator auf VCC aufgeladen.
Über einen 10k Widerstand in Reihe zum Taster schaltest Du den Eingang
gegen GND.
Wenn alles nicht funktioniert, gibt es in der Codesammlung auch Beiträge
zur Drehzahlmessung.
Also ich habe jetzt mal die negative Flanke gemessen und siehda, die
Messwerte sind schon wesentlich besser.
Wert: 103
Wert: 785
Wert: 5282
Wert: 5908
Wert: 5041
Wert: 5641
Wert: 5907
Wert: 5507
Wert: 5743
Wert: 5699
Wert: 696
Da sind noch einige totale Abweichungen, aber die schieben wir mal auf
den nicht entprellten Taster. Ich habe jetzt 10k gegen VCC und dann den
Taster gegen GND. Die variante mit dem Kondensator und Widerstand
parallel hat gar nicht gefunzt. Ich glaub das is auch ein bissl falsch
erklärt oder ?.
Ich werde mir jetzt einen 74HC 14 kaufen und damit eine Entprellung so
wie imForum erklärt bauen. Ist das denn genau genug, wenn ich die
durchgeschaltete Spannung vom Sensor über einen Spannungsteiler dann auf
den Schmidt Trigger lege ?
Es kann auch an deiner Eingangsschaltung für den Sensor liegen. Ich weiß
nicht, ob das einfach mit einem PNP-Transistor hinhaut, ob der sauber
sperrt und wie die Flanken aussehen.
Kannst du mal den genauen Schaltplan posten und wenn möglich auch ein
paar Infos über den Sensor rausrücken?
Thomas schrieb:> Die variante mit dem Kondensator und Widerstand> parallel hat gar nicht gefunzt. Ich glaub das is auch ein bissl falsch> erklärt oder ?.
Von Kondensator und Widerstand parallel ist auch nirgends die Rede.
Liebe Grüße noch an Herrn Schmidt!
Also ich hatte den Sensor einfach mit nem einfachen Spannungsteiler an
den Eingang des Atmega 8 gehängt. Ohne Transistor, etc.
Der Sensor ist der im Anhang.
Ich habe mit einem Frequenzgenerator meine Software ausprobiert und habe
dort eine Genauigkeit von + - 1 Umdrehung. Also die Software wertet das
Eingangssignal schon mal sehr genau aus.
Jetzt muss halt nur noch geguckt werden, wie ich die Eingangsflanken vom
sensor stabil und ohne Prellen hinbekomme.
Hallo,
jetzt hab ich doch noch mal eine frage bezüglich des Spannungsteilers.
Wie groß ist der innenwiderstand des Atmega 8 Einganges, damit ich den
belasteten Spannungsteiler berechnen kann.
Gruß
Thomas schrieb:> Hallo,>> jetzt hab ich doch noch mal eine frage bezüglich des Spannungsteilers.> Wie groß ist der innenwiderstand des Atmega 8 Einganges, damit ich den> belasteten Spannungsteiler berechnen kann.
Für alle praktischen Zwecke kannst du ihn ignorieren.
Einen eingeschalteten Pullup Widerstand kannst du mit rund 35kOhm in
Richtung Vcc in Rechnung stellen. Also auch hier wieder: Wenn du deinen
Spannungsteiler auf 10k Gesamtwiderstand auslegst ist das eine zu
vernachlässigende Größe.
Also ich habe jetzt mit einer Eingangsspannung von 13V gerechnet (hängt
an einer Batterie). Ausgangsspannung sind die 5V, welche direkt an den
Eingangspin vom Atmega 8 gehen.
Dann habe ich für R2 4,7kOhm angenommen und somit ergibt sich für R1
7,2kOhm:
------- -------
+12V---------| R1 |-------- --------| R2 |------------ GND
------- | -------
|
5V
Jetzt werte ich per software ja die positiven Flanken aus. Wie ist ds
mit dem PullDown Widerstand, reichen da die 4,7k jetzt oder muss ich da
zusätzlich noch einen Widerstand gegen GND setzen ?
Gruß
Thomas schrieb:> Jetzt werte ich per software ja die positiven Flanken aus. Wie ist ds> mit dem PullDown Widerstand, reichen da die 4,7k jetzt oder muss ich da> zusätzlich noch einen Widerstand gegen GND setzen ?
Wofür brauchst du noch einen Pull Down? Jeder zusätzlicher Widerstand
würde dir den Spannungsteiler verstellen.
Das ist gut so.
Wenn der Eingang an einer Autobatterie hängt solltest du dir allerdings
noch die Infos zu Schutzmaßnahmen durchlesen, da in einem KFZ ziemlich
gemeine Störungen auf dem Bordnetz sein können:
http://dse-faq.elektronik-kompendium.de/dse-faq.htm#F.23
Hallo,
Danke für den Tipp, aber das ist einen einzelne kleine Gelbatterie,
welche in einem Gehäuse sitzt, damit der Drehzahlmesser transportabel
ist. Also können da vom KFZ keine Störgrößen draufkommen.
Gruß
Hallo,
wollte mich noch einmal für die große Unterstützung bedanken, Drehzahl
wird jetzt genau angezeigt, habe einen anderen Sensor genommen und mit
dem funktioniert es wunderbar.
Gruß