PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : nocheinmal Drehzahlmessung



Florian.
08.06.2005, 16:15
Hallo,

wie schon in einem anderen Beitrag weiter unten erwähnt möchte ich gerne mit einem CNY70 die Drehzahl einer Welle erfassen und diese auf einem LCD ausgeben.

Dazu habe ich jetzt folgendes Programm geschrieben:



$regfile = "m8def.dat"
$crystal = 3686400
Dim Zaehlerstand As Byte
Dim A As Integer
Dim Drehzahl As Integer
Const Timervorgabe = 61936
Config Timer1 = Timer , Prescale = 1024
Enable Interrupts
Config Int0 = Falling
Enable Int0
On Int0 Zaehlen
On Timer1 Mytimer
Timer1 = Timervorgabe
Enable Timer1


Do
Config Lcd = 16 * 2
Cls
Lcd Drehzahl


End

Loop

Zaehlen:
Zaehlerstand = Zaehlerstand + 1


Mytimer:
A = Zaehlerstand
Drehzahl = A * 60
Print Drehzahl
Timer1 = Timervorgabe
Zaehlerstand = 0
Return

End


Ich möchte also mit dem Timer1 die Impulse pro Sekunde zählen. Statt dem CNY70 verwende ich zum testen nur einen Taster der Pb.0 (int0) auf 0V zieht.
Allerdings scheint sich in den Code noch irgendein Fehler eingeschlichen zu haben, weil sich auf dem Display nichts tut.

Ich würde mich freuen wenn jemand den Code überfliegen könnte.

Florian

PicNick
08.06.2005, 16:22
"Zaehlen:" hat keinen return ?

Florian.
08.06.2005, 16:29
das hab ich doch glatt übersehen. War aber scheinbar nicht der einzige Fehler, es tut sich genauso wenig.
Am Display liegt es sicher nicht, die Ansteuerung funktioniert soweit.
Trotzdem Danke für den Hinweis

edit: Habe jetzt selbst noch einen kleinen Fehler gefunden, der aber scheinbar immer noch nicht der letzte war. Das End mitten in der Do Loop Schleife war natürlich fehl am Platze.

Florian.
12.06.2005, 13:40
könnte es sein, dass mit der Reihenfolge am Anfanf des Programms etwas nicht stimmt? Muss ich den int0 (pb.0) als Eingang definieren?
Ich hab keine Ahnung mehr was sonst noch falsch sein könnte.

mfg

Florian

PicNick
12.06.2005, 14:00
Wenn ich nicht irre, fehlt

START TIMER1

Florian.
12.06.2005, 14:12
also mein Code sieht jetzt so aus:



$regfile = "m8def.dat"
$crystal = 3686400
Dim Zaehlerstand As Byte
Dim A As Integer
Dim Drehzahl As Integer
Const Timervorgabe = 61936
Config Timer1 = Timer , Prescale = 1024
Enable Interrupts
Config Int0 = Falling
Enable Int0
On Int0 Zaehlen
On Timer1 Mytimer
Timer1 = Timervorgabe
Enable Timer1
Start Timer1


Do
Config Lcd = 16 * 2
Cls
Lcd Drehzahl
Waitms 100
Loop

Zaehlen:
Zaehlerstand = Zaehlerstand + 1
Return

Mytimer:
A = Zaehlerstand
Drehzahl = A * 60
Print Drehzahl
Timer1 = Timervorgabe
Zaehlerstand = 0
Return

End


Aber funktionieren tut das ganze noch nicht.

Hat noch jemand eine Idee?

PicNick
12.06.2005, 14:25
Ehm, du meinst, der Timer1 springt nicht an oder zählt er nix ?
In der DO-Schleife solltest du nicht config LCD machen (einmal vorher reicht.
der Print bei mytimer sollte doch zu Terminal ? Hat der eine Baud-angabe ? ( $BAUD=nnnn )

Florian.
12.06.2005, 14:36
das Print in mytimer war überflüssig. Ich habs rausgemacht. Config lcd hab ich vor die Do Loop Schleife gemacht.

Ich weiss nicht ob der Timer nicht anspringt oder es am Zählen liegt. Wenn ich das Programm simuliere und auf int0 klicke, diesen also auslöse, sehe ich an den ganze Variablen keine Änderung. Ich habe ja den int0 auf die fallenden Flanken angesetzt. Kann es sein, dass das Simulieren deshalb nicht funktioniert?

PicNick
12.06.2005, 14:42
Na ja, um das zu wissen, mach den LCD Drehzahl in die Timer-Routine.
Zählt er nicht, müßt er ja wenigstens "Drehzahl=0" sagen
Dann mach umgekehrt in die INT0-Routine einen LCD "aua".
So läßt sich rauskriegen, geht und was NICHT.
Ich sag ehrlich, ich kann am Programm so nix böses sehen

PicNick
12.06.2005, 14:48
Noch eine Frage: Die Timereinstellungen: welche Zeit willst du haben ?

Florian.
12.06.2005, 14:53
also wenn ich in mytimer lcd "bla" schreibe, dann erscheint (vermutlich) jede Sekunde einmal bla auf dem Display. Wenn ich lcd Drehzahl in mytimer schreibe dann erscheint pro Sekunde einmal 0 im Display. Schreibe ich lcd "bla" in Zaehlen, dann passiert gar nichts. Auch nicht wenn ich den pb.0 (int0) mit einem Taster auf 0V ziehe.

also meine Diagnose: Timer geht, beim int0 ist was faul, nur was?!

siehst du das genau so?

edit: zu deiner 2. Frage...ich möchte eben die Impulse (Flanken) die in einer Sekunde an int0 ankommen. Diese werden dann in U/min umgerechnet und auf dem Display ausgegeben. Der Timer sollte also nach jeder Sekunde überlaufen.

PicNick
12.06.2005, 15:02
Einstellung: Wenn's funzt, hat sich die Frage erübrigt, die Absicht war eh' klar.

Ich fürchte, du mußt den INT0-Eingang mit Pullup-versehen
PORTB.0 = 1 (pullup intern)
einmal vor do..loop sollte reichen.
Oder ein externer Pullup-widerstand

Florian.
12.06.2005, 15:08
also der Code sieht jetzt so aus:



$regfile = "m8def.dat"
$crystal = 3686400
Dim Zaehlerstand As Byte
Dim A As Integer
Dim Drehzahl As Integer
Const Timervorgabe = 61936
Config Timer1 = Timer , Prescale = 1024
Enable Interrupts
Config Int0 = Falling
Enable Int0
On Int0 Zaehlen
On Timer1 Mytimer
Timer1 = Timervorgabe
Enable Timer1
Start Timer1
Config Lcd = 16 * 2
PORTB.0 = 1

Do
Cls
Lcd Drehzahl
Waitms 100
Loop

Zaehlen:
Zaehlerstand = Zaehlerstand + 1

Return

Mytimer:
A = Zaehlerstand
Drehzahl = A * 60
Timer1 = Timervorgabe
Zaehlerstand = 0

Return

End


auf dem Display steht nur 0_ und wenn ich int0 auf 0 ziehe passiert trotzdem nichts.

PicNick
12.06.2005, 15:26
Also, am Programm seh ich da mal nix mehr.
Du mußt am Taster messen, ob erst 5V und bei drücken 0V sind.
und, wenn geht, auch am Pin.
Nochmal nachsehen, ob's der richtige PIN ist.
GND Taster == GND Mega8 ?
Wenn's geht , ev. mit Testverbindung den Pin mal direkt auf GND ziehen.

Seltsam, mit dem INT0 kämpfen einige.

Ev. Probieren mit INT1 ?

Florian.
12.06.2005, 17:02
also an pb.0 liegen 5V an, bei Drücken des Tasters sind es 0V.
Ich habe jetzt mal testweise den int1 genommen, aber es funktioniert auch nicht. int1 ist schon pb.1 oder?

Guy
30.09.2005, 12:56
Ich möchte auch einen Drehzahlmesser bauen, darum benutze ich mal diesen Thread.

All die Beispiele für Drehzahlmesser die ich hier gefunden habe funktionieren alle gleich.


.ich möchte eben die Impulse (Flanken) die in einer Sekunde an int0 ankommen. Diese werden dann in U/min umgerechnet und auf dem Display ausgegeben. Der Timer sollte also nach jeder Sekunde überlaufen.

Also Impulse/ Sekunde Zahlen und mit 60 multiplizieren. Ich glaube aber daß dieses Messung falsch ist, denn in einer Sekunde kann die Drehzahl sich erheblich verändern.

Mann könnte jetzt jede Zehntelsekunde messen, und dann die Drehzahl ausrechnen. Was aber meiner Meinung nach auch nicht klapp. Weil ich ja bei einer Sekunde oder Zehntelsekunde nicht unbedingt eine Vollumdrehung hab.

Ich glaube der richtige Weg ist es, die Dauer zwischen zwei Impulse zumessen, und dann die Drehzahl errechnen.

Würde mal gerne andre Meinungen zu dem Problem hören.


mfg
guy

PicNick
30.09.2005, 13:38
"Kommt darauf an" ist immer eine gute Aussage. Je niedriger die Drehzahl (eigentlich die Impulszahl), desto besser der letztgenannte Weg.
Das gößte abdeckbare Bereich hast du, wenn du beide Methoden automatisch umschalten kannst.

ähM_Key
30.09.2005, 21:36
Je nach Aufbau kann das natürlich anders sein, aber ich hab große Probleme gehabt mit nem CNY70 große Drehzahlen zu messen. Bei kleinen alles kein Problem, aber wenn's dann an die 5000UpM gingen zumindest bei mir dann viele Takte verloren.

Nur so als Tip, falls jemand ähnliches vorhat.

Grüße; ähM_Key

pebisoft
30.09.2005, 22:13
wenn du 8mhz oder einen 16mhz nimmst, hast überhaupt keine probleme mit 20000 u/minute. bascom verschlingt intern zuviel zeit. ich kann mit meinem fastavr-basicprogramm mit 8 mhz über 18000 auslesen und dem cny70.
mfg pebisoft

ähM_Key
01.10.2005, 07:31
Bei mir lag's nicht am Controller, sondern dass dem CNY70 zwar soviel licht relfektiert wurde, dass er bei langsamen Drehzahlen schaltete aber bei größeren hat's dann nicht mehr ausgereicht.

MK

Guy
02.10.2005, 13:26
Hallo,

Ich habe meinen Drehzahlmesser jetzt soweit fertig. Und um es vorweg zu nehmen, das klappt auf die Drehzahl genau. (+/- 2 U/M) .ich habe ihn aber noch nicht am Motor getestet. Bis jetzt nur mit Frequenzgenerator die Drehzahl simuliert. Aber ob die Impulse vom Motor kommen oder vom Frequenzgenerator ist ja egal.

Anfangs war das ganze ziemlich ungenau, aber das lag daran, daß ich den internen Oszillator benutzt habe. Jetzt mit einem externen Quarz ist das genau. Der interne Oszillator scheint ziemlich viel von seiner Frequenz abzuweichen.

Was ich jetzt nicht verstehe sind Aussagen wie " bascom verschlingt intern zuviel zeit." Ich habe ja bei 18000 u/minute nur 300 Hz. Da müßte doch jeder Controller locker mit kommen, selbst wenn er nur mit 1 Mhz läuft.

Ich habe das so gemach, daß ich die Dauer einer Umdrehung messe. Also auf steigender Flanke warten und den Timer starte, auf die nächste steigende Flanke warten und dann den Timer auslesen und auf null setzen. Dann Berechnung durchführen, Drehzahl anzeigen und so weiter. Das kann ruhig einige Zeit dauern, auch wenn da einige Umdrehungen nicht gemessen werden, ist das nicht schlimm, denn ich zeige die Umdrehung ja nur alle 300-400 ms an, damit die anzeige ruhig steht und nicht flackert.

Von dem Prinzip währen einer gewiesenen Zeit die Impulse zuzählen, hallte ich nicht viel. Zumale wenn sich die Drehzahl in kurzen Abstände oft ändert. Denn dann muß man die Messzeit sehr kurz halten, und wenn da ein paar Impulse fehlen, und man das auf eine Minute hohe rechnet ist die Fehlerquote groß.

Bei konstanter Drehzahl mach das sicher Sinn. Wo man die Impulse während einer Minute mißt und die dann anzeigt.

Mit freundlichen Grüßen
Guy

Florian.
02.10.2005, 22:38
Hallo,

toll, dass es bei dir jetzt funktioniert. Könntest du vielleicht deinen Code veröffentlichen?

Gruss

Florian

Guy
03.10.2005, 07:45
Hallo Florian,

Ich werde den Code mal hier rein setzen, das kann aber ein paar Tage dauern. Ich muß nur meinen Loptop mal mit zur Arbeit bringen, denn Zuhause habe ich kein Internet. Ich will kein Internet Zuhause, denn sonst hänge ich zuviel auf dem Computer.

Bis dann,
Guy

PicNick
03.10.2005, 07:48
@Guy: Für das kann ich dir nur diese USB-Sticks empfehlen, wie es sie erstens überall und auch manchmal beim Aldi gibt. Wirklich praktisch, das Zeug.

Guy
03.10.2005, 08:25
Ja, ist eine Gute Idee. Ich habe ja erst meinen Computer vor einem Monat gekauft. Und das nur um meinen Datalogger vom Modellauto auszulesen. Ich wolle meine Freizeit nicht mehr wie Früher nur am Computer verbringen. Darum habe ich auch kein Internetanschluß .

Und da ich eine Schaltung für den Datalogger brauchte, habe ich auch wieder angefangen Controller zu progen.

Werde mir mal gleich im Supermark so einem USB-Sticks besorgen.


Danke für die Idee, und einen schönen Tag noch.
Guy

Guy
04.10.2005, 09:03
Hier mal meinen Code für den Drehzahlmesser.

Der soll die Drehzahl messen und dann die 5 oder 10 maximal Drehzahlen speichern. Das ist wichtig damit ich sehe ob das Modellauto mit der Übersetzung die Maximale Drehzahl erreicht. (Fehlt aber noch im Programm).

Dann soll der Drehzahlmesser zwischen z.B. 8000 und 9000 U/m eine Lampe an schalten. (einstellbar) Das ist um die Fliehkraftkupplungs einstellung zu vereinfachen. Denn die Kupplung darf nicht zu früh kuppeln und auch nicht zu spät.

Ich setzt mal den ganzen Code hier rein, wichtig ist aber nur der Code zwischen dem do –loop. Also die Hauptschleife.

Das Prinzip ist einfach. Auf Steigende Flanke (oder fallende Flanke) warten dann Timer starten, auf fallende Flanke warten, und wieder auf Steigende Flanke warten. Dann Timer aus lesen. Im Timer steht die Zeit von einer Umdrehung. Umdrehung ausrechnen usw.. Wenn das schneller geht als das Hi von der Steigende Flanke braucht, sollte man wieder auf fallende Flanke warten bevor man neu beginnt.

Ich arbeite erst seit 2-3 Wochen mit Bascom. Wenn einer was sieht was man besser machen kann, nur zu. Freue mich für jeden Vorschlag.









$regfile = "m16def.dat"
$crystal = 8000000
$baud = 19200
Config Lcdpin = Pin , Db4 = Porta.0 , Db5 = Porta.2 , Db6 = Porta.4 , Db7 = Porta.6 , E = Portc.7 , Rs = Portc.6
'Config Lcd = 16 * 2
Config Lcd = 16 * 1
'$sim


Dim Count1 As Single
Dim Rpm As Word
'Dim Temp As Single
Dim Uberlauf As Bit
Dim Menuselect As Byte
Dim Zylinder As Byte
Dim Lampe_an As Word
Dim Lampe_aus As Word

Config Timer1 = Timer , Prescale = 8

'On Timer1 Timer1_isr

Config Pind.4 = Output
Portd.4 = 1

Set Portb.0
Config Pinb.0 = Input ' eingang fur drehzahl
' ********* Menu Tasten *************
Config Pind.2 = Input
Set Portd.2
Config Pinb.4 = Input
Set Portb.4
Config Pinb.5 = Input
Set Portb.5
Config Pinb.6 = Input
Set Portb.6
Config Pinb.7 = Input
Set Portb.7
' ********* end Menu Tasten *************
On Int0 Menu_int0
Enable Int0
Enable Timer1
Enable Interrupts
Stop Timer1

Do
Bitwait Pinb.0 , Reset
Start Timer1
Timer1 = 0
Bitwait Pinb.0 , Set
Bitwait Pinb.0 , Reset
Stop Timer1
Count1 = Timer1
Count1 = 1000000 / Count1
Count1 = Count1 * 60

Rpm = Int(count1)
Cls
Cursor Off Noblink
Lcd Rpm ; " RPM"
If Rpm > Lampe_an And Rpm < Lampe_aus Then
Portd.4 = 0
Else
Portd.4 = 1
End If
Waitms 300
Bitwait Pinb.0 , Set
Loop

End 'end program



Timer1_isr:
Cls
Lcd "Fehler"
Waitms 100
Rpm = 0
Count1 = 0
Return




Menu_int0:
Menuselect = 0
Do
Waitms 100
If Pind.2 = 0 Then
Incr Menuselect


Do
Loop Until Pind.2 = 1
End If
If Menuselect > 6 Then
Menuselect = 1
End If
Select Case Menuselect
Case 1 'Max_drehzahl
Cls
Lcd "Drehzahl"
If Pinb.4 = 0 Then
Do
Loop Until Pinb.4 = 1
Gosub Max_drehzahl
End If
Case 2 'Motortype
Cls
Lcd "Motortype"
If Pinb.4 = 0 Then
Do
Loop Until Pinb.4 = 1
Gosub Motor_type
End If
Case 3 'Zylinder Zahl
Cls
Lcd "Zyl. Zahl"
If Pinb.4 = 0 Then
Do
Loop Until Pinb.4 = 1
Gosub Zyl_zahl
End If
Case 4 ' Lampe an
Cls
Lcd "Lampe an"
If Pinb.4 = 0 Then
Do
Loop Until Pinb.4 = 1
Gosub Lampe_an
End If
Case 5 ' Lampe aus
Cls
Lcd "Lampe aus"
If Pinb.4 = 0 Then
Do
Loop Until Pinb.4 = 1
Gosub Lampe_aus
End If
Case 6 ' ruruck
Cls
Lcd "return"
If Pinb.4 = 0 Then
Exit Do
End If
End Select
Loop
Return

Max_drehzahl:
'Cls
'Lcd "Max Drehzahl"
'Waitms 100
Return


Motor_type:
'Cls
'Lcd "Motor type"
'Waitms 100
Return


'***************************************
Zyl_zahl:
Cls
Do
Cls
Lcd "Zylinder"
Lcd Zylinder
Waitms 100
If Pinb.5 = 0 Then
Incr Zylinder
If Zylinder > 8 Then
Zylinder = 1
End If
Do
Loop Until Pinb.5 = 1
End If
If Pinb.6 = 0 Then
Decr Zylinder
If Zylinder = 0 Then
Zylinder = 8
End If
Do
Loop Until Pinb.6 = 1
End If
If Pinb.4 = 0 Then
Do
Loop Until Pinb.4 = 1
Exit Do
End If
Loop
Return

'*******************************************
Lampe_an:
Cls
Do
Cls
Lcd "Lam. An "
Lcd Lampe_an
Waitms 100

If Pinb.5 = 0 And Pind.2 = 0 Then
Lampe_an = Lampe_an + 100
If Lampe_an > 23000 Then
Lampe_an = 0
End If

End If
If Pinb.6 = 0 And Pind.2 = 0 Then
Lampe_an = Lampe_an - 100
If Lampe_an =< 0 Then
Lampe_an = 23000
End If

End If
If Pinb.5 = 0 And Pind.2 = 1 Then
Incr Lampe_an
If Lampe_an => 23000 Then
Lampe_an = 0
End If
End If
If Pinb.6 = 0 And Pind.2 = 1 Then
Decr Lampe_an
If Lampe_an =< 0 Then
Lampe_an = 23000
End If
End If
If Pinb.4 = 0 Then 'zuruck
Do ' enprellen
Loop Until Pinb.4 = 1
Dta1:
Data Lampe_an
Exit Do
End If
Loop
Return

'*******************************************
Lampe_aus:
Cls
Do
Cls
Lcd "Lam. aus "
Lcd Lampe_aus
Waitms 100

If Pinb.5 = 0 And Pind.2 = 0 Then
Lampe_aus = Lampe_aus + 100
If Lampe_aus > 23000 Then
Lampe_aus = 0
End If

End If
If Pinb.6 = 0 And Pind.2 = 0 Then
Lampe_aus = Lampe_aus - 100
If Lampe_aus =< 0 Then
Lampe_aus = 23000
End If

End If
If Pinb.5 = 0 And Pind.2 = 1 Then
Incr Lampe_aus
If Lampe_aus => 23000 Then
Lampe_aus = 0
End If
End If
If Pinb.6 = 0 And Pind.2 = 1 Then
Decr Lampe_aus
If Lampe_aus =< 0 Then
Lampe_aus = 23000
End If
End If
If Pinb.4 = 0 Then 'zuruck
Do ' enprellen
Loop Until Pinb.4 = 1
Exit Do
End If
Loop
Return

Majus
17.01.2006, 17:10
Ja,
ich wäre auch an dem Code interessiert, da ich auch eine Drehzahlmessung per CNY70 vor habe.
Majus