Drehzahlmesser mit 4 stelliger 7Segment-Anzeige

dino03

Aktives Mitglied
27. Okt. 2008
6.760
20
38
Sprachen
  1. BascomAVR
  2. Assembler
Hallo zusammen,

und schon kommt das nächste Projekt und das vorherige ist noch nicht mal
abgeschlossen :eek:

Diesmal mach ich es mir aber leicht. Ich klaue ein wenig :D :rolleyes:
Drehzahlmesser 4 mal 7-segment mit 90S2313
Ich benutze allerdings einen Tiny2313 und habe die Segmente und Stellen
etwas anders über die Pins verteilt. Also anpassen muß ich das Programm
sowieso. da ich aber zZt keine Lust habe alles von Grund auf zu entwickeln
(die Schaltung ist da das kleinste Problem) werde ich mich an den Codes
aus diesem Thread gütlich zun. Nach Anpassung der Pins und der Taktfrequenz
sollte es wohl hoffentlich laufen.

Hier schonmal ein paar Bildchen der halbfertigen Hardware ...
P1050987.JPG P1050988.JPG P1050989.JPG

Schaltplan gibts zur Zeit noch nicht. Ist noch alles im Kopf ;)
Bei Basisschaltungen benötigt man keinen Schaltplan :p und das Ding
zählt meiner Meinung nach noch zur Basisschaltung. ... Naja .. ok ... mal
sehen ob ich mich erweichen lassen ...

Nochmal kontrollieren ... Quellenangabe ist drin ... OK ... Beitrag ist kein
Guttenberg :D :rolleyes:

Gruß
Dino
 
Hallo Dino!

Ich bewundere immer wieder deine Lötkünste mit SMD und den 2,54mm Lochrasterplatinen!

Nun sag aber mal:
Wofür benötigst du denn nun einen Drehzahlmesser und wie möchtest du die Erfassung realisieren?


Grüße,
Cassio
 
Hi
Da greifst du aber meinem Projekt vor...:D Das wollte ich als Assembler-Lehrgang bringen, denn genau das brauchen wir, einen Drehzahlmesser...:cool:
Hintergrund: Unser Unimog, sehr betagt, soll uns die Arbeit bei der Holzaufbereitung erleichtern. Das tut er auch, aber wie es so ist, wissen wir nie, ob die Anbauteile in der richtigen Drehzahl laufen. Dafür werden wir sowas brauchen und weil's einem Atmega8 schnell langweilig wird, hab ich geich einen Intervallschalter für den Scheibenwischer und einen Summer für den Blinker mit reingebastelt... Warum Atmega8 ? Na, weil ich davon ein Dutzend gekauft hab. Ich wohn auf dem Land, und da muß man sich alles schicken lassen.
Aber es geht leider nur sehr langsam weiter, weil's halt immer wieder wichtigere Dinge zu tun gibt.
Gruß oldmax:ciao:
 
Hi,

Ich bewundere immer wieder deine Lötkünste mit SMD und den 2,54mm Lochrasterplatinen!
darf man sich vorher aber nicht über irgendwas aufgeregt haben. Mit ner
tattrigen Hand kommt da nur noch ein Lötzinnklumpen bei raus :D

Nun sag aber mal:
Wofür benötigst du denn nun einen Drehzahlmesser und wie möchtest du die Erfassung realisieren?
Fraese.jpg
:D :D :D
Keine Angst ... ich bin nicht unter die Metaller gegangen ;)
Die Drehzahlanzeigen sind für meinen Bruder.
Fräse, Drehmaschine, Bohrsäule, ...
Die Fräse wird grad auf CNC umgebaut. Wiegt auch nur gute 380kg ;)
(ohne den CNC-Kram da dran) Ich tippe am Ende mal so auf ne gute
halbe Tonne.

Die Erfassung wird entweder über einen Hallsensor (nur noch wenige
Stück da) oder ne Lichtschranke gemacht.

Hier das Originalprogramm für nen 90S2313 aus dem Forum von
mikrocontroller.net (siehe Link in Beitrag #1) ...


CodeBox BASCOM
      'Drehzahlmesser - InitCapture mit Timer1
'Hardware: PD6: Signaleingang
' PD1-PD4: 7-segment - Ziffer - Select
' PB0-PB6: 7-segment - Segment A bis G

$regfile = "2313def.dat"
$crystal = 8000000
Ddrb = &B11111111
Ddrd = &B00111111

Dim Icount As Long At &H60
Dim Wcountlo As Word At &H60 Overlay
Dim Wcounthi As Word At &H62 Overlay
Dim Zahl1 As Long
Dim Zahl2 As Long
Dim Zahl As Long
Dim Frequenz As Long
Dim Y As String * 4 At &H70 Overlay
Dim Z(4) As Byte At &H70 Overlay
Dim Test As Integer
Dim Zaehler As Integer

On Icp1 Oncapture
On Ovf1 Onoverflow
Config Timer1 = Timer , Prescale = 1 , Capture Edge = Rising
Enable Icp1
Enable Ovf1
Enable Interrupts

Main:

If Z(4) = 0 Then
Z(4) = Z(3)
Z(3) = Z(2)
Z(2) = Z(1)
Z(1) = 0
End If

For Zaehler = 1 To 4
Test = Z(zaehler)
Select Case Test
Case 48 : Portb = 63
Case 49 : Portb = 6
Case 50 : Portb = 91
Case 51 : Portb = 79
Case 52 : Portb = 102
Case 53 : Portb = 109
Case 54 : Portb = 125
Case 55 : Portb = 39
Case 56 : Portb = 127
Case 57 : Portb = 111
Case Else : Portb = 0
End Select
Portd.zaehler = 1
Waitms 5
Portd.zaehler = 0
Next Zaehler
Goto Main

Oncapture:
Disable Interrupts
Wcountlo = Timer1
Timer1 = 0
Zahl1 = Wcounthi
Zahl2 = Wcountlo
Wcounthi = 0
Zahl = Zahl1 * 65536
Zahl = Zahl + Zahl2
Frequenz = 120000000 / Zahl ' Drehzahl (Umdr./min. bei 4-Taktern)
Y = Str(frequenz)
Enable Interrupts
Return

Onoverflow:
Incr Wcounthi
Return

End

Die Hardwarebastelei liegt auch in den letzten Zügen. Noch den 7805, nen
Elko und ein paar Leitungen und dann sollte am Wochenende der erste
Test am Funktionsgenerator dran sein.

Gruß
Dino
 
Hallo,

langsam gehts weiter ... Ich hab erstmal versucht das andere Programm zu
verstehen ...


CodeBox BASCOM
'Drehzahlmesser - InitCapture mit Timer1
'Hardware: PD6: Signaleingang
' PD1-PD4: 7-segment - Ziffer - Select
' PB0-PB6: 7-segment - Segment A bis G

' Prozessor ATtiny2313
$regfile = "ATtiny2313.DAT"
' 8MHz Quarz
$crystal = 8000000

' ################################
' ##### DEFINITION DER PORTS #####
' ################################
'
' PD0 ---->-- Stelle 1 (Tausender)
' PD1 ---->-- Stelle 2 (Hunderter)
' PD2 ---->-- Stelle 3 (Zehner)
' PD3 ---->-- Stelle 4 (Einer)
' PD4 --
' PD5 --
' PD6 --<---- ICP (Sensorimpulse 1x pro Umdrehung)
'
' PB0 ---->-- Segment a
' PB1 ---->-- Segment b
' PB2 ---->-- Segment c
' PB3 ---->-- Segment d
' PB4 ---->-- Segment e
' PB5 ---->-- Segment f
' PB6 ---->-- Segment g
' PB7 ---->-- Segment dp
'
' PA0 -- XTAL1 | Systemquarz
' PA1 -- XTAL2 | 8,000MHz
' PA2 -- RESET
'
' ===== PortB =================================================================
' O=7= O=6= O=5= O=4= O=3= O=2= O=1= O=0= => 11111111 => DDRB
' SegP SegG SegF SegE SegD SegC SegB SegA => 00000000 => PORTB (init)
' | | | | | | | |
'
Ddrb = &B1111_1111
Portb = &B0000_0000

' ===== PortD =================================================================
' I=7= I=6= I=5= I=4= O=3= O=2= O=1= O=0= => 00001111 => DDRD
' ---- ICP ---- ---- St4 St3 St2 St1 => 01110000 => PORTD (init)
' x | | | | | | |
'
Ddrd = &B0000_1111
Portd = &B0111_0000
'

' ####################################
' ##### DEFINITION DER VARIABLEN #####
' ####################################

Dim Icount As Long At &H60 ' 32Bit
Dim Wcountlo As Word At &H60 Overlay ' unteren 16Bit
Dim Wcounthi As Word At &H62 Overlay ' oberen 16 Bit

Dim Zahl1 As Long ' 16Bit Hi-Zaehler
Dim Zahl2 As Long ' 16Bit Lo-Zaehler
Dim Zahl As Long ' Zaehler zusammenfassung
Dim Frequenz As Long ' berechnete Drehzahl

Dim Y As String * 4 At &H70 Overlay ' Frequenz als Text gewandelt
Dim Z(4) As Byte At &H70 Overlay ' Einzelne Stellen der Textvariable

Dim Test As Integer ' Variable fuer aktuelle Anzeigestelle
Dim Zaehler As Integer ' Zaehlervariable fuer Stellenanzeige

On Icp1 Oncapture ' Zaehler 1 auf Capture
On Ovf1 Onoverflow ' Zaehler 1 Overflow
Config Timer1 = Timer , Prescale = 1 , Capture Edge = Rising
Enable Icp1 ' Zaehler 1 Capture starten
Enable Ovf1 ' Zaehler 1 Ueberlauf starten
Enable Interrupts ' Und Interrupts los

' ###############################################
' ##### Hauptschleife Start #####################
' ###############################################
Main:

If Z(4) = 0 Then ' Stelle 4 ist String-Ende ? ( nur 3stellig )
Z(4) = Z(3) ' Alles um eine Stelle nach rechts schieben
Z(3) = Z(2)
Z(2) = Z(1)
Z(1) = 0 ' und vorderste Stelle auf 0 setzen ( Vornullen unterdruecken )
End If

For Zaehler = 1 To 4
Test = Z(zaehler) ' Anzeigestelle holen
Select Case Test
Case 48 : Portb = 63 ' 0
Case 49 : Portb = 6 ' 1
Case 50 : Portb = 91 ' 2
Case 51 : Portb = 79 ' 3
Case 52 : Portb = 102 ' 4
Case 53 : Portb = 109 ' 5
Case 54 : Portb = 125 ' 6
Case 55 : Portb = 39 ' 7
Case 56 : Portb = 127 ' 8
Case 57 : Portb = 111 ' 9
Case Else : Portb = 0 ' aus
End Select
Portd.zaehler = 1 ' Stelle anschalten
Waitms 5 ' Stelle ausschalten
Portd.zaehler = 0 ' Stelle ausschalten
Next Zaehler
Goto Main
' ###############################################
' ##### Hauptschleife Ende ######################
' ###############################################

' ================================================
' ===== ISR fuer Timer1 Capture ==================
' ================================================
Oncapture:
Disable Interrupts ' Interrupts abschalten
Wcountlo = Timer1 ' Timerstand sichern
Timer1 = 0 ' Timer fuer neuen Start wieder auf Null
Zahl1 = Wcounthi ' obere 16Bit des Zaehlerstandes (Ueberlaeufe)
Zahl2 = Wcountlo ' untere 16Bit des Zaehlerstandes (Timerinhalt)
Wcounthi = 0 ' Ueberlaufszaehler fuer neuen Start auf Null
Zahl = Zahl1 * 65536 ' obere 16Bit in Zahl
Zahl = Zahl + Zahl2 ' untere 16Bit in Zahl
Frequenz = 120000000 / Zahl ' Drehzahl (Umdr./min. bei 4-Taktern)
Y = Str(frequenz)
Enable Interrupts ' Interrupts fuer naehste Messung wieder an
Return

' ================================================
' ===== ISR fuer Timer1 Overflow =================
' ================================================
Onoverflow:
Incr Wcounthi ' Ueberlauf zaehlen (+1)
Return

End

Das Programm paßt allerdings noch nicht zur Hardware ...

Gruß
Dino
 
Hallo zusammen,

der Drehzahlmesser lebt und ist in der Software an einen Impuls/Umdrehung
angepaßt ...
P1050997.JPG


CodeBox BASCOM
'Drehzahlmesser - InitCapture mit Timer1
'Hardware: PD6: Signaleingang
' PD1-PD4: 7-segment - Ziffer - Select
' PB0-PB6: 7-segment - Segment A bis G

' Prozessor ATtiny2313
$regfile = "ATtiny2313.DAT"
' 8MHz Quarz
$crystal = 8000000

' ################################
' ##### DEFINITION DER PORTS #####
' ################################
'
' PA0 -- XTAL1 | Systemquarz
' PA1 -- XTAL2 | 8,000MHz
' PA2 -- RESET
'
' ===== Kathoden (0=an) =====
' PB0 ---->-- Segment a
' PB1 ---->-- Segment b
' PB2 ---->-- Segment c
' PB3 ---->-- Segment d
' PB4 ---->-- Segment e
' PB5 ---->-- Segment f
' PB6 ---->-- Segment g
' PB7 ---->-- Segment dp
'
' ===== PortB =================================================================
' O=7= O=6= O=5= O=4= O=3= O=2= O=1= O=0= => 11111111 => DDRB
' SegP SegG SegF SegE SegD SegC SegB SegA => 00000000 => PORTB (init)
' | | | | | | | |
'
Ddrb = &B1111_1111
Portb = &B0111_1111

' ===== Anoden (pnp 0=an) ======
' PD0 ---->-- Stelle 1 (Tausender)
' PD1 ---->-- Stelle 2 (Hunderter)
' PD2 ---->-- Stelle 3 (Zehner)
' PD3 ---->-- Stelle 4 (Einer)
' PD4 --
' PD5 --
' PD6 --<---- ICP (Sensorimpulse 1x pro Umdrehung)
'
' ===== PortD =================================================================
' I=7= I=6= I=5= I=4= O=3= O=2= O=1= O=0= => 00001111 => DDRD
' ---- ICP ---- ---- St4 St3 St2 St1 => 01110000 => PORTD (init)
' x | | | | | | |
'
Ddrd = &B0000_1111
Portd = &B0111_1110
'

' ####################################
' ##### DEFINITION DER VARIABLEN #####
' ####################################

Dim Icount As Long At &H60 ' 32Bit
Dim Wcountlo As Word At &H60 Overlay ' unteren 16Bit
Dim Wcounthi As Word At &H62 Overlay ' oberen 16 Bit

Dim Zahl1 As Long ' 16Bit Hi-Zaehler
Dim Zahl2 As Long ' 16Bit Lo-Zaehler
Dim Zahl As Long ' Zaehler zusammenfassung
Dim Frequenz As Long ' berechnete Drehzahl

Dim Y As String * 4 At &H70 Overlay ' Frequenz als Text gewandelt
Dim Z(4) As Byte At &H70 Overlay ' Einzelne Stellen der Textvariable

Dim Test As Integer ' Variable fuer aktuelle Anzeigestelle
Dim Zaehler As Integer ' Zaehlervariable fuer Stellenanzeige

On Icp1 Oncapture ' Zaehler 1 auf Capture
On Ovf1 Onoverflow ' Zaehler 1 Overflow
Config Timer1 = Timer , Prescale = 1 , Capture Edge = Rising
Enable Icp1 ' Zaehler 1 Capture starten
Enable Ovf1 ' Zaehler 1 Ueberlauf starten
Enable Interrupts ' Und Interrupts los

Y = "0000"

' ###############################################
' ##### Hauptschleife Start #####################
' ###############################################
Main:

If Z(4) = 0 Then ' Stelle 4 ist String-Ende ? ( nur 3stellig )
Z(4) = Z(3) ' Alles um eine Stelle nach rechts schieben
Z(3) = Z(2) ' Stelle 4 => Einer
Z(2) = Z(1) ' Stelle 1 => Tausender
Z(1) = 0 ' und vorderste Stelle auf 0 setzen ( Vornullen unterdruecken )
End If

For Zaehler = 1 To 4 ' Alle 4 Stellen durcharbeiten

Test = Z(zaehler) ' Anzeigestelle holen
Select Case Test ' Segm. pgfe_dcba
Case 48 : Portb = &B1100_0000 ' 0 ===> 1100_0000
Case 49 : Portb = &B1111_1001 ' 1 ===> 1111_1001
Case 50 : Portb = &B1010_0100 ' 2 ===> 1010_0100
Case 51 : Portb = &B1011_0000 ' 3 ===> 1011_0000
Case 52 : Portb = &B1001_1001 ' 4 ===> 1001_1001
Case 53 : Portb = &B1001_0010 ' 5 ===> 1001_0010
Case 54 : Portb = &B1000_0010 ' 6 ===> 1000_0010
Case 55 : Portb = &B1111_1000 ' 7 ===> 1111_1000
Case 56 : Portb = &B1000_0000 ' 8 ===> 1000_0000
Case 57 : Portb = &B1001_0000 ' 9 ===> 1001_0000
Case Else : Portb = &B1111_1111 ' aus => 1111_1111
End Select

Select Case Zaehler ' Stelle anschalten
Case 1 : Portd = &B0111_1110
Case 2 : Portd = &B0111_1101
Case 3 : Portd = &B0111_1011
Case 4 : Portd = &B0111_0111
End Select
Waitms 5
Portd = &B0111_1111 ' Stelle ausschalten

Next Zaehler

Goto Main
' ###############################################
' ##### Hauptschleife Ende ######################
' ###############################################

' ================================================
' ===== ISR fuer Timer1 Capture ==================
' ================================================
Oncapture:
Disable Interrupts ' Interrupts abschalten
Wcountlo = Timer1 ' Timerstand sichern
Timer1 = 0 ' Timer fuer neuen Start wieder auf Null
Zahl1 = Wcounthi ' obere 16Bit des Zaehlerstandes (Ueberlaeufe)
Zahl2 = Wcountlo ' untere 16Bit des Zaehlerstandes (Timerinhalt)
Wcounthi = 0 ' Ueberlaufszaehler fuer neuen Start auf Null
Zahl = Zahl1 * 65536 ' obere 16Bit in Zahl
Zahl = Zahl + Zahl2 ' untere 16Bit in Zahl
Frequenz = 480000000 / Zahl ' Drehzahl (Umdr./min. bei 1Impuls/Umdr.)
Y = Str(frequenz)
Enable Interrupts ' Interrupts fuer naehste Messung wieder an
Return

' ================================================
' ===== ISR fuer Timer1 Overflow =================
' ================================================
Onoverflow:
Incr Wcounthi ' Ueberlauf zaehlen (+1)
Return

End

Allerdings zuckt der Meßwert doch relativ stark hin und her. Die Anzeige
muß also noch etwas beruhigt werden. Mal sehen wie ich das anstelle ;)

Gruß
Dino
 
Hi
Ich habe es wie folgt gelöst:
Die Ausgabe erfolgt aus der Timer - ISR im mSek. Takt. Dadurch erhalte ich gleichmäßige Ansteuerzeiten der Ziffern.
Damit alles fix geht, greife ich auf die vorbereiteten 7Segment-Codes direkt zu.Die aufbereitung erfolgt in der Programmschleife. Wenn du noch etwas Geduld hast, ich brauch noch ein wenig Zeit. Dann steht der komplette Assemblercode zur Verfügung.
Gruß oldmax
 
Hi oldmax,

die Anzeige an sich ist ruhig und gleichmäßig. Das Problem ist der Meßwert.
Der Drehzahlmesser soll bis etwa 6000 u/min messen. Da er dann so um die
100 mal pro Sekunde mißt kann es natürlich vorkommen das nicht alle dieser
100 Messungen exakt das selbe Ergebnis liefern. Damit ist der Wert auf der
Anzeige am tanzen (mal 5990, mal 6005 mal 5995, ... usw) das sieht bei
etwa 100x pro Sekunde ziemlich zappelig aus. Man kann den Wert schlecht
ablesen. Ich muß also den gemessenen Wert irgendwie mitteln ohne damit
unter 2 Messungen/sekunde zu kommen damit die Anzeige schnell genug
reagiert wenn man die Drehzahl ändert.

Also benötige ich im Moment eher eine Beruhigung des Messwertes.

Der Multiplexbetrieb läuft soweit problemlos.

Gruß
Dino
 
Hi Dino
100 x / Sek. bedeutet, alle 10 mSek. Wenn du 5 Messungen mittelst, sollte der Wert bis auf die letzte Stelle ruhig sein, wenn nicht, hast du Probleme mit der Berechnung oder dein Istwert schwankt tatsächlich, wobei ich nicht glaube, das ein Antrieb so dynamisch ist. Vielleicht solltest du da etwas Kompromissfreudiger sein, denn selbst 20 Hz (50 mSek) ergibt schon eine ziemlich flotte Anzeige. Vielleicht solltest du dich mit 2 Hz Aktualisierungszeit zufrieden geben. Dann kannst du d. 50 Werte mitteln.
Ich hab bei meinem Drehzahlmesser eigentlich gar nicht so genau aufgelöst. Ich zähle in der Timer ISR mSek. in eine Variable. Kommt ein Impuls, wird 60000 (mSek für Minute) durch den gezählten Wert geteilt und der Zähler wieder auf 0 gesetzt. Die Berechnungen werden im Programm durchgeführt und der 7-Segment-Code für die Ausgabe in Variablen geschrieben. Bisher sieht das Ergebnis schon ganz gut aus. ( nachdem ich mit meinen zittrigen Händen 3 Platinen versaut hab... :eek: )
Gruß oldmax
 
Hi,

100 x / Sek. bedeutet, alle 10 mSek. Wenn du 5 Messungen mittelst, sollte der Wert bis auf die letzte Stelle ruhig sein, wenn nicht, hast du Probleme mit der Berechnung oder dein Istwert schwankt tatsächlich, wobei ich nicht glaube, das ein Antrieb so dynamisch ist. Vielleicht solltest du da etwas Kompromissfreudiger sein, denn selbst 20 Hz (50 mSek) ergibt schon eine ziemlich flotte Anzeige. Vielleicht solltest du dich mit 2 Hz Aktualisierungszeit zufrieden geben. Dann kannst du d. 50 Werte mitteln.
Der Antrieb ist nicht so dynamisch. Also Drehzahl wird eingestellt und dann
damit gearbeitet. Allerdings braucht man mal ne sehr hohe Drehzahl (kleiner
Durchmesser in Alu) und mal ne sehr kleine. Der Drehzahlmesser soll nachher
an ne Bohrsäule und an ne Drehbank dran. Beide haben Getriebestufen und
nen Frequenzumrichter für die Drehzahleinstellung. Es muß also ein sehr
breiter Bereich abgedeckt werden. Wenn ich jetzt bei sehr kleinen Drehzahlen
Mittelwerte bilde wird die Anzeige recht langsam. Bei hohen Drehzahlen
bleibt es aber immer noch recht wackelig.

Ich hab bei meinem Drehzahlmesser eigentlich gar nicht so genau aufgelöst. Ich zähle in der Timer ISR mSek. in eine Variable. Kommt ein Impuls, wird 60000 (mSek für Minute) durch den gezählten Wert geteilt und der Zähler wieder auf 0 gesetzt. Die Berechnungen werden im Programm durchgeführt und der 7-Segment-Code für die Ausgabe in Variablen geschrieben. Bisher sieht das Ergebnis schon ganz gut aus. ( nachdem ich mit meinen zittrigen Händen 3 Platinen versaut hab... :eek: )
Ne Minute Meßzeit ist definitiv zu lange wenn man die Drehzahl am FU
verstellt. 0,5 bis 1sec Meßzeit (Zeit zwischen 2 Anzeigen) ist das was ich
mir als langsamstes gesetzt habe. Damit komme ich bei einer Messung pro
Umdrehung auf 60..120u/min .

Irgendwie muß ich das evtl mit dem 2ten Timer und ner gleitenden Bildung
des Mittelwertes oder nem Fenster für Wertänderungen machen. Damit eine
prozentuale kleine Wertänderung nicht zu einer neuen Anzeige führt. Evtl
mit dem 8Bit-Timer ne Zeit von 0,5sec erzeugen damit in dem Raster der
Wert auf die Anzeige übernommen wird und der Rest einfach ignoriert wird.

Gruß
Dino
 
Hi Dino
Ne Minute Meßzeit ist definitiv zu lange wenn
Da hast du mich aber gründlich mißverstanden... :eek:
Also, ich zähle in der Timer ISR mSe. in eine Variable. Bekomme ich von der Umdrehung einen Impuls, rufe ich bei der steigenden Flanke die Berechnung auf:
60000 / zezählte Zeit ergibt U/ Min.
Bsp. Der Zähler hat 100 mSek. gezählt.
60000/ 100 =600 U/Min
Natürlich wird der Zähler für eine neue Berechnung dann zurückgesetzt. Die Anzeige wird also sofort nach einer Umdrehung aktualisiert. Da dürfte ein Mittelwert von 5 Werten nicht so stark ins Gewicht fallen. Vielleicht kannst du ja die Mittelwertberechnung nur bei höheren Drehzahlen wirken lassen.
Gruß oldmax
 
Hallo zusammen,

hier mal ein Foto vom laufenden Drehzahlmesser ...
P1050997.JPG
im Moment ist zum testen ein Motor mit Hall-Sensor dran.
Die Anzeige ist "akzeptabel" aber nicht "gut". Muß ich am Programm wohl noch
mal ein wenig rumstricken ;) Aber das Ding funktioniert erst mal. Das ist die
Hauptsache :D

Gruß
Dino
 
vielleicht solltest du den Mittelwert aus 4 Messungen bilden
(da der Quellcode in Bascom ist, kannst auch ne beliebig andere Zahl nehmen, in Assembler bieten sich halt Vielfache von 2 an; ror bzw. lsr)
kuck ma hier: http://www.mikrocontroller.net/topic/76994

in Deinem Prog. wird der Mittelwert nur aus 2 Messungen gebildet:

Freq2 = Freq1
Freq1 = Frequenz
Frequenz = Freq1 + Freq2
Frequenz = Frequenz / 2
Freq = Frequenz

probier ma folgendes:

Freq2 = Freq1*3; (x)
Freq1 = Frequenz
Frequenz = Freq1 + Freq2
Frequenz = Frequenz / 4 ;(x+1)
Freq = Frequenz

somit wird der der Unterschied zur neuen Frequenz nur mit einem Viertel gewichtet.

gruss
wolf

//edit by me:

noch viel einfacher gehts mit exponentialem Mittelwert (hab ich grad noch gefunden): http://www.ibrtses.com/embedded/exponential.html
(Beispiel fuer asm)

mit Y als 16bit Register:


Y= Y - (Y lsr N)
Y= Y + Input
Output= Y lsr N
mit N gleich rightshifts mit 5,6,7...(entspricht geteilt durch: 32,64,128... oder 2^5, 2^6, 2^7...)

bei nochmaliger Betrachtung der Formel faellt auf, dass "Input" falsch gewichtet ist, sollte naemlich INPUT lsr 5 sein....
siehe hier: output:=input shr 5 + output - output shr 5
oder. http://de.wikipedia.org/wiki/Exponentielle_Glättung

dann muesste die richtige Formel sein:

Y= Y - (Y lsr N)
Output= (Input lsr N)+Y

auf der Wiki-Site wird ein Glaettungsfaktor zwischen 0,2 und 0,3 empfohlen, somit reicht ein lsr mit 2, das entspricht geteilt durch 4 somit 0,25
 
Hi Leute
Das ist ja Klasse, dass Ihr einen Drehzahlmesser programmiert. Das versuche ich schon eine ganze Weile, nur leider fange ich bei 0 an. Und gleich mit Assembler.
Nun habe ich mir natürlich die Demo von Bascom geladen und versuche mich hier einzuklinken.
Glücklicher Weise dokumentiert Ihr die Programme gut. So das ich mich ein bischen reinversetzen kann :).
Vielen dank und macht weiter so.
Gruß falli4
 
Hi
Um einen Drehzahlmesser zu bauen, gibt es ja genug Anleitungen. Aber es selbst und dann in Assembler zu machen, schult...
Was braucht's ? Ein Signal von der Umdrehung. Wenn 12 V Bordspannung, dann halt über einen Optokoppler. Auch die Anzeige hab ich über die 12 V ( 14 V) verschaltet, da ich dann keinen Kühlkörper für den Spannungsregler brauche. Normal sollte ein Atmega8 locker reichen.
Zum Programm:
Befasse dich zuerst mit dem Timer. Er muß dir den Interrupt alle mSek. liefern, die du für den Multiplexer und die Zeitbasis brauchst.Ein wenig Hilfe sollte dir der Beitrag: "Keine Angst vor Assembler" liefern. Du findest ihn unter FAQ. Ebenfalls hilfreich ist eine serielle Verbindung mit deinem PC und dem Tool OpenEye. Richtig eingesetzt wird es dir ein paar graue Haare ersparen.
Gruß oldmax
 
Hallo an alle,

als erstes mal vorweg ... der Quellcode ist wie schon im ersten Beitrag erzählt von
mikrocontroller.net geklaut :wink: Ich habe ihn bis jetzt nur ein wenig an meine
Gegebenheiten angepaßt und mit wesentlich mehr Kommentaren versehen. Die
Kommentare brauchte ich zwangsläufig um zu verstehen was da wie programmiert
wurde und wie ich es für meine Zwecke anpassen kann. Im ersten Beitrag ist auch
ein Link auf den Originalbeitrag.
Ich will mich ja hier nicht mit fremden Federn
schmücken :yes4:

@Michaela1234 : Das mit den Mittelwerten ist mir schon klar. Das Problem ist aber,
ich kann nicht dauernd 4 Messungen zu einem Wert mitteln weil es sonst bei kleinen
Drehzahlen viel zu langsam wird. Bei 60 U/min habe ich sonst nur alle 4 sec eine
neue Anzeige. Ich brauche also eine variable Anzahl an Meßwerten die gemittelt
werden. Aber da bin ich dran wenn wieder etwas Zeit ist.

@Falli4 : Wie gesagt, der Quellcode ist geklaut und wird hier von mir entsprechend
angepaßt. Klauen ist in dem Fall aber nichts böses wenn man drauf hinweist. Man
muß das Rad ja nicht jedesmal neu erfinden. Es wurde von mir also nicht programmiert
sondern nur geändert.

@oldmax : Jou! In Assembler und dann als Anfangsprojekt ist da schon ein wenig
Zeit und Gehirnschmalz von Nöten :wink: Nen Mega8 ist da aber (wie man bei mir
sieht) in Assembler bestimmt unterfordert. Bei Bascom würde ich sagen das er
paßt, bei Assembler reicht aber auf jeden Fall der Tiny2313. Hängt aber auch davon
ab was grade so in der Bastelkiste rumfliegt :flute:

Da der Drehzahlmesser aber wohl bis zum Einsatz noch nen guten Monat Zeit hat
werde ich mich mit den Änderungen nicht unbedingt überschlagen :sarcastic: Also
etwas Geduld mitbringen.

Gruß
Dino
 
Schönen Abend

@ dino03
Den Beitrag von mikrokontroller.net habe ich mir auch schon mehrmals angesehen nur leider nie richtige Ergebnisse erzielt. Da ich eigentlich mit Assembler anfangen wollte und ich von Bascom keine Ahnung habe.
Da Du das Programm so gut interpretiert hast habe ich auch meinen Fehler entdeckt. Ich benutzte Anzeigen mit gemeinsamer Anode und einem TD62554s die ich immer schön mit dem STK500 Ansteuern könnte :-(! Aber nun habe ich die ersten Erfolge. Danke

@ oldmax
Danke für Deine Ratschläge. Ich werde mal versuchen mich besser in die Materie einzuarbeiten. Habe mir dein Programm OpenEye mal angesehen, Ist mir aber noch viel zu hoch für mich. Ich werde erst mal ein paar LED blinken lassen.

Ein ähnliches Projekt ist auch auf der Seite von Gido Speer zu finden. Dort wird mit einer Reflexlichtschranke CNY70 abgetastet. Klappt super.
Was mir aufgefallen ist, dass der letzte Messwert immer stehen bleibt. Mal sehen ob ich das hinbekomme das nach einer gewissen Zeit die Anzeige wieder auf 0000 geht.
Ich bin gestern schon fast verzweifelt wo ich die Idee von oldmax mit der Mittelwertbildung einbinden wollte.

So es leider wieder Spät, heute wird nichts mehr viele Grüße.
falli4
 
@dino03
du hast auch bei 60u/min und Mittelwertberechnung jede sec. ne neue Anzeige, allerdings wollt ich den Motor sehen, der mit 60 U/min laeuft (im uebrigen brauchst dann keinen DZM, da kannst ja die Touren mitzaehlen), selbst ein Schiffsdiesel hat ca. 800 U/min.

@falli4

hier ist der Beitrag fuer nen Tacho in asm, allerdings mit LCD-Anzeige, das aber ruckzuck in eine 7-Segment-Anzeige umgecodet ist. Das Prinzip ist aehnlich dem eines DZM.
Dann kannst noch nach dem Sourcecode von der Zuendung vom Hans Krause suchen; diese Zuendung ermittelt den Zuendzeitpunkt auch ueber einen Pickup, also einem Signalgeber fuer die Kurbelwelle. Daraus kann man auch einen DZM basteln.
Ich selber bau grad nen Tacho mit 7-Segment-Anzeige fuer die Geschwindigkeitsanzeige, (km-Zaehler laeuft ueber LCD) allerdings mit Schieberegistern (74HC595D), anstatt die Anzeigen zu multiplexen, da ich noch Oel- und Wassertemp. ueber den mc per i2c laufen lassen werd.
Meine Zuendung nach Hans Krause wird ueber die Krankenkassenkarte aktiviert (ich sag nur Mofa), das wird auch noch lustig. Und auf die KKK passt dann noch eine separate Zuendkurve.
 
Hi Michaela,

@dino03
du hast auch bei 60u/min und Mittelwertberechnung jede sec. ne neue Anzeige, allerdings wollt ich den Motor sehen, der mit 60 U/min laeuft (im uebrigen brauchst dann keinen DZM, da kannst ja die Touren mitzaehlen), selbst ein Schiffsdiesel hat ca. 800 U/min.

Der Motor der solche Drehzahlen macht sieht so aus ...
Ständerbohrmaschine
Je nach Gang des Riemengetriebes und Stellung des Frequenzumrichters kann das
Ding ganz langsam bohren oder für Alu mit nem kleinen Bohrer auch mal ganz schnell.

Und zu den 60 U/min ...
Da jede Umdrehung ein Impuls erzeugt wird und der Abstand der Impulse für die
Berechnung der Drehzahl genommen wird hat man bei 60 U/min also 1 U/sec.
Damit ergibt sich zwangsweise aber auch nur eine Messung pro Sekunde und
auch nur eine Anzeige pro Sekunde. Soweit auch ganz gut. Wenn ich das Programm
dann so lasse (also ohne Mittelwerte) dann wird die Anzeige bei höherer Drehzahl
und leicht ungleichmäßiger Messung sehr unruhig. Wenn ich jetzt aber mit einer
festen Mittelwertbildung arbeite (zB immer 4 Messungen) dann habe ich bei 60 U/min
also 1 U/sec bei 4 Werten zu einem Mittelwert nur noch eine Anzeige in 4 Sekunden.
Außer ich arbeite mit einem Array von 4 Werten und lasse die älteste Messung
rausfallen und nehme dafür immer ne neue rein. Dann wird aber der Anzeigewert
bei höheren Drehzahlen wieder unruhig. Zwar nicht ganz so stark aber trotzdem.

Also bleibt mir nichts anderes übrig als mir was auszudenken wie ich dynamisch mal
mit nur einer Messung (bei 60 U/min) und mal mit vielen Mittelwerten (bei 6000 U/min)
arbeite. Ich will dabei aber auch nicht unbedingt riesige Variablen einsetzen weil mir
sonst der Platz im SRAM wieder zu eng wird.

Laß dich am besten mal überraschen was mir da einfällt ;)
Es wird wohl darauf hinauslaufen das ich den 8Bit-Timer dabei einsetze.

Gruß
Dino
 
Wenn ich jetzt aber mit einer
festen Mittelwertbildung arbeite (zB immer 4 Messungen) dann habe ich bei 60 U/min
also 1 U/sec bei 4 Werten zu einem Mittelwert nur noch eine Anzeige in 4 Sekunden.

Da hast nen Denkfehler drin...
du loest mit jedem Impuls einen Interrupt aus. Dann schreibst am Anfang der Interruptroutine:
(in der Inititialisierungsphase definierst ein Register oder eine Speicherzeile)
diese Zelle wird mit 0 vorbelegt. gehen wir mal von einem 16-bit Register aus (wegen mir nennen wir das Teil X, dann sind die beiden 8 bit Register XH:XL, temp und temp1 sind 8 bit Register):
ist halt in asm, geht aber mit Bascom genau so:

cpi XH, Timerzaehler (Wert fuer den Timer wenn Drehzahl groesser als x Umdrehungen)
brsh Mittelwert ( verzeige in Subroutine Mittelwert, wenn Timerwert fuer Drehzahl groesser als x Umdrehungen)

hier kommt der restliche Code, Drehzahl anzeigen.. bla

(Subroutine)
Mittelwert:
ldi temp, XL (lowByte des alten Werts zwischenspeichern)
ldi temp1, XH ( das gleiche mit dem HighByte
lsl X (2 mal X)
add XL, temp
adc XH, temp1 (einmal X dazuaddieren, entspricht dann 3 mal X)
add XL, neuerWert_lowbyte
adc XH, neuerWert_highbyte
lsr X (x durch 2 teilen)
adiw X, 1 (vorsichtshalber noch 1 zuaddieren, wegen der Nachkommastellen)
lsr X (nochmal durch 2 teilen, Ergebnis bleibt im Register x)
ret

x wertest als Anzeige aus

somit hast jede Sekunde ne neue geglaettete Anzeige..

rechne es mit Excel nach (das 1 zuaddieren ist hier net beruecksichtigt)
erste Sek ergibt (0+0+0+60)/4=15
2. Sek: (3*15+60)/4=26,25
3. sek: (3*26,25+60)/4=34,6875
41,01
45,76
49,32
51,99
53,99
55,49
56,61
.
.
.
bei angenommener Aktualisierung alle sec....

gruss
wolf
 

Über uns

  • Makerconnect ist ein Forum, welches wir ausschließlich für einen Gedankenaustausch und als Diskussionsplattform für Interessierte bereitstellen, welche sich privat, durch das Studium oder beruflich mit Mikrocontroller- und Kleinstrechnersystemen beschäftigen wollen oder müssen ;-)
  • Dirk
  • Du bist noch kein Mitglied in unserer freundlichen Community? Werde Teil von uns und registriere dich in unserem Forum.
  •  Registriere dich

User Menu

 Kaffeezeit

  • Wir arbeiten hart daran sicherzustellen, dass unser Forum permanent online und schnell erreichbar ist, unsere Forensoftware auf dem aktuellsten Stand ist und der Server regelmäßig gewartet wird. Auch die Themen Datensicherheit und Datenschutz sind uns wichtig und hier sind wir auch ständig aktiv. Alles in allem, sorgen wir uns darum, dass alles Drumherum stimmt :-)

    Dir gefällt das Forum und unsere Arbeit und du möchtest uns unterstützen? Unterstütze uns durch deine Premium-Mitgliedschaft!
    Wir freuen uns auch über eine Spende für unsere Kaffeekasse :-)
    Vielen Dank! :ciao:


     Spende uns! (Paypal)