PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Impulslänge einer Fernsteuerung messen



JL
14.03.2005, 21:09
Hallo,

nach dem Einlesen in die Programmierung habe ich versucht, mit dem nachfolgenden Programm die Länge der Impulse von meiner Fernsteuerung zu messen. Das ist mein kleines Einstiegsprojekt 8-[


'----- Titel -------------------------------------------------------------------
' Module.......: ServoSignal.bas
' Purpose......: Measure and show radio control pulse length
'-------------------------------------------------------------------------------

'----- Settings ----------------------------------------------------------------
$regfile = "2313DEF.Dat"
$crystal = 4000000

Config PortB = Output
Config PinB.0 = input 'used for RC signal
Config PortD = Output

config Timer0 = timer , prescale = 64
on timer0 Mispulse

'----- Functions ---------------------------------------------------------------
Declare Sub GetPulse(PulseLength As byte )

'----- Variables ---------------------------------------------------------------
Dim PulseLength As byte 'stores current reading of RC signal
Dim PulseLast As byte 'stores last reading of RC signal
Dim PulseError as Byte 'stores errors, given by timer0
'Dim PulseLengthMin As Byte
'Dim PulseLengthMax As Byte

'----- Initialization ----------------------------------------------------------
PulseLength = 0
PulseLast = 0
PulseError = 0
PortB = &B00000000
'PulseLengthMax = 0
'PulseLengthMin = 0
enable Timer0
enable Interrupts

'----- Program -----------------------------------------------------------------
do
call GetPulse(PulseLength)
'PulseLast = PulseLength
PortD = &B00000000 'delete last value of pulse length

select case PulseLength
case 000 to 036 : PortD.0 = 1
case 037 to 072 : PortD.1 = 1
case 073 to 108 : PortD.2 = 1
case 109 to 144 : PortD.3 = 1
case 145 to 180 : PortD.4 = 1
case 181 to 216 : PortD.5 = 1
case 217 to 252 : PortD.6 = 1
end select
'print PulseLast

loop

end 'end program

'----- Subroutines -------------------------------------------------------------
Sub GetPulse(PulseLength As byte)
PulseLength = 0

WaitForPulse:
!sbis PinB,0 'jump if bit is set = pulse is positive
!rjmp WaitForPulse

WaitForLow: 'run loop until pulse gets negative
Incr PulseLength 'add 1 in variable PulseLength
!sbic PinB,0 'jump if bit is not set = pulse is negative
!rjmp WaitForLow

Timer0 = 0
End Sub

Mispulse:
'print "Timer0 active"
incr PulseError
'Print "Fehler #" ; PulseError
PortB.1 = 0
wait 1
PortB.1 = 1
return

Im Bascom-Simulator läuft es einwandfrei, aber im real existierenden Leben tut es absolut nicht das, was es soll. De facto ist keine Reaktion auf das Eingangssignal festzustellen; d.h. trotz Variation der Eingangs-Impulslänge am Servotester reagieren die am PortD verbundenen LED's nicht.
Deshalb weiß ich jetzt erst einmal nicht weiter... ](*,) Kann hier jemand mit einem Tipp helfen (ich werde das Gefühl nicht los, dass ich einfach etwas Grundlegendes übersehen habe)?

Beste Grüße
Jürgen

PicNick
15.03.2005, 09:55
@JL: "Wait 1" in einer Interrupt-routine mit prescale 64 ist nicht günstig.
Es muß reichen, wenn du "TOGGLE PortB.1" machst.

JL
16.03.2005, 21:09
Hallo Robert,

ich habe die Interrupt-Routine wie vorgeschlagen geändert -> jetzt läufts!
Allerdings schlägt immer der Interrupt vom Timer zu. Mit einem Prescaler von 1024 läuft es jetzt so, wie es soll, d.h. der Interrupt kommt nur, wenn das Signal längere Zeit ausbleibt.
Was ich aber immer noch nciht verstanden habe ist die Größe des Prescaler. Im Simulationsprogramm reicht ein Prescaler von 64, in der realen Hardware müssen es aber 1024 sein. Da werde ich mir noch einmal die zeitlichen Abläufe ansehen müssen.

PicNick
17.03.2005, 06:28
Es gibt im Download (glaub ich) ein Super hilfreiches Programm
"RNAVR", daß die beim Berechnen Prescale etc. hilft.