Archiv verlassen und diese Seite im Standarddesign anzeigen : RC-Empfänger Auswerten
Halllo Zusammen,
ich habe folgendes Problem:
Ich möchte gerne einen Empfänger Kanal auslesen, und einen Wert zwischen -100 und +100 Bekommen. Wie man dass mit ner Summensignalmessung macht is mir klar nur ich möchte den Normalen RC Ausgang vom Empfänger nehmen! Ich programmiere in Bascom.
Kann mir da jemand weiter Helfen??
Vielen Dank im Voraus
Che Guevara
20.03.2010, 19:46
Hallo Minimax,
im Prinzip ist es ganz einfach ;-)
Du configuriest einen externen interrupt auf steigende flanke (rising) und in der isr startest du dann einen timer (z.b. timer0). Außerdem configurierst du den interrupt um, auf fallende flanke (falling). Wenn der interrupt nun das nächste mal ausgelöst wird, stopst du den timer, configurierst wieder auf falling.
In der timer isr (welche auf z.b. 10µs eingestellt wird) erhöhst du jedesmal einen wert, welchen du dann beim fallenden signalpegel in eine andere variable einliest. diese variable ist dann dein PWM-Wert. Diese solltest du jedoch noch durch 100 teilen, um auf einen wertebereich zwischen 0 und 255 zu kommen.
Hier mal schnell ein beispiel, habs gerade schnell geschrieben, müsste aber funktionieren ;-)
$regfile = "m32def.dat"
$crystal = 16000000
$framesize = 80
$hwstack = 80
$swstack = 80
Config Lcd = 20 * 4
Config Lcdpin = Pin , Db4 = Portc.0 , Db5 = Portc.1 , Db6 = Portc.2 , Db7 = Portc.3 , E = Portc.4 , Rs = Portc.5
Config Lcdbus = 4
Initlcd
Cls
Config Pind.2 = Input
Portd.2 = 1
Config Int0 = Rising
On Int0 Servo_input
Enable Int0
Config Timer2 = Timer , Prescale = 1
Timer2 = 96
On Timer2 Servo_zaehler
Stop Timer2
Enable Timer2
Dim Servo_pin As Bit
Dim Servo_wert As Word
Dim Servo_wert_read As Word
Servo_pin = 0
Enable Interrupts
Do
If Servo_wert_read <> 0 Then
Servo_wert_read = Servo_wert_read / 100
Locate 1 , 1
Lcd "Servo_wert: " ; Servo_wert_read ; " "
Servo_wert_read = 0
End If
Loop
End
Servo_zaehler:
Timer2 = 96
Incr Servo_wert
Return
Servo_input:
If Servo_pin = 0 Then
Servo_pin = 1
Timer2 = 96
Start Timer2
Config Int0 = Falling
Elseif Servo_pin = 1 Then
Servo_pin = 0
Stop Timer2
Config Int0 = Rising
Timer2 = 96
Servo_wert_read = Servo_wert
End If
Return
Gruß
Chris
Ah ok -- :-k
Nur was ist der Servo wert den ich noch durch 100 Teilen muss??
Is das Servo Wert?
Che Guevara
21.03.2010, 13:46
Der servo wert ist die high-zeit des pwm-signals. 1ms entspricht einem wert von 100.
Da du ja einen wert im ms haben möchtest, musst du durch 100 teilen.
128 bedeutet z.b., dass das signal 128ms lang high ist und 255-128=127ms low ist.
Hoffe das ist verständlich, bin nicht so der Erklärer
Gruß
Chris
Also ist 0 = -100 % und 225 = + 100% ??
Che Guevara
21.03.2010, 16:47
ja, so könnte man es sagen.
ah ok danke! Und die Variable ist dann ServoWert wo die 0 bis 225 angegeben sind? Also das Gemessene?
radbruch
21.03.2010, 16:57
Könnte man das nicht auch mit dem Pulsein-Befehl lösen?
Che Guevara
21.03.2010, 18:56
nein, servo_wert_read ist die endgültige variable.
Was ich noch vergessen habe, du musst nach jedem Messen die variable servo_wert zurücksetzen, da diese sonst immer größer wird.
Gruß
Chris
und wo schreibe ich das rein? Am Ende der Procedure? Und ich habe noch den Timer1 nebenbei laufen und in seiner Subrrutine Disable Ich die Interrups und am Ende der Rutine Enable ich sie -- ist das nen Problem?
Che Guevara
23.03.2010, 19:19
hab jetzt nochmal ein neues Programm geschrieben, welches mit weniger Hardware auskommt (also nur 2 ext. Interrupts) und sonst nichts ;-)
Dadurch hast du nicht immer diese blöde Timer-isr und hast mehr Zeit für andere sachen.
Hier mal der Code:
$regfile = "m32def.dat"
$crystal = 16000000
$framesize = 80
$hwstack = 80
$swstack = 80
Config Lcd = 20 * 4
Config Lcdpin = Pin , Db4 = Portc.0 , Db5 = Portc.1 , Db6 = Portc.2 , Db7 = Portc.3 , E = Portc.4 , Rs = Portc.5
Config Lcdbus = 4
Initlcd
Cls
Cursor Off
Config Pind.2 = Input
Portd.2 = 0
Config Pind.3 = Input
Portd.3 = 0
Config Int0 = Rising
On Int0 Kanal_1
Enable Int0
Config Int1 = Rising
On Int1 Kanal_2
Enable Int1
Dim Kanal(2) As Word
Dim Rc(2) As Word
Enable Interrupts
Do
Locate 1 , 1
Lcd "Servo(1): " ; Rc(1) ; " "
Locate 2 , 1
Lcd "Servo(2): " ; Rc(2) ; " "
Waitms 100
Loop
End
Kanal_1:
While Pind.2 = 1
Waitus 10
Incr Kanal(1)
Wend
Rc(1) = Kanal(1)
Kanal(1) = 0
Return
Kanal_2:
While Pind.3 = 1
Waitus 10
Incr Kanal(2)
Wend
Rc(2) = Kanal(2)
Kanal(2) = 0
Return
Aber hier noch die Antworten auf deine Frage, falls du lieber den ersten Code verwenden möchtest:
Im label "Servo_input" schreibst du nach "Servo_wert_read = Servo_wert " noch "servo_wert = 0".
Das mit dem disablen der Interrupts kannst du dir sparen, da diese sowieso standartmäßig disabled sind (also in isr's) ;-)
Solltest du es doch verwenden wollen (aus welchen Gründen auch immer), könntest du auch "Disable Timer1" schreiben, dann wird nur dieser disabled.
Gruß
Chris
Hi, ok Also ich werde den 2. Code nehmen! Ich habe den Timer1 jetzt mit "Stop Timer1" Angehalten und mit "Start Timer1" gestartet. Wenn ich deinen Code richtig verstehe, springt der nurnoch bei einer Änderung des Schaltzustandes in die ISR ?? RC(1 bzw. 2) sind die Zustände mit 0 bis 225 ?
Könnte man das nicht auch mit dem Pulsein-Befehl lösen?
Gute Idee werde ich mal testen. :-)
Richard
Hi,
@Chris: Dein Code funkt I wie net! Ich Teile Rc(1) / 100 und gehe damit in ne If then else endif schleife rein aber die LED's leuchten net und per Print befehl bekomme ich nur zahlen um 1000 und net Tiefer (also org wert) egal ob ich den Knüppel ändere :-( Und dein Erster Code Liefert nur nullen :-k
Hast du nen Tipp?
Sauerbruch
24.03.2010, 15:42
Wieviele Empfängerausgänge willst Du denn messen? (Weil Che Guevara einen Code für 2 Pulslängen reingestellt hat)
128 bedeutet z.b., dass das signal 128ms lang high ist und 255-128=127ms low ist.
Das ignoriert aber die Tatsache, dass RC-Impulse eine ziemlich kleines Impuls/Pausen-Verhältnis haben! Die Impulse dauern zwischen 0,8 und 2 ms, währen die Pause ca. 20ms dauert.
Außerdem ist es u.U. ungünstig, den Controller länger in einer ISR festzunageln, wie es hier durch die While..Wend-Schleife geschieht:
Kanal_1:
While Pind.2 = 1
Waitus 10
Incr Kanal(1)
Wend
Rc(1) = Kanal(1)
Kanal(1) = 0
Return
Wenn Du es nicht mit dem ja bereits vorgeschlagenen Pulsein-Befehl machen möchtest, hätte ich eine ziemlich einfache Lösung. Müsste nur wissen, mit welchen Takt der Controller läuft.
Hi, der Controller läuft mit 16 MHZ! Ich benötige nur 2 Kanäle!
Sauerbruch
24.03.2010, 17:36
Okay - 2 Kanäle, handelsübliche Impulslängen von 0,8 - 2,0 ms, 16 MHz Taktfrequenz.
Wenn Du mit Timer1 ohne Prescaler arbeitest, zählt er während eines kurzen Impulses (0,8ms) um 12.800 weiter, während eines langen Impulses (2ms) um 32.000 - stimmt´s?
Der Code liefert Dir erstmal die beiden Impulsdauern in dieser Form, d.h. als Word-Variablen zwischen 12.800 und 23.000. Wie Du sie dann in %-Angaben oder sonstwas verwurstest, bleibt Dir überlassen :-)
Die Idee ist die, den Timer einfach durchlaufen zu lassen. Außerdem konfigurierst Du zwei Interrupt-Eingänge auf "Change", für jeden Kanal einen.
In der ISR fragst Du den Level des auslösenden Pins ab. Ist er 1 (d.h. Impuls hat gerade begonnen), weist Du einer Variablen "Start" den aktuellen Timerwert zu. Ist der Pin 0 (d.h. der Impuls ist zu Ende), weist Du einer Variablen "Stop" wiederum den aktuellen Timerwert zu - und setzt ein Flag.
In der Hauptschleife fragst Du das Flag ab. Ist es 1, subtrahiertst Du einfach "Stop" - "Start". Dadurch, dass man auch über den Wert 0 hinweg subtrahieren kann, ist es egal, wenn der Timer während des Impulses überläuft. Die Differenz entspricht der Impulslänge und liegt zwischen 12.800 und 32.000.
Konkret also etwa so:
...
...
Config Timer1 = timer
Start timer1
Dim Start1 as word
Dim Stop1 as word
Dim Impuls1 as word
Dim Flag1 as bit
Dim Start2 as word
Dim Stop2 as word
Dim Impuls2 as word
Dim Flag2 as bit
Config Int0=Change
On Int0 Impuls1
Enable Int0
Config Int1=Change
On Int1 Impuls2
Enable Int1
Enable Interrupts
Do
If Flag1 = 1 then
Flag1 = 0
Impuls1 = Stop1 - Start1
Locate 1,1
Lcd Impuls1
End if
If Flag2 = 1 then
Flag2 = 0
Impuls2 = Stop2 - Start2
Locate 2,1
LCD Impuls2
End if
Loop
Impuls1:
If Pind.2=1 then
Start1 = Timer1
Else
Stop1 = Timer1
Flag1 = 1
End if
Return
Impuls2:
If Pind3 = 1 then
Start2 = Timer1
Else
Stop2 = Timer1
Flag2 = 1
End if
Return
Ist ungeprüft, weil ich 1. gerade nicht @home bin und 2. noch nie sowas wie einen Mega32 in den Händen hatte :-) Müsste aber funktionieren...
Gruß,
Daniel
Hi, Welche Variable ist denn die zwischen 12.800 und 23.000 ?? Impuls 1 u 2?
Ich habe den Timer1 bereits in Verwendung daher kann ich dass auch mit Timer2 machen?
Sauerbruch
24.03.2010, 18:29
Hi, Welche Variable ist denn die zwischen 12.800 und 23.000 ?? Impuls 1 u 2?
Beide: Impuls1 und Impuls2!
Ich habe den Timer1 bereits in Verwendung daher kann ich dass auch mit Timer2 machen?
Das hättest Du auch schon mal früher sagen können :-)
Da Du den Code ja wahrscheinlich nicht nur abtippen willst, sondern ihn auch verstanden hast ( :-b ) sei nur am Rande angemerkt, dass das natürlich auch mit dem Timer2 geht! Da der aber nur 8 Bit hat, müsstest Du die Variablen Start1/2, Stop1/2 und Impuls1/2 als Bytes deklarieren.
Wenn er bei 16 MHz eine Impulslänge von 2ms zählen soll, würde ein Prescaler von 128 gerade mal so ausreichen. 256 wäre sicherer, würde aber eine nicht so gute Auflösung bringen.
Klar? :-)
Ähmm nicht wirklich?!?!?! Also Timer2 = Timer Prescale128
und dann den Start wert -- wie groß soll der sein? Wenn ich die Variabeln als Byte deklariere welchen unterschied macht dass? Oder ist die Vorwahl egal und ich nehme nur nen Prescale von 256?
Sauerbruch
25.03.2010, 11:49
Wenn ich die Variabeln als Byte deklariere welchen unterschied macht dass?
Bist Du sicher, dass Du mit dem Bascom-Lernen wirklich ganz, ganz vorne angefangen hast?
Die Idee hinter meinem Ansatz ist die, den Timer überhaupt nicht mit irgendwelchen Werten vorzulanden, sondern ihn permanent durchlaufen zu lassen. Von 0 bis 255, und dann wieder von 0 bis 255, usw.
Wenn die Flanke des Signals steigt, übergibst Du den gerade aktuellen Timer-Wert an eine Variable, nennen wir sie mal Start. Wenn die Flanke fällt, hat der Timer logischerweise ein Stückchen weitergezählt, und in diesem Moment übergibst Du seinen neuen Wert an eine zweite Variable, die ich originellerweise Stop genannt habe.
Die Differenz zwischen Stop und Start ist die Anzahl der Schritte, die der Timer während der High-Phase des Impulses weitergezählt hat.
Weil man Byte-Variablen "über den Nullpunkt hinweg" subtrahieren kann, ist es dabei vollkommen egal, bei welchem Timer-Wert Du die Messung anfängst. Vielleicht wird das an einem Beispiel klarer:
Angenommen, es vergehen 50 Timer-Takte während der High-Phase des Impulses. Egal, bei welchem Wert der Timer im Moment des L/H-Überganges ist: Die Differenz ist immer 50!
Start = 25, Stop = 75, Stop-Start = 50
Start = 130, Stop = 180, Stop - Start = 50
Start = 220, Stop = 24 (weil der Timer inzwischen einmal "übergelaufen" ist), 24 - 220 ergibt auf Byte-Ebene aber auch wieder 50. Das ist so - probier´s mal aus!!
Und weil Timer1 16Bits umfasst, müsste man für die Verwendung dieses Timers die Variablen Start, Stop und Differenz als Words dimensionieren. Timer0 und 2 haben nur 8 Bits, deshalb reichen hierfür Bytes aus.
BTW: Hast Du schon mal mit einem Timer ´ne LED zum blinken gebracht? :-b
Hi, LED Ja habe ich dafür ist das ganze ja gedacht :-)
Ich habe soeben dein Code ausprobiert und für mich sieht die Ausgabe der Zahlen willkürlich aus! Ungefähr so: 1 250 168 5 8 154 75 142 usw.
Mache ich was Falsch? Ich habe von einen Normalem Empfänger den Impulspol einfach an den PD2 (Int0) angschlossen - is dass richtig? Was der Unterschied zwischen Byte und Word ist is mir Klar nur welchen vorteil dass bringen soll net :roll:
Sauerbruch
25.03.2010, 12:13
Okay - also die einfachere Variante mit nur einem Kanal. Die ganz blöden Fragen gleich mal vorneweg (sorry, aber daran liegt´s sooo oft):
- Die Masse des RX ist auch mit der Board-Masse verbunden?
- Der Controller läuft auch wirklich auf 16 MHz?
Wenn ja, wäre hier mal ein Code-Vorschlag für einen Kanal an INT0:
$regfile=m32def.dat
$Crystal=16000000
(Config LCD.........)
Config Timer2=Timer, Prescale=256
Start Timer2
Config INT0=Change
On INT0 Flanke
Enable INT0
Enable Interrupts
Dim Start1 as Byte
Dim Stop1 as Byte
Dim Impuls as Byte
Fim Flag as Bit
Do
If Flag = 1 then
Flag = 0
Impuls = Stop1 - Start1
Locate 1,1
LCD Impuls; " " (die Leerzeichen, weil Impuls 2- oder 3stellig sein kann)
End if
Loop
Flanke:
If PIND.2=1 then
Start1 = Timer2
Else
Stop1 = Timer2
Flag = 1
End if
Return
Müsste eigentlich klappen...
EDIT: Bei Start und Stop als Variablen meckert Bascom natürlich - sorry, da habe ich gepennt. Nenn´ sie Start1 und Stop1 (oder Max und Moritz, wie immer Du willst...)
Hi, Masse des Empfängers is ja am Akku Drann und der µC is am Netzgerät = 2 Schaltkreise. Muss ich masse vom Empfänger noch zusätzlich an den µC Masse hängen?
Sauerbruch
25.03.2010, 13:08
Aber hallo - irgendeine Verbindung müssen die Massen der beiden Stromkreise haben, sonst kann´s nicht funktionieren!
Ob Du auf der einen Seite das Board oder das Netzteil nimmst ist egal, und auf der anderen Seite kann´s der Akku oder der RX sein. Aber beide Seiten müssen miteinander verbunden sein!!
Hi, es funktioniert Trotzdem net! selbst wenn ich beide Masse pole Verbinde vom Akku und vom Netzteil :-(
Hier mal mein Code:
$regfile = "m32def.dat" ' specify the used micro
$crystal = 16000000 ' used crystal frequency 16mHz
$framesize = 80
$hwstack = 80
$swstack = 80
$baud = 9600
Config Porta.0 = Output
Config Porta.1 = Output
Config Porta.2 = Output
Config Porta.3 = Output
Config Porta.4 = Output
Config Porta.5 = Output
Config Porta.6 = Output
Flashlinks Alias Porta.0
Flashrechts Alias Porta.1
Baconheck Alias Porta.2
Flashheck Alias Porta.3
Landescheinwerfer Alias Porta.4
Posilightlirot Alias Porta.5
Posilightregruen Alias Porta.6
Timer1 = 3000
Config Timer1 = Timer , Prescale = 8
Enable Timer1
Stop Timer1
On Timer1 Flash
Gosub Flashoff
Gosub Landescheinwerferoff
Gosub Posilightsoff
Dim V As Byte
Dim Flasher As Byte
Dim Posi As Byte
Declare Sub Flash
Config Timer2 = Timer , Prescale = 128
Start Timer2
Dim Start1 As Byte
Dim Stop1 As Byte
Dim Impuls1 As Byte
Dim Flag1 As Bit
Dim Start2 As Byte
Dim Stop2 As Byte
Dim Impuls2 As Byte
Dim Flag2 As Bit
Config Int0 = Change
On Int0 Impuls1
Enable Int0
Config Int1 = Change
On Int1 Impuls2
Enable Int1
Enable Interrupts
Start Timer1
Do
Gosub Flashon
Gosub Landescheinwerferoff
Gosub Posilightsoff
If Flag1 = 1 Then
Flag1 = 0
Impuls1 = Stop1 - Start1
Print Impuls1
End If
If Flag2 = 1 Then
Flag2 = 0
Impuls2 = Stop2 - Start2
Print Impuls2
End If
Loop
Impuls1:
If Pind.2 = 1 Then
Start1 = Timer2
Else
Stop1 = Timer2
Flag1 = 1
End If
Return
Impuls2:
If Pind.3 = 1 Then
Start2 = Timer2
Else
Stop2 = Timer2
Flag2 = 1
End If
Return
Flash:
Stop Timer1
If V = 0 Then
Set Flashlinks
Set Flashrechts
Set Flashheck
End If
If V = 1 Then
Reset Flashlinks
Reset Flashrechts
Reset Flashheck
End If
If V = 2 Then
Waitms 30
End If
If V = 3 Then
Waitms 30
End If
...
'Enable Interrupts
Incr V
Start Timer1
Timer1 = 3000
Return
Flashon:
If Flasher = 0 Then
Start Timer1
Flasher = 1
End If
Return
Flashoff:
Stop Timer1
Flasher = 0
Return
Landescheinwerferon:
If Landescheinwerfer = 0 Then
Set Landescheinwerfer
End If
Return
Landescheinwerferoff:
If Landescheinwerfer = 1 Then
Reset Landescheinwerfer
End If
Return
Posilightson:
If Posi = 0 Then
Set Posilightlirot
Set Posilightregruen
Posi = 1
End If
Return
Posilightsoff:
If Posi = 1 Then
Reset Posilightlirot
Reset Posilightregruen
Posi = 0
End If
Return
Ich bekomme beim Print immer nur 0?!?
Ich hoffe dass ich dort einen Fehler drinne Habe ;-)
Sauerbruch
25.03.2010, 13:29
Wow - das sieht nach einem gigantischen Flieger aus :-)
Ich wusste nicht, dass Du mit Print arbeitest. Dieser Befehl braucht immer ene ganze Zeit - und so wie der Code gerade ist, wird der Print-Befehl nach jedem (!) Impuls ausgeführt. Das heißt etwa 50 mal pro Sekunde. Das könnte problematisch sein.
Du könntest mal zwei Zähler etablieren (z.B. Z1 und Z2 als Bytes). In den Interrupt-Routinen lässt Du Z jedesmal um eins hochzählen, wenn ein Impuls fertig ist.
In der Hauptroutine könntest Du dann so dafür sorgen, dass z.B. nur nach jedem 50. Impuls grprintet wird. Also insgesamt etwa so:
...
...
Do
If Flag1 = 1 then
Flag 1 = 0
Impuls1 = Stop1 - Start1
If Z1 = 50 then
Print Impuls
Z1 = 0
End if
End if
(analog das gleiche für Start2, Stop2, Impuls2 und Z2)
Loop
...
Impuls1:
If Pind.2 = 1 Then
Start1 = Timer2
Else
Stop1 = Timer2
Flag1 = 1
Z1 = Z1 + 1
End If
Return
...
...
Sonst fallen mir auf den ersten Blick keine Fehler auf...
Hi, naja aber warum bekomme ich nur nullen im Print?
Ich bekomme immer Verschiedene Werte :-( :-(
Die LEDs zucken und flacker wie die Lust und Laune haben. Die Knüppel stellelungen schlagen nur geringfügig ein - hast du nen tipp`?
radbruch
25.03.2010, 15:47
Hallo
Ich hab's jetzt auch mal versucht die Impulslängen der Servosignale mit Bascom zu messen. Mit dem Pulsein-Befehl habe ich es nicht geschafft, aber mit einer einfachen Zählschleife funktioniert es recht gut:
$regfile = "m32def.dat"
$crystal = 8000000
$hwstack = 32
$swstack = 8
$framesize = 24
$baud = 38400
Dim A As Byte
Dim Counter As Integer
Config Servos = 1 , Servo1 = Portc.0 , Reload = 10
Config Portc.0 = Output
'Servo(1) = 100
Enable Interrupts
Do
Print
Print "----------------"
For Servo(1) = 30 To 150 Step 10
Waitms 500
Counter = 0
Do ' Warten bis aktiver Impuls zu Ende
A = Pinc.0
Loop Until A = 0
Do ' Warten bis Pause fertig
A = Pinc.0
Loop Until A = 1
Do
A = Pinc.0
Incr Counter ' Zähler erhöhen
'Waitus 2
Loop Until A = 0 ' Solange impuls ansteht
Counter = Counter - 149 ' Wert für Mittelstellung abziehen
Print "Winkel:" ; Servo(1)
Print "Zähler: " ; Counter
Print
Next
Loop
Das Programm erzeugt mit Config Servos seine eigenen Impulse und misst dann deren Länge mit einer Zählschleife. Der Drehbereich meines angeschlossenen Servos ist 30 bis 150. Die Zählwerte sind ohne Verzögerung durch waitus in der Zählschleife und ohne Korrektur von 49 bis 249:
Winkel:30
Zãhler: 49
Winkel:40
Zãhler: 66
Winkel:50
Zãhler: 82
Winkel:60
Zãhler: 99
Winkel:70
Zãhler: 116
Winkel:80
Zãhler: 133
Winkel:90
Zãhler: 149
Winkel:100
Zãhler: 166
Winkel:110
Zãhler: 183
Winkel:120
Zãhler: 199
Winkel:130
Zãhler: 216
Winkel:140
Zãhler: 233
Winkel:150
Zãhler: 249
Mit Korrektur -149 erhalte ich folgende Werte:
Winkel:30
Zãhler: -100
Winkel:40
Zãhler: -83
Winkel:50
Zãhler: -66
Winkel:60
Zãhler: -50
Winkel:70
Zãhler: -33
Winkel:80
Zãhler: -16
Winkel:90
Zãhler: 0
Winkel:100
Zãhler: 17
Winkel:110
Zãhler: 34
Winkel:120
Zãhler: 50
Winkel:130
Zãhler: 67
Winkel:140
Zãhler: 84
Winkel:150
Zãhler: 100
Bin ich jetzt selbst etwas überrascht wie gut das passt ;) Für schneller getaktete Kontroller kann man in der Zählschleife noch etwas mit waitus spielen. Bei 16MHz muss man vermutlich nur den Zählwert halbieren.
Gruß
mic
Hi, ähm und wo lese ich meinen Port ein?? Sollte ich da vielleicht in der Schleife meine Interrups abschalten?
radbruch
25.03.2010, 16:32
Hallo
INT0 ist PD2 und INT1 ist PD3. In der Zählschleife muss man diese Ports eintragen:
Do ' Warten bis aktiver Impuls zu Ende
A = Pind.2
Loop Until A = 0
Do ' Warten bis Pause fertig
A = Pind.2
Loop Until A = 1
Do
A = Pind.2
Incr Counter ' Zähler erhöhen
'Waitus 2
Loop Until A = 0 ' Solange impuls anstehtMit der Zählschleife kannst du aber auch jeden anderen Pin verwenden.
Bei gesperrten Interrupts wären die Werte genauer und reproduzierbarer, aber die Zählschleife dauert unter Umständen zwei Impulszyklen lang, also über 20ms. Das könnte deine interruptgesteuerten Funktionen stören.
Gruß
mic
radbruch
25.03.2010, 17:05
Das bedeutet, du mußt es selbst ausprobieren. Ich kann bei meinem Programm die Interrupts nicht sperren, weil ich dann keine Servoimpulse mehr erzeuge.
Hi, naja die Interrupts sperre ich net sondern ich benutzte sie!
Sauerbruch
25.03.2010, 18:08
Also, Dein Projekt ist ja ganz schön groß, mit ´nem Haufen Subroutinen, Printbefehlen, etc., etc. Wenn´s dutzende Stellen gibt an denen es haken könnte, ist es manchmal ganz hilfreich, nochmal gaaaaanz von vorne anzufangen, und dann schön nacheinander Stufe für Stufe dazuzuprogrammieren. Dann merkt man nämlich sofort, bis wohin es geht - und ab wann nicht mehr.
Als erstes würde ich mal checken, ob der Controller den Empfängerimpuls überhaupt versteht. Ganz einfacher Code:
$regfile=m32def.dat
$Crystal=16000000
Config Timer2 = Timer, Prescale = 256
Stop Timer2
Timer2=0
Dim Zahl as Byte
PORTD.2=1 'PullUp-Widerstand - für alle Fälle...
Print "Test - Test" 'nur um zu sehen, ob die Kommunikation mit dem PC klappt...
wait 1
Do
Bitwait PIND.2, reset
Bitwait PIND.2, set
Start Timer2
Bitwait PIND.2, reset
Stop Timer2
Zahl = Timer2
Timer2=0
Print Zahl
waitms 500
Loop
Hack´ das doch mal rein und schließ den Empfänger an den Eingang D.2 an. Das müsste je nach Knüppelstellung Werte zwischen etwa 60 und 120 geben.
Hi, also ichbekomme als Rückmelödung im Print folgende Werte:
Knüppel hinten: 69/70
Knüppel vorne: 118/119
Die werte schwanken immer um +- 1 oder +-2
Also dass geht ja schon ma - wie gehts weiter?
Sauerbruch
26.03.2010, 12:55
Also dass geht ja schon ma - wie gehts weiter?
Na also - dann haut die Schnittstelle RX->Timer doch schon mal hin!!
Ab hier gibt es schätzungsweise mindestens 7684 Möglichkeiten weiterzumachen! Leider fehlt mir im Moment die Zeit, mir alle möglichen neue Codes auszudenken - aber was noch viel schlimmer ist: Du würdest NIX dabei lernen :-)
Wenn Du weißt wie man einen Timer konfiguriert, wie man mit Interrupts umgeht, und was die schlimmsten No-Go´s sind, wirst Du sicherlich in relativ kurzer Zeit Deinen eigenen Code zusammenbekommen - und eine Menge für neue Projekte lernen!
Und wenn nicht, solltest Du genau dort anfangen (wie es praktisch jeder hier in desem Forum irgendwann einmal gemacht hat). Eine Unmenge an Beiträgen zu den verschiedensten Themen findest Du im RN-Wissensbereich.
Ansonsten wird sich jeder hier Deine Entwürfe gerne ansehen und ggf. Verbesserungsvorschläge machen - fang´ einfach an!!
Hi, ich habe deinen Test Code nun mal einen Sub gelegt und wollte ihn immer aufrufen in der Hauptrotine aber der Timer1 funkt mir dazwischen was kann ich tun?
Sauerbruch
26.03.2010, 15:01
...Code zeigen :-)
$regfile = "m32def.dat" ' specify the used micro
$crystal = 16000000 ' used crystal frequency 16mHz
$framesize = 80
$hwstack = 80
$swstack = 80
$baud = 9600
Config Porta.0 = Output
Config Porta.1 = Output
Config Porta.2 = Output
Config Porta.3 = Output
Config Porta.4 = Output
Config Porta.5 = Output
Config Porta.6 = Output
Flashlinks Alias Porta.0
Flashrechts Alias Porta.1
Baconheck Alias Porta.2
Flashheck Alias Porta.3
Landescheinwerfer Alias Porta.4
Posilightlirot Alias Porta.5
Posilightregruen Alias Porta.6
Timer1 = 3000
Config Timer1 = Timer , Prescale = 8
Enable Timer1
Stop Timer1
On Timer1 Flash
Gosub Flashoff
Gosub Landescheinwerferoff
Gosub Posilightsoff
Dim V As Byte
Dim Flasher As Byte
Dim Posi As Byte
Declare Sub Flash
Config Timer2 = Timer , Prescale = 256
Stop Timer2
Timer2=0
Dim Zahl as Byte
Dim Z11 As Byte
Enable Interrupts
Start Timer1
Do
Waitms 20
Loop
Empfaengerwerten:
Gosub Empfaengereins
Return
Empfaengereins:
Bitwait PIND.2, reset
Bitwait PIND.2, set
Start Timer2
Bitwait PIND.2, reset
Stop Timer2
Zahl = Timer2
Timer2 = 0
Waitms 500
Return
Empfaengersort:
Print Zahl
If Zahl > 105 Then
Gosub Flashon
Gosub Landescheinwerferon
Else
If Zahl > 85 Then
Gosub Flashon
Gosub Landescheinwerferoff
Else
If Zahl < 75 Then
Gosub Flashoff
Gosub Landescheinwerferoff
End If
End If
End If
Return
Flash:
'Disable Interrupts
Stop Timer1
If V = 0 Then
Set Flashlinks
Set Flashrechts
Set Flashheck
End If
If V = 1 Then
Reset Flashlinks
Reset Flashrechts
Reset Flashheck
End If
If V = 2 Then
Waitms 30
End If
If V = 3 Then
Waitms 30
End If
If V = 4 Then
Set Flashlinks
Set Flashrechts
Set Flashheck
End If
If V = 5 Then
Reset Flashlinks
Reset Flashrechts
Reset Flashheck
End If
If V = 6 Then
Waitms 30
Set Baconheck
End If
If V = 7 Then
Gosub Empfaengerwerten
End If
If V = 8 Then
Gosub Empfaengersort
End If
If V = 9 Then
End If
If V = 10 Then
Waitms 30
End If
If V = 11 Then
Waitms 30
End If
If V = 12 Then
End If
If V = 13 Then
End If
If V = 14 Then
Waitms 30
Reset Baconheck
End If
If V = 15 Then
Waitms 30
V = 0
'Enable Interrupts
Start Timer1
Timer1 = 3000
Return
End If
'Enable Interrupts
Incr V
Start Timer1
Timer1 = 3000
Return
Flashon:
If Flasher = 0 Then
Start Timer1
Flasher = 1
End If
Return
Flashoff:
Stop Timer1
Flasher = 0
Reset Flashlinks
Reset Flashrechts
Reset Flashheck
Reset Baconheck
Return
Landescheinwerferon:
If Landescheinwerfer = 0 Then
Set Landescheinwerfer
End If
Return
Landescheinwerferoff:
If Landescheinwerfer = 1 Then
Reset Landescheinwerfer
End If
Return
Posilightson:
If Posi = 0 Then
Set Posilightlirot
Set Posilightregruen
Posi = 1
End If
Return
Posilightsoff:
If Posi = 1 Then
Reset Posilightlirot
Reset Posilightregruen
Posi = 0
End If
Return
Sauerbruch
26.03.2010, 19:07
ich habe deinen Test Code nun mal einen Sub gelegt
Eine Sub?? Das ist doch mindestens ein halbes Dutzend...
Also:
1. ISRs soll man so kurz wie nur irgend möglich halten. Warum? Weil während eines Interrupts zwar die nächsten IRQs angenommen, aber nicht ausgeführt werden können. Also idealerweise nur schnell ein Flag setzen, das in der -> Hauptschleife dann anzeigt, dass ein Interrupt passiert ist.
2. In der Hauptschleife (von DO bis LOOP) dürfen ruhig auch ein paar Befehle stehen!
3. Waitms... in einer ISR ist eines von den klassischen No-Go´s, weil es aus genannten Gründen für lange Zeit das Abarbeiten von anderen IRQs blockiert. Deine Timer1-ISR wird ja schon ca. 30mal pro Sekunde angesprungen, da kann es leicht sein, dass er sozusagen von einem Timer1-IRQ nahtlos in den anderen übergeht.
4. Eine ISR sollte man nur im äußersten Notfall über ein Goto oder Gosub verlassen - und dann muss man unbedingt sicherstellen, dass das Programm korrekt in die ISR zurückkehrt, um sie sauber über das return zu verlassen. Ansonsten läuft Dir der Stack in wenigen Sekunden über.
Möglicherweise wiederhole ich mich, aber ich würde an Deiner Stelle versuchen, all die Features nacheinander dazuzustricken, und nicht alles auf einmal. Und die Messung des Empfängerimpulses solltest Du unbedingt über einen Interrupt machen, da die Bitwait-Geschichte den Controller irrsinnig lange aufhält. Das war nur ein ganz grobes Testprogramm um zu sehen, ob der Controller den Empfänger überhaupt erkennt.
Naja mein Problem ist ja wenn ich das in die Do loop schleife schreibe, unterbricht meine Timer1 ISR das Abfragen des Kanals :-(
Ich weiß einfach nicht mehr weiter! Wie ich dass so lösen kann, dass mein Timer die Port Abfrage net Unterrbricht :-k
Sollte ich vielleicht die "Leeren" Timer1 isr's canceln und in der Zeit die Port abfrage tun?
Hi, Ich habe jetzt deine "schnelle" Variante genommen - geht sehr gut:
$regfile = "m32def.dat" ' specify the used micro
$crystal = 16000000 ' used crystal frequency 16mHz
$framesize = 80
$hwstack = 80
$swstack = 80
$baud = 9600
Config Porta.0 = Output
Config Porta.1 = Output
Config Porta.2 = Output
Config Porta.3 = Output
Config Porta.4 = Output
Config Porta.5 = Output
Config Porta.6 = Output
Flashlinks Alias Porta.0
Flashrechts Alias Porta.1
Baconheck Alias Porta.2
Flashheck Alias Porta.3
Landescheinwerfer Alias Porta.4
Posilightlirot Alias Porta.5
Posilightregruen Alias Porta.6
Config Timer2=Timer, Prescale=256
Start Timer2
Config INT0=Change
On INT0 Flanke
Enable INT0
Enable Interrupts
Dim Start1 As Byte
Dim Stop1 As Byte
Dim Impuls As Byte
Dim Flag As Bit
Dim V11 As Byte
Do
If Flag = 1 then
Flag = 0
Impuls = Stop1 - Start1
If Impuls > 110 Then
Set Flashlinks
Set Flashrechts
Set Baconheck
Set Flashheck
Set Landescheinwerfer
Else
If Impuls > 80 Then
Set Flashlinks
Set Flashrechts
Set Baconheck
Set Flashheck
Reset Landescheinwerfer
Else
If Impuls < 75 Then
Reset Flashlinks
Reset Flashrechts
Reset Baconheck
Reset Flashheck
Reset Landescheinwerfer
End If
End If
End If
If V11 = 50 Then
Print "Impuls Kanal 1 " ; Impuls ; " " 'die Leerzeichen, weil Impuls 2- oder 3stellig sein kann)
V11 = 0
End If
End if
Loop
Flanke:
If PIND.2=1 then
Start1 = Timer2
Else
Stop1 = Timer2
Flag = 1
V11 = V11 + 1
End if
Return
Ich habe das Problem jetzt erkannt - Timer 1 und die Blitzlichter :-b :twisted: :frown: :(
Ich galube da muss ich mir was anderes Überlegen - oder hast du einen Tipp? :-b
Sauerbruch
27.03.2010, 12:53
Okay - ich wollte Dir gerade auf Deinen vorletzten Beitrag hin empfehlen, die Impulserkennung über einen Interrupt zu machen. Das hast Du ja schon mal mit Erfolg gemacht!
Kannst Du vielleicht noch ein Bisschen was zum Kapitel "Timer1 & die Blitzlichter" sagen? Was soll denn als Ergebnis am Ende rauskommen?? Mit ein paar mehr Infos kriege ich vielleicht auch einen Tip zusammen... :-)
Hi, also es funktionier so:
Blitz
kurze Pause
Blitz
Kurze Pause
Bacon an
Lange Pause
Bacon aus
Kurze Pause
Die Timer Frequenz weist de ja schon. Eine Blitz funktioniert so:
Timer1 läuft über -> ISR -> LED an -> Timer1 läuft über -> ISR -> LED aus
Eine Kurze Pause ist so: Timer1 läuft über -> ISR -> Waitms 30 -> Timer1 läuft über -> ISR -> Waitms 30
Eine Lange pause ist insgesamt etwa 7 Überläufe mit in jeder 4. Isr ein Waitms 30
Stop Timer1
If V = 0 Then
Set Flashlinks
Set Flashrechts
Set Flashheck
End If
If V = 1 Then
Reset Flashlinks
Reset Flashrechts
Reset Flashheck
End If
If V = 2 Then
Waitms 30
End If
If V = 3 Then
Waitms 30
End If
If V = 4 Then
Set Flashlinks
Set Flashrechts
Set Flashheck
End If
If V = 5 Then
Reset Flashlinks
Reset Flashrechts
Reset Flashheck
End If
If V = 6 Then
Waitms 30
Set Baconheck
End If
If V = 7 Then
Gosub Empfaengerwerten
End If
If V = 8 Then
Gosub Empfaengersort
End If
If V = 9 Then
End If
If V = 10 Then
Waitms 30
End If
If V = 11 Then
Waitms 30
End If
If V = 12 Then
End If
If V = 13 Then
End If
If V = 14 Then
Waitms 30
Reset Baconheck
End If
If V = 15 Then
Waitms 30
V = 0
'Enable Interrupts
Start Timer1
Timer1 = 3000
Return
End If
'Enable Interrupts
Incr V
Start Timer1
Timer1 = 3000
Return
Das is die ORGINAL Beleuchtung eines PPL-A Schein unterliegenden Flugzeuges nach der Anlage 1 zu §§ 17 und 19 Abs.
7 der LuftVO.
Ich hoffe ich habe genug Infos dir gegeben sonst einfah fragen ;-)
Sauerbruch
28.03.2010, 00:28
Eine Lange pause ist insgesamt etwa 7 Überläufe mit in jeder 4. Isr ein Waitms 30
Nochmal: Waitms 30 in einer ISR ist ungefähr so schlau wie bei 30 kn Ostwind nach Westen zu starten.
Wenn das kleinste Zeitintervall 30ms ist, und der Rest ganzzahlige Vielfache davon sind, dann würde ich in der ISR einfach nur eine Variable um 1 hochzählen lassen. In der Hauptschleife bietet es sich dann an, mit "Select Case" die entsprechenden Ausgänge zu steuern.
Wenn die Hauptschleife die Flash- und Beaconausgänge periodisch nach einem festen System auf High und Low legt, musst Du Dir noch etwas einfallen lassen, wie der RC-Empfänger mit einbezogen werden soll. So wie Du es bisher gemacht hast, dürfte dessen Einfluss nur von sehr begrenzter Dauer sein, weil alle 30ms die Ausgänge neu gesetzt werden. Man könnte das z.B. ganz einfach über die DDR-Register regeln!
Hi, ähm DDR Register - was is das? ;-) War das nicht das um die Datenrichtung (ein/ausgang) zu bestimmen? Aber was soll das Bringen? Erklär dass doch mal etwas genauer
Sauerbruch
28.03.2010, 14:44
Hi, ähm DDR Register - was is das?
*Seufz... das meinte ich mit "ganz vorne anfangen..."
Also: Wenn ich Dich richtig verstanden habe, sollen Zwei Dinge parallel laufen: Erstens soll ein regelmäßiger Rhythmus für die Flashlights und die Beacon generiert werden, gleichzitig sollen diese Gruppen und die Landescheinwerfer per RC-Signal ein- und ausgeschaltet werden. Richtig??
Ersteres würde ich mit der Variablen V machen, die in der Timer1-ISR alle 30 ms hochgezählt wird. Select Case hatte ich ja schon angedeutet:
...
...
Do
...
Select Case V
Case 1:
Set Flashlinks
Set Flashrechts
Set Flashheck
Case 2:
Reset Flashlinks
Reset Flashrechts
Reset Flashheck
Case 4:
Set Flashlinks
Set Flashrechts
Set Flashheck
Case 5:
Reset Flashlinks
Reset Flashrechts
Reset Flashheck
Case 6:
Set Baconheck
Case 14:
Reset Baconheck
Case 16:
V=0
End select
...
Nur am Rande sei erwähnt, dass man den Effekt der Zeilen
Set Flashlinks
Set Flashrechts
Set Flashheck
auch kürzer bekommen kann:
PORTA = PORTA OR &B00001011
Damit setzt Du in einem Rutsch die Ausgänge A.0, A.1 und A.3, weil die Operation X ODER 1 als Resultat immer 1 hat, während X ODER 0 immer X ergibt.
Wenn die Flashlights wieder aus sollen, könntest Du schreiben
PORTA = PORTA AND &B11110100
Damit löschst Du die Ausänge A.0, A.1 und A.3, denn X UND 0 ergibt immer 0, während X UND 1 immer X ergibt.
(Boolesche Algebra...).
Wie Du schon richtig vermutet hast, legt das DDR-Register fest, welcher der Anschlüsse als Ausgang konfiguriert ist. Wenn Du Deine Lampen nicht mit einem superhochverstärkenden Vorverstärker ansteuerst, kannst Du die Anschlüsse einfach als Eingang konfigurieren - dann bleiben die daran angeschlossenen Lampen aus, unabhängig davon, was im dazugehörigen PORT-Register steht.
Beispiel:
Flashlights und Beacon aktiv, Landescheinwerfer und Positionslichter aus:
DDRA = &B00001111
Positinslichter an, Rest aus:
DDRA = &B01100000
Nur Flashlights aktiv:
DDRA = &B00001011
dafür würde sich ein zweiter Select-Case-Befehl in der Hauptschleife anbieten, der die Variable Impuls abcheckt.
BTW: Kenst Du eigentlich das Buch von Roland Walter? :-)
Hals- und Beinbruch!!
Hi, Ja das Buch kenne ich ;-)
Also: Wenn ich Dich richtig verstanden habe, sollen Zwei Dinge parallel laufen: Erstens soll ein regelmäßiger Rhythmus für die Flashlights und die Beacon generiert werden, gleichzitig sollen diese Gruppen und die Landescheinwerfer per RC-Signal ein- und ausgeschaltet werden. Richtig??
Ja! Also es sind 2 SChalter vorhanden (1x 3Stufen und 1x 2Stufen) Über den 2Stufen schalter wird der Landescheinwerfer ein/aus geschaltet.
Und auf dem 3Stufen Schalter soll es so laufen: Posilichter aus, Flash aus --> Posilichter an, Flash aus --> Posilichter an, Flash an.
So nur die Sache mit dem Flash macht mir Kopfschmerzen :-k
Sauerbruch
28.03.2010, 15:24
So nur die Sache mit dem Flash macht mir Kopfschmerzen
Wieso??
...
...
Select case Impuls
Case is > 110: DDRA = &B01111111 'Flash, Beacon, LS und PosLi als Ausgang
Case 75 to 109: DDRA = &B01101111 'Flash, Beacon und PosLi als Ausgang
Case is < 75: DDRA = &B01100000 'Nur PosLi als Ausgang
End select
..
..
Hi, Ja das Buch kenne ich
Großartig - es gibt m.E. kein besseres, um Bascom von der Pieke auf zu lernen!!!
EDIT:
In Deinem Beitrg von vorgestern 18.00 Uhr sind´s noch die Landescheinwerfer, die zusammen mit dem Flashlight über den 3-stufigen Schalter geschaltet werden sollen. Das geht ein wenig durcheinander, aber wenn Dir das Prinzip klar ist, kannst Du natürlich auch die Positionslichter über das DDR-Register steuern!
Hi, naja so wie du dass Schaltest leuchten alle LED's Dauer ;-)
Die Flash lights muss ich ja mit dem µC zum Blinken Bringen - darum Kopfschmerzen :-k
Sauerbruch
28.03.2010, 17:35
naja so wie du dass Schaltest leuchten alle LED's Dauer
Wenn das so wäre, hätte ich´s nicht so geschrieben.
DDRDX.Y = 1 heißt mitnichten, dass der Ausgangspin ein High führt. Er ist lediglich als AUSGANG konfiguriert. Ob er eine 1 oder 0 führt, hängt von PORTX.Y ab.
Mein Vorschlag war also der, in der Hauptroutine die Ports vom Flasher und der Beacon kontinuierlich in ihrem Rhythmus zu setzen und zu löschen, und auf DDR-Ebene zu entscheiden, ob diese Levels wirklich an die Endverbraucher kommen (DDRX.Y = 1) oder eben nicht (DDRX.Y = 0).
BTW: Das Buch von Roland Walter kostet echt nicht die Welt...
Hi, ähmm irgendwie verstehe ich nicht ganz was du meinst? Was hat die DDR ebene damit zu tun ob die LED's an oder aus sind?!? WAs ich jetzt gemacht habe, ist DDRD = &B11111111 --> Alle Ports im Segment D sind als Ausgang konfiguriert ;-)
Sauerbruch
29.03.2010, 11:34
So wie ich das verstanden habe willst Du doch die Flashs und die Beacon nicht immer an oder immer aus haben, sondern sie sollen blinken oder nicht blinken, je nach Steuerknüppelstellung. Richtig??
Und eine von 2914 Möglichkeiten das zu realisieren wäre die:
1. die PORTs (!!) werden in der Hauptschleife immer und immer nach Deinem Muster gesetzt und resettet. Also Flash an, Flash aus, Flash an, Flash aus, Beacon an, laaaange pause, Bacon aus.
2. Wenn das RC-Signal aber grade anzeigt, dass z.B. die Flashs aus sein sollen, setzt Du die dazugehörigen DDR-Register einfach auf 0. Dann sind die Anschlusspins des Controllers als Ausgänge quasi "abgehängt", völlig unabhängig davon, was auf der PORT-Ebene passiert.
Jetzt klarer??
Hi,
So wie ich das verstanden habe willst Du doch die Flashs und die Beacon nicht immer an oder immer aus haben, sondern sie sollen blinken oder nicht blinken, je nach Steuerknüppelstellung. Richtig??
Jop!
1. die PORTs (!!) werden in der Hauptschleife immer und immer nach Deinem Muster gesetzt und resettet. Also Flash an, Flash aus, Flash an, Flash aus, Beacon an, laaaange pause, Bacon aus.
2. Wenn das RC-Signal aber grade anzeigt, dass z.B. die Flashs aus sein sollen, setzt Du die dazugehörigen DDR-Register einfach auf 0. Dann sind die Anschlusspins des Controllers als Ausgänge quasi "abgehängt", völlig unabhängig davon, was auf der PORT-Ebene passiert.
Also: Wenn die Lichter Aus sein Sollen setzte ich das dazugehörige register auf 0 und wenn die Flasher ein sein Sollen, setze ich sie auf 1 ? Richtig??? Und die Flash reinfolge passiert unabhämging von den Schalterzuständen? Richtig?? Nur wie SOll ich die Flaher laufen lassen? Mit ner Case abfrage in do und in der Timer_isr einfach "incr Blabla" ?? :-k
So habe es jetzt so gemacht und siehe da -- es funktionier - naja halb ;-)
Wenn ich mit DDRA = ... die Ausgänge auf Eingang schalte, leuchten die LED's ganz leicht noch - geht dass später mit nem Transistor weg?
Sauerbruch
29.03.2010, 18:46
Wenn ich mit DDRA = ... die Ausgänge auf Eingang schalte, leuchten die LED's ganz leicht noch - geht dass später mit nem Transistor weg?
Das ist der kleine Schönheitsfehler an meinem Gedanken.
Das PORTX.Y-Register legt ja fest, ob ein Anschluss, der als Ausgang konfiguriert ist, 1 oder 0 führt. Wenn der Anschluss als Eingang konfiguriert ist, ist das PORT-Register aber nicht ganz unbeteiligt: Ist es 1, wird ein eingebauter PullUp-Wierstand aktiviert, der den Eingangspin auf ein definiertes High zieht, wenn er komplett unbeschaltet in der Luft hängt. Das ist dann wichtig, wenn Du z.B. einen Taster oder sowas abfragst, denn frei in der Luft hängende Pins fangn sich sofort alle möglichen Störsignale (z.B. 50Hz-Brumm, aber auch hochfrequente Signale) ein.
Dieser PullUp-Widerstand nach +5V ist zwar hochohmig (ca. 50 kOhm), aber offensichtlich reichen diese 0,1mA schon aus, Deine LEDs ein bisschen leuchten zu lassen. Eine Transistorstufe würde das sogar noch verschlimmern, weil man mit 50 kOhm gegen +5V einen Transistor ohne weiteres komplett durchsteuern kann.
Die einfachste Lösung hierfür wäre, dass Du Deine LEDs nicht vom Controller nach Masse legst, sondern genau adersherum von +5V zum Controller. Da die LED ohnehin an +5V hängt, ist der 50 kOhm-PullUP nach +5V ohne Wirkung.
Das wird eigentlich auf fast allen Boards ohnehin so gemacht, weil der Strom, den ein LOW-Anschluss nach Masse ableiten kann höher ist als der Strom, den er im HIGH-Zustand z.B. an eine LED abgeben kann.
Man muss dann halt nur umdenken, denn RESET xyz schaltet die LED an, und SET schaltet sie aus. Aber das haben sch viele Bascom-Anwender geschafft.
Nur wie SOll ich die Flaher laufen lassen? Mit ner Case abfrage in do und in der Timer_isr einfach "incr Blabla" ??
Ich bin zwar absolut kein Profi, würde es aber genau so machen. Oder spricht irgendetwas dagegen?
Also LED + geht an AVR und GND an Netzteil meinst du dass so? Aber ich schalte ja eh später mit nem Mosfet ?!? Der läuft ja über 100 OHM und dann gegen Base --> siehe (http://hoelscher-hi.de/hendrik/light/led/lux.gif)
Geht dass so?
Sauerbruch
29.03.2010, 19:04
Okay - dann muss ´ne andere Lösung her. So´n FET würde natürlich von den 50 kOhm komplett durchgesteuert.
Dann würde ich das so machen, dass Du in der Hauptschleife die Select Case-Abfrage machst, und vor dem Einschalten der entsprechenden Ausgänge die Impuls-Variable abfragst. Also etwa so:
...
...
Select Case V
Case 1:
If Impuls > 185 then
Set Flashlinks
Set Flashrechts
SetFlashheck
End if
Case 2:
Reset Flashlinks
Reset Flashrechts
Reset Flashheck
...
...
Das resetten sollte unabhängig von der Variablen Impuls laufen, denn wenn Du per 3-Stufenschalter die Flashs in dem Moment ausschaltest wo sie gerade an sind, müssen sie in der nächsten Select-Case-Runde ja trotzdem ausgeschaltet werden.
D.h. ganz allgemein: Das Einschalten mit einem "If Impuls</> blabla" verknüpfen, das Auschalten nicht. Dann hast Du alle beiden Funktionen in einer einzigen Select-Case-Schleife.
Hi, also die Abfrage immer in den "Set" schleifen? If Blabla = sowieso then LED an ???? Und die Reset Schleifen einfach so lassen?
Sauerbruch
30.03.2010, 12:20
Würde ich mal sagen. Angeschaltet werden sie nur, wenn der Impuls im richtigen Bereich sind, und ausgeschaltet immer. Das müsste passen...
ok, werde ich gleich mal probieren - werde berichten
So, habe es erst so probiert wie du gesagt hattest - es funktioniert aber die Schaltzeit dauerte mindestens 5-10 sec. Jetzt habe ich das so gelößt, dass in der RC auswertung einfach der Timer Disabled wird, alle Ports Resettet und fertig ;-)
Naja das wars dann wohl \:D/ Wenn ich Fragen habe, darf ich dich doch anschreiben ?
Eine Frage noch, so wie ich die SChaltung Gepostet (http://hoelscher-hi.de/hendrik/light/led/lux.gif) habe is die doch IO oder?
\:D/ \:D/ \:D/ \:D/ \:D/ \:D/ \:D/ \:D/ \:D/ \:D/ \:D/ \:D/ \:D/ \:D/ \:D/ \:D/\:D/ \:D/ \:D/ \:D/ \:D/ \:D/ \:D/ \:D/ \:D/ \:D/
Frohe Oster euch allen und wenn du, Sauerbruch nochmal antwortest, wäre das schön ;-)
Sauerbruch
31.03.2010, 18:15
Na, das ist doch ein erhebendes Gefühl, wenn die kleinen Dinger ENDLICH das machen, was man sich von ihnen wünscht :-)
...dass in der RC auswertung einfach der Timer Disabled wird, alle Ports Resettet und fertig
Das verstehe ich aber nicht ganz. Dann müssten ja jedesmal alle Lichter ausgehen, wenn ein RC-Impuls reingeflattert kommt - was ja so schätzungsweise 50 mal pro Sekunde passiert [grübel] ...
Vielleicht kannste ja den Code nochmal posten?
Der Schaltplan sieht auf den ersten Blick gut aus. Laut Datenblatt liefert der Spannungsregler maximal 1,5 Ampere, währen der FET 26 Ampere Dauerstrom schalten kann. Der Transistor sollte Dir also schon mal nicht abrauchen :-)
Wie auch immer - danke für die netten Osterwünsche & viel Spaß bei neuen Projekten!!
Hi, also das is nicht mein Plan ;-) De Regler wird eh anders gelößt! Also Ich gehe in die Abfrage des Servo Impulses - dann wird der Wert ermittelt und ddann in die If then else endif abfrage geschoben. Dort wo der Flasher aus sein soll (Schalter unten, Mitte) wird einfach der Timer Disabled und alle Flash Leds Resettet! Das wars :-) Ich danke dir und den Anderen für die Hilfe \:D/
Und wie gesagt Frohe Ostern! Bei Fragen PN
Powered by vBulletin® Version 4.2.5 Copyright ©2024 Adduco Digital e.K. und vBulletin Solutions, Inc. Alle Rechte vorbehalten.