Erstmal DANKE für eure Vorschläge und Tipps.
Ich war warscheinlich etwas voreilig mit meiner Frage weil ich den ganzen Tag immer nur per Hand die Autos über den Empfänger geschuppst hab.
Jetzt hab ich mal die Bahn aufgebaut und siehe da es gibt erste Erfolge.
Also ich habe 2 Codevarianten aus dem Inet versucht beide haben Probleme, die eine mehr die andere weniger.
Version1, messen über INT0 mit folgendem Code
Code:
$regfile = "m8def.dat"
$crystal = 8000000
$hwstack = 32
$swstack = 10
$framesize = 40
$baud = 9600
Config Portd.2 = Input 'int 0
Portd.2 = 1
Config Timer1 = Timer , Prescale = 64
'Tccr1b.6 = 0
Stop Timer1 'we stop the timer , because it will be activated
'inside the int0 routine
Config Int0 = Falling 'or rising
On Int0 Int0isr 'Nosave 'nosave .. saves time and code
Enable Int0
On Ovf1 T1overflow 'Nosave 'again nosave
Enable Ovf1
'about nosave : if you use the int routines "called ORIGINAL BASCOM" please comment
'out the NOSAVE DIRECTIVE
Enable Interrupts
' **************************************************************************************
' *** hier kommen zwei spezialkonstukte, die rechenzeit sparen .. was zum nachdenken !!
Dim Periodelow As Word
Dim Periodehigh As Word
Dim Pericount As Long At Periodelow Overlay
Dim T1overlow As Byte
Dim T1overhigh As Byte
Dim T1overflows As Word At T1overlow Overlay
' ** ENDE von *** hier kommen zwei spezialkonstukte, die rechenzeit sparen .. was zum nachdenken !!
' **************************************************************************************
Dim Messzyklus As Byte 'fertig = 0 -- also eine ganze periode gemessen
Messzyklus = 0
Dim Status As Byte ' 0=stop timer 1 = start timer
Status = 0
Wait 2 '
Do
'************ do not change below this line, if you are not sure what you are doing
If Messzyklus = 0 Then
Periodelow = Timer1
Periodehigh = T1overflows
'************ do not change above this line, if you are not sure what you are doing
' ##### your code below this line #####
Print "timer" ; Timer1
Print "ovr" ; T1overflows
Print "pericount " ; Pericount
'************ do not change below this line, if you are not sure what you are doing
Pericount = 0
T1overflows = 0
Timer1 = 0
Messzyklus = 1
Status = 1
End If
'************ do not change above this line, if you are not sure what you are doing
Loop
End
Int0isr: 'ORIGINAL Bascom
Tccr1b = Status
If Status = 0 Then
Messzyklus = Status
End If
Status = 0
Return
'Int0isr: ' FASTER VERSION
'push r23
'PUSH R24 ' since we are going to use R24 we better save it
'IN r24, SREG ' get content of SREG into R24
'PUSH R24
' we can save a register
'lds r24,{status}
'!out tccr1b,r24
'cpi r24,0
'brne exitthis
'sts {messzyklus},r24
'Exitthis:
'cbr r24,1
'sts {status},r24
'POP R24 'get content of SREG
'!OUT SREG,r24 ' save into SREG
'POP R24
'pop r23 ' get r24 back
'Return
'T1overflow: ' ORIGINAL Bascom
'T1overflows = T1overflows + 1
'Return
T1overflow: ' FASTER VERSION
push r23
PUSH R24 ' since we are going to use R24 we better save it
IN r24, SREG ' get content of SREG into R24
PUSH R24 ' we can save a register
lds r23,{t1overlow}
lds r24,{t1overhigh}
inc r23
brne kein_uebertrag
inc r24
Kein_uebertrag:
sts {t1overlow} , r23
sts {t1overhigh} , r24
POP R24 'get content of SREG
!OUT SREG,r24 ' save into SREG
POP R24
pop r23 ' get r24 back
Return
Also diese Variante zählt erstmal wirklich jede Runde egal wie schnell man fährt, bei einem Auto sind die Werte 98% zu verwerten soll heißen manchmal zählt er doppelt oder mal 1 Wert stimmt völlig nicht. Das 2.Auto macht rießige Sorgen, da ist irgend eine Störung wohl vorhanden, da zählt er wirr egal wo das Auto auf der Bahn ist nur nicht am Sensor.
Auch wenn beide Autos Stoßstange an Stoßstange fahren also direkt hinternander werden beide gezählt, nur eben stört bei einem irgendwas. Wenns geht gehts zu 98% sauber. Also Zeit zum messen hat der Mega8.
Wobei ich gestehen muss das ich den Code fast garnicht verstehe was da gemacht wird.
2.Variante mit Capture und folgendem Code
Code:
$regfile = "m8def.dat"
$crystal = 8000000
Baud = 9600
Config Lcd = 16 * 2
Config Lcdpin = Pin , Db4 = Portd.4 , Db5 = Portd.5 , Db6 = Portd.6 , Db7 = Portd.7 , E = Portd.3 , Rs = Portd.2
Config Lcdbus = 4
' ++++++++++++++++++++++++++++++++++ hier wird $crystal ausgelesen
Dim Quartzfrequenz As Long
Quartzfrequenz = _xtal
' ********************************************** hier den prescaler für timer1 definieren
' zulässig sind 1,8,64,256,1024
Const Prescalerwert = 1
' in dieser version wird der overflow von T1 ausgewertet und mitgezählt
' daher kann man mit prescale = 1 d.h. volle auflösung fahren
'******************** und den capturetimer configurieren ********************
Config Timer1 = Timer , Capture Edge = Falling , Prescale = 1 'Prescalerwert
Start Timer1
' ****************************************************************************
' *********** das zu messende digitalsignal wird am ICP1 eingang (hier PB0) eingespeist
Dim Starttime As Word
Dim Endtime As Word
Dim Nroverflows As Byte
Dim Ersteflanke As Bit
Dim Updatedisplay As Bit
Dim Taktejesekunde As Long
Dim Periodendauer As Single
Dim Frequenz As Single
Dim Counterticks As Long
Taktejesekunde = Quartzfrequenz / Prescalerwert
Dim Maxoverflows As Long
Maxoverflows = Taktejesekunde / 31375
'***** zwei werte zur verzögerung des seriellen ausgabe
'***** sonst verschluckt sich das terminalprogramm
'***** kleinerer wert = schnellerer output
Dim Outputcounter As Byte
Const Anzeigeinterval = 10
'***************************
Ersteflanke = 1
Updatedisplay = 0
'********************************* option eingangscomparator
' diese 2 zeilen sind optional zu verwenden
' da der icp1 eingang ja logigpegel benötigt
'besteht hier die möglichkeit anstelle des icp den ain1 eingang des comparators zu verwenden
' der eingang ist dann empfindlicher --- schwelle etwa 1,23 volt '
' der icp1 eingang gilt dann nicht mehr als eingang und kann als normaler port verwendet werden
'Config Aci = On , Compare = On
'Acsr.6 = 1 'interne bandgap als ref
'********************************* ende option eingangscomparator
' ******************* und die int routinen definieren
On Ovf1 T1overflow
Enable Ovf1
On Capture1 Captureint 'wenn pb0 auf low geht dann capture int
Enable Capture1
Enable Interrupts
' ************* und los gehts
Cls
Do
'If Nroverflows > Maxoverflows Then
'Cls
'Lcd "freq kleiner 2 Hz"
'Nroverflows = 0
'Updatedisplay = 0
'Ersteflanke = 1
'End If
If Updatedisplay = 1 Then
If Outputcounter = Anzeigeinterval Then
'Disable Capture1
'Disable Ovf1
Disable Interrupts
' //
' // Die Zeitdauer zwischen den Flanken bestimmen
' // Da EndTime und StartTime unsigned sind, braucht nicht
' // darauf Ruecksicht genommen werden, dass EndTime auch
' // kleiner als StartTime sein kann. Es kommt trotzdem
' // das richtige Ergebnis raus.
' // Allerdings muss die Anzahl der Overflows in der Messperiode
' // beruecksichtigt werden
' //
' // Die Zeitdauer wird als Anzahl der Taktzyklen zwischen den
' // beiden gemessenen Flanken berechnet ...
Counterticks = Nroverflows * 65536
Counterticks = Counterticks + Endtime
Counterticks = Counterticks - Starttime
'// ... mit der bekannten Taktfrequenz ergibt sich dann die Signalfrequenz
Periodendauer = Counterticks / Taktejesekunde
Frequenz = 1 / Periodendauer
' // Das Ergebnis fuer die Anzeige aufbereiten ...
' // ... und ausgeben
' //
'Locate 1 , 1
'Lcd "ti=" ; Counterticks
'Locate 1 , 8
'Lcd " Pe=" ; Periodendauer
'Locate 2 , 1
Print Frequenz
'Lcd " Fr=" ; Frequenz
' // Das wars: Display ist wieder up to date
'// die naechste Messung kann starten
'//
Outputcounter = 0
'Timer1 = 0
'Enable Capture1
'Enable Ovf1
Enable Interrupts
End If
Outputcounter = Outputcounter + 1
Counterticks = 0
Updatedisplay = 0
End If
Loop
End 'end program
T1overflow:
Nroverflows = Nroverflows + 1
'Print "timer1 overflow"
Return
Captureint:
If Updatedisplay = 1 Then Return '// Das Display wurde mit den Ergebnissen der vorhergehenden
'// Messung noch nicht upgedated. Die naechste Messung
'// verzögern, bis die Start und EndTime Variablen wieder
'// gefahrlos beschrieben werden koennen
If Ersteflanke = 1 Then
Starttime = Capture1
Nroverflows = 0
Ersteflanke = 0 ' / / Die Naechste Flanke Ist Das Ende Der Messung
Else
Endtime = Capture1
Updatedisplay = 1 ' / / Eine Vollständige Messung. Sie Kann Ausgewertet Werden
Ersteflanke = 1 '/ / Bei Der Naechsten Flanke Beginnt Der Naechste Messzyklus
End If
Return
So diesen Code versteh ich eher, da gibts auch keinerlei Störungen und wenn er mal was anzeigt dann stimmt das auch, ABER die Version zählt nur mal aller 5 Runden und nur wenn man langsam fährt.
Auf jeden Fall wenn was ausgewertet wird stimmt das super genau nur eben ist irgendwas viel zu lahm.
Und die Variante mit dem NE567 hatte ich auch schon ins Auge gefasst, nur muss man dem nicht per Widerstände und Kondensatoren was vorgeben an Frequenz?
So also weiter basteln....und Infos sammeln
DANKE für eure Hilfe
EDIT jetzt gehts bei Version 1 wieder mit beiden Autos, hab das störende mal zerlegt, weiß nich was da war.
Auf jeden Fall wenn man die Fehlmessungen weggbekommt würde es schon gehen, bestimmt was mit Timing oder sowas.........
Lesezeichen