PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Frequenzmesser bis 100Hz



bnitram
10.11.2012, 16:22
Hallo Forum,
Ich möchte mir gerne einen Frequenzmesser bauen der bis 100Hz arbeitet.
Wie wird das in Bascom programmiert??
Ich würde dafür gerne einen ATmega8 mit 4MHz Quarz benutzen.
Ich wäre euch für Antworten sehr dankbar.

Mfg
bnitram

MagicWSmoke
10.11.2012, 16:54
Glaubst Du, dass Du einen Code, den ich mal für ATMega32 geschrieben hab', umbasteln kannst ?

bnitram
10.11.2012, 17:19
Hallo MagicWSmoke,
Danke für deine schnelle Antwort. Ich denke das ich das schon irgend wie hinkriegen sollte. Ansonsten ist es aber mir bestimmt auch so eine Hilfe. Also wäre ich dir sehr dankbar wenn du das Programm mir schicken oder posten könntest.

Mfg
bnitram

MagicWSmoke
10.11.2012, 17:27
Dann versuch' Dich mal hiermit:

$regfile = "m32def.dat"
$crystal = 8000000
$hwstack = 64
$swstack = 64
$framesize = 64
Config Lcdpin = Pin , Db4 = Portd.4 , Db5 = Portd.1 , Db6 = Portd.5 , Db7 = Portd.0 , E = Portd.2 , Rs = Portd.3
Config Lcd = 16 * 2
Cursor Off

Const True = 1
Const False = 0
Const Measure_success = 0
Const Measure_failed = 1
Const Measure_request = 2

Dim Frequency As Long
Dim Capt_prev_val As Word
Dim Capt_curr_val As Word
Dim Measure_result As Long
Dim Capt_result As Word At Measure_result Overlay ' Differenz aus Capture beschreibt das Low-Word von Measure_Result
Dim Ovf_result As Word At Measure_result + 2 Overlay ' Mit dem Overflowergebnis das High-Word von Measure_Result beschreiben, spart das multiplizieren mit 65536
Dim Ovf_ctr As Word

Dim F_str As String * 10

' Variablen zur Ablaufsteuerung
Dim Got_edge As Byte
Dim Measure_status As Byte

Config Timer1 = Timer , Prescale = 1 ' , Noise Cancel = 1 ' , Capture Edge = Falling ' , Noise Cancel = 1

' Trigger durch Analogkomperator an Pin4, AIN1, AIN0 an Bandgap Reference 1V
Config Aci = On , Compare = On
Acsr.acbg = 1

On Capture1 Isr_capt Nosave
Enable Capture1

On Ovf1 Isr_ovf
Enable Ovf1

Ovf_ctr = 0
Got_edge = False
Tifr = Bits(icf1 , Tov1)
Enable Interrupts

Initlcd
Cursor Off Noblink
Cls
Locate 1 , 1
Lcd "START"
Wait 2

Cls
Do
Locate 1 , 1

Measure_status = Measure_request
While Measure_status = Measure_request
Wend
If Measure_status = Measure_failed Then
Lcd "Timeout K.Erg."
End If
If Measure_status = Measure_success Then
If Measure_result > 0 Then
Measure_result = Measure_result / 10
' Frequency = 826787928 / Measure_result ' Kalibrierung für abweichenden internen RC Oszillator
Frequency = 830996156 / Measure_result
' Frequency = 800000000 / Measure_result
F_str = Str(frequency)
Lcd "Freq: " ; Format(f_str , "000.000") ; " Hz"
Else
Lcd "Fehler, Ergebnis = 0"
End If
End If
Waitms 50
Loop

End

Isr_capt:
PUSH R22
LDS R22, ICR1L
STS {Capt_curr_val}, R22
LDS R22, ICR1H
STS {Capt_curr_val +1}, R22
POP R22
Pushall
If Measure_status = Measure_request And Got_edge = True Then ' Messung angefordert und eine Flanke erkannt ?
Capt_result = Capt_curr_val - Capt_prev_val ' Ja, dann Werte übernehmen
Measure_status = Measure_success
If Capt_curr_val < Capt_prev_val Then ' Natürlicher Overflow ?
Decr Ovf_ctr ' Bereichsgrenze überschritten, Overflows um 1 erniedrigen
End If
Ovf_result = Ovf_ctr
End If
Capt_prev_val = Capt_curr_val ' Aktuellen CAP-Wert speichern
Ovf_ctr = 0 ' Overflowzähler zurücksetzen
Got_edge = True
Popall
Return

Isr_ovf:
Incr Ovf_ctr
' If Ovf_ctr > 122 Then ' Niedrigste Messfrequenz 1 Hz unterschritten
If Ovf_ctr > 126 Then ' Korrektur für zu hohe RC Oszillatorfrequenz
Got_edge = False
Ovf_ctr = 0
If Measure_status = Measure_request Then Measure_status = Measure_failed
End If
Return
Edit:
µC wird momentan mit 'nem 16MHz Quarz betrieben, war noch so im Code gestanden, hab's geändert.
Musst die Werte halt auf 4MHz Takt anpassen.

EditEdit:
Hab' gerad' mal den ATMega8 als µC angegeben, das compiliert ohne Probleme. Es sollte also reichen den Takt auf 4MHz anzupassen, da ist nur:

Frequency = 830996156 / Measure_result
If Ovf_ctr > 126 Then

zu ändern. Dann LCD anpassen und der Analog-Comparator-Pin ist auch ein anderer.

Thegon
10.11.2012, 20:44
Hallo,

weil ich eigentlich auch gerade an einen Drehzahlmesser gedacht habe (und ich nehme an, es handelt sich noch um das Thema mit dem Benzinmotor)
habe ich das mal ausprobiert.
Ich habe leider auch nur einen ATmega16 herumliegen, das Programm ist also auch für Mega16, jedoch sollte es reichen, einfach die Pins, an die das Display angeschlossen ist, zu ändern.

Der Eingang ist Int0 (den es ja auch beim Mega8 gibt).
Die Umrechnung ist jetzt so ausgelegt, dass der Timer1 1Mio mal pro Sekunde tickt. Wenn man z.B. einen Quarz anderer Frequenz verwenden möchte müsste man das halt entweder im Prescaler oder in der Umrechnung ändern.


$regfile "M16def.dat"
$hwstack = 32
$swstack = 32
$framesize = 32
$crystal = 1000000

'Initialisiere Timer1
Config Timer1 = Timer , Prescale = 1
Enable Timer1
On Timer1 Isr_timer1

'Das LCD konfigurieren
Config Lcd = 16 * 2
Config Lcdpin = Pin , Db4 = Portc.2 , Db5 = Portc.3 , Db6 = Portc.4 , Db7 = Portc.5 , E = Portc.1 , Rs = Portc.0

'Den Int0 konfigurieren, er dient zum erfassen der Pulse
Config Int0 = Rising
Enable Int0
On Int0 Isr_puls

'Die Interrupts global aktivieren
Enable Interrupts

'Variablen Definieren
Dim Timer1_overflows As Byte
Dim Ticks As Long
Dim Rpm As Long

'Variable auf Null setzen, nur um sicher zu gehen
Timer1_overflows = 0
'Anfang Hauptprogramm +++++++++++++++++++++++++++++++++++++++++
Do

'Die Ticks in Umdrehunge pro Sekunde umrechnen
Rpm = 60000000 / Ticks

Cls
Locate 1 , 1
Lcd "Umdrehungen: "
Locate 2 , 1
Lcd Rpm

'Eine viertelsekunde warten, damit das Display nicht zu häufig
Waitms 250

Loop
'Ende Hauptprogramm +++++++++++++++++++++++++++++++++++++++++



Isr_puls:
'Es wurde ein Puls registriert


'Anzahl der Ticks ermitteln
Ticks = Timer1_overflows * 65536
Ticks = Ticks + Timer1

'Zurücksetzen
Timer1 = 0
Timer1_overflows = 0

Return

Isr_timer1:
'Timer 1 ist übergelaufen
Timer1_overflows = Timer1_overflows + 1
Return

Der Code ist getestet und hat bei mir funktioniert.

23694

Natürlich, es wurde ja schon Code gepostet, aber das habe ich jetzt gerade eben ausprobieren müssen und villeicht nützt es dir ja etwas ;-)

EDIT: Habe gerade gesehen, dass die Textphrase "Umdrehungen * 1/min: " garicht platz hat am LCD, siehe Foto.
Also im Code auf "Umdrehungen: " geändert...

Mfg Thegon

bnitram
10.11.2012, 22:08
Danke euch beiden!! :)
Vielen Dank für die beiden Programme.

@Thegon:
Ja genau für den Verbrenner war es gedacht....
Ich denke ich werde dann den Code von Thegon morgen mal testen, da er eh schon perfekt für meinen Einsatzzweck ist. Trotzdem Danke an MagicWSmoke.

Mfg
bnitram

bnitram
13.11.2012, 13:59
Hallo nochmal,
Werde erst heute zu dem Test kommen. Der Code funktioniert auf jedenfalls.
Ist es eig. egal wie lang ein "high" Signal ist oder ab wann beginnt der Timer zu zählen ??
Ist eine reine Verständnis frage.

Mfg
bnitram

Thegon
13.11.2012, 16:54
Der Interrupt ist auf Rising gestellt (siehe Konfiguration des Interrupts), d.h. die ISR wird ausgelöst, wenn die Spannung von Low auf High wechselt. Es wird also genau die Zeit gemessen, die vergeht, zwischen zwei solchen Vorgängen. Wie Lange oder kurz diese pulse sind, ist praktisch egal.

Mfg Thegon

bnitram
13.11.2012, 16:58
Ok vielen Dank für die info.
Bin heute leider von Test abgehalten worden. Der Hallsensor hat den Geist aufgegeben :(
Naja. Morgen wird ein neuer besorgt.

Mfg
bnitram

bnitram
14.11.2012, 18:02
Hallo Forum,
Heute habe ich den Drehzahlmesser testen können. Leider hat er nicht funktioniert.
Ich habe den Sensor via LED getestet und er hat funktioniert. Wenn ich die Beine vom Sensor berühre, dann gibt der LCD mir irgend welche Werte aus. Allerdings funktioniert das ganze zusammen nicht. Werde wohl nochmal alles durchchecken.
Hab Ihr noch welche Ideen woran das liegen könnte??

Mfg
bnitram

Thegon
14.11.2012, 18:20
Hast du irtendwie die Möglichkeit ein Signal zu erzeugen? Also z.B. 100Hz Rechteckspannung, mit einem Funktionsgenerator mit TTL Ausgang?
Oder einfach mal einen Taster mit einem Pullup anschließen und so ca. im Sekundentakt drücken, dann sollten ja ca. 60rpm rauskommen.

Wenn irgentwelche (sehr großen) Zahlen ausgegeben werden, dann wäre das eigentlich ein Anzeichen dafür, dass die Pulse garnicht richtig erfasst werden, und dass das ganze ab und zu mal überläuft (kommen auch manchmal negative Zahlen raus?)


Sonst fällt mir jetzt erst einmal nichts ein, weil an der Software sollte es ja nicht liegen, die hat ja schon mal bei dir funktioniert(?).

Mfg Thegon

bnitram
14.11.2012, 18:48
Danke Thegon für deine Antwort.
Habe das mal mit dem Raster getestet. Ging schneller :) Da hat auf Anhieb alles geklappt. Dann das ganze noch mal mit dem hallsensor getestet. Und siehe da.....es funktioniert. Der Fehler war mein steckbrett. Dort war ein Kontakt verbogen. Naja jetzt funktioniert es. Werde dann morgen den Test am Motor machen. Der ist jetzt zu laut. Aber vielen Dank für das Programm.

Mfg
bnitram

Thegon
14.11.2012, 19:00
Na dann Glückwunsch!

Freut mich wenn es funktioniert ;-)

Mfg Thegon

bnitram
15.11.2012, 17:01
Hallo zusammen,
heute konnte ich den Drehzahlmesser testen, in der Hoffnung den Motor einstellen zu können, ABER es gab da ein RIESEN Problem.
Wenn der Motor in Leerlauf Geschwindigkeit ist(also die fast tiefste Drehzahl die die Motor läuft ohne aus zu gehen) dann sollten ja Werte von 750 bis ca.1100 rauskommen. Der Motor dreht laut Hersteller auch nicht schneller als 4300, da er einen mechanischen Drehzahlbegrenzer besitz. Allerdings will ich den guten Motor keinem 50 Jahre alten Drehzahlbegrenzer an vertrauen. Wenn von dem Drehzahlmesser bekomme ich im Leerlauf allerdings angeblich schon 4250 UPM, was auf keinen Fall stimmen kann. Unter ca. Halbgas bekomme ich Werte um die 5500. Da is was auf jeden Fall nicht richtig. Hat jemand ne Idee woran das liegen könnte??

Mfg
bnitram

PS:
Wenn ich den Magneten jede sek. vor den Hallsensor halte dann bekomme ich trotzdem Werte um die 60.

Besserwessi
15.11.2012, 17:30
Es kann sein, dass der Motor mehr als einen Impuls pro Umdrehung erzeugt, sondern z.B. 4 oder 6. Die Pulse kommen dann schneller und täuschen eine höhere Drehzahl vor.

bnitram
15.11.2012, 18:11
Hallo Besserwissi,
Das kann ich eig ausschließen. Im Schwungrad sind Wuchtungs Löcher drin. Und in eins davon habe ich einen Magneten befestigt. Das heißt Drr sollte eig nur einen Kontakt pro
Umdrehungen haben.

Mfg
bnitram

Searcher
15.11.2012, 18:25
Vielleicht fängt die Zuleitung zum Hallsensor oder der Drehzahlmesser selbst Störungen vom Motor, Zündspule ... ein, die als Impuls gezählt werden. Wie man das wirksam abschirmt weis ich leider nicht. Drehzahlmesser eigene Stromversorgung oder am Bordnetz?

Gruß
Searcher

bnitram
15.11.2012, 19:13
Hallo zusammen,
Das Problem hat sich geklärt. Ich habe das ganze nochmal an meiner Standbohrmaschine getestet. Da ich dort ja auch feste Übersetzungen habe, habe ich es gut testen können und Musste feststellen das der Drehzahlmesser problemlos funktioniert. Das Problem liegt wohl darin, das ich durch den 1 Magneten das Schwungrad so Magnetisiere das ich mehrere " Störquellen" erzeuge. Ohne Magnet bekomme ich nämlich kein Signal. Das heißt eine Störung durch die Zündung kommt nicht in Frage

Mfg
bnitram

Thegon
15.11.2012, 20:58
Villeicht wäre Optisch doch auch eine Lösung?
Mit einer Gabellichtschranke und einer kleinen Schraube die irgendwo mitdrehend befestigt wird?
Die Frequenz liegt ja bei so ca. 100 Hz, da braucht es auch gar kein besonders schneller Typ oder so sein.
Man könnte sich dann halt sicher sein (sofern die Störungen nicht über das Kabel aufgefangen werden),
dass auch wirklich nur ein Puls pro Umdrehung rauskommt.

Aber ob das mechanisch möglich musst du entscheiden.

Mfg Thegon