es gibt mehrere Möglichkeiten das Servosignal eines Empfängers auszuwerten, dabei gefällt mir die Methode mit den Schaltknüppelimpulsen (1x links, 2xlinks,...) am besten, nur wird dafür der Timer0 schon benötigt um die Impulszeiten auszuwerten. Wie wird das nun bewerkstelligt, wenn noch Sonderfunktionen wie z.B. Blinken, Doppelblitz, Horn, etc. dazu kommt? Soweit ich weiss hat der Attiny13 und/oder Attiny2313 nur einen Timer und ich will nicht unbedingt mit waitms arbeiten, da dieser Befehl mein ganzes Hauptprogramm zerstückeln würde.
kleiner Tipp... Du kannst das Servosignal auch sehr gut mit "Pulsein" abfragen. Da sparst Du Dir den Timer.
Hier im Beispiel ist PINB 4 das Servosignal. Ist der Hebel oben, wird LED1 ein bzw. ausgeschaltet. Ist der Hebel unten, wird LED2 ein bzw. aus geschaltet.
Do Pulsein Ppm , Pinb , 4 , 1 If Ppm < Unterer_nullpunkt Then Toggle LED 1 Wait 1 End If If Ppm > Oberer_nullpunkt Then Toggle LED 2 Wait 1 End If Loop
Ich hoffe ich konnte dir damit helfen. So kannst Du ohne Timer Servosignal abfragen.
ja richtig Sven, das mit den verschiedenen Lagen und Positionen der Schalthebel wäre auch noch ne Methode. Jedoch würde ich die Impulsmethode (1x Links, 2x Links) eher bevorzugen, da ich dort "unbegrenzte" Möglichkeiten in alle Richtungen habe ohne zusätzliche Schalter, etc. an der Fernbedinung montieren zu müssen. Ich will einen Tiny entwickeln, indem alle Funktionen enthalten sind (Blinker, Blaulicht, Horn, Licht, Nebellicht), ob das sinnvoll und machbar ist wird sich zeigen Im Blink-Tiny von Harry wurde es auch irgendwie zusammengeflickt, dass Blinker, Rundumleuchte und Impulsmethode unabhängig voneinander in einem Tiny agieren
mittels der Pulsein eingabe funktioniert das auch mit mehrmaligem Betätigen. Nimm doch eine Variable und zähle diese bei jedem Betätigen in eine Richtung hoch. Nach einer gewissen Zeit fragst du die Variable ab. 1, 2 oder 3 als Beispiel. Bei wert 1 = Blinker ein, bei Wert 2 = Warnblink, bei Wert = Licht
das habe ich mir auch schon überlegt, nur hängt (glaube ich) die Abfrage auch wieder zeitlich von nem timer ab. Er braucht ja einen festgelegten Zeitwert, indem er periodisch seine Abfragen durchnimmt.
ich würde da so planen: Der Timer dient lediglich dazu, die Impulse richtig zu erkennen, also ob Links, Rechts oder Mittelstellung empfangen wird.
1. Warte auf Impuls, kommt ein Impuls, die Länge über Timer 0 ermitteln. 2. Wird jetzt ein Ausschlag nach L oder R erkannt, wird eine entsprechende Variable um 1 erhöht. (Ist die Variable für die andere Richtung ungleich 0, ist die entsprechende Aktion auszuführen). Anschließend wird gewartet, bis die Mittelstellung wieder erkannt wird. Ab diesem Zeitpunkt wird mit jedem weiteren Impuls vom Empfänger eine weitere Variable erhöht, die als Timer 1, 2, 3... dient. Wird unterhalb eines Schwellwertes (z.B. 50 => 50 * 20ms = 1000ms = 1s) ein weiterer Ausschlag in die gleiche Richtung erkannt, geht es wieder zu 1. 2. Ist der Schwellwert überschritten, wird je nach Wert der Richtungsvariablen die entsprechende Aktion ausgeführt. Die Variable wird dann wieder auf 0 gesetzt. 3. Blink-/Lichtfunktionen werden ausgewertet und umgesetzt. 4. Es geht wieder mit 1. weiter.
Für die entsprechenden Aktionen wird lediglich eine kleine Routine aufgerufen, die entsprechende Variablen setzt: a) Licht an/aus b) Nebellicht an/aus c) Warnblinker an/aus d) Blinker links an/aus e) Blinker rechts an/aus f) Blaulicht an/aus g) Horn an/aus
Dabei gibt es bei den Blinkern Prioritäten und Abhängigkeiten: Ist der Warnblinker an, werden normale Blinkfunktionen ignoriert. Ist der Blinker in eine Richtung an und der Warnblinker wird eingeschaltet, wird der "normale" Blinker deaktiviert Ist der Blinker in eine Richtung an und es wird in die andere Richtung geblinkt, wird der andere Blinker deaktiviert.
Weiterhin musst Du in dem Abschnitt (Punkt 3) für die Lichtfunktionen weitere Zähler erhöhen und auswerten, damit z.B. bei "Blinker links" gezählt wird, wie lange der schon an ist. Wird ein Schwellwert überschritten, wird die LED umgeschaltet. Ebenso für das Blaulicht.
Da in der Hauptroutine immer auf ein Signal (also ein Interrupt über den entsprechenden Pin) gewartet wird, hast Du da ja eine relativ gute Zeitmessung und die Zähler werden nur langsam erhöht.
Ein Problem könnte mit unterschiedlichen Fernsteuerungen auftreten, da je nach Protokoll die Zeit zwischen zwei Impulsen bei 11 bis 22 ms liegen kann. Das müsste man mal mit einem Oszilloskop und verschiedenen Sendern / Empfängern / Protokollen (DSM2 und DSMX) testen.
Nochmal zu den versch. Zählern für die Blink-Zeitmessung: Die Zeit für zwei Impulse sollte bei 11 bis 22 ms liegen. Ich nehme jetzt mal 20 ms an, macht das Rechnen etwas einfacher ;) In einer Sekunde (1000 ms) sollten also 50 Impulse ermittelt werden. Somit müssten, wenn eine Blink-LED eine Sekunde leuchten und eine Sekunde ausgeschaltet sein soll, jeweils die entsprechende Variable bis 50 zählen. Über ein Bit kann man ja den gewünschten Zustand für Blaulicht steuern. Für Blinker und Warnblinker würde ich zwei Bit verwenden: 00: beide Blinker aus 01: Blinker rechts an, links aus 10: Blinker links an, rechts aus 11: Warnblinker an
Vielen Dank für die Tipps. Ich habe nun die Interrupts in einen extra Zähler (Timer1) gepackt und werden mittels Zähler und Select Case angewählt. Das funktioniert soweit.
Nun das nächste Problem: Die Schaltung auf dem Testboard ist sehr langsam, da scheint was mit den Zeiten nicht zu stimmen. Wenn ich ein Signal bekomme springt er in den Interrupt, dieser soll eine LED schnell ein und ausschalten. In der Praxis benötigt die aber über eine Minute für Ein- und Aus.
Hab ihn in den Fuses mit intern 8 Mhz eingestellt. Habe nun Divide by 8 rausgemacht, nun läuft er ein bisschen schneller. Wenn ich die Prescale noch auf 1 runterziehe läuft er fürs blitzen, blinken, etc. zwar schnell genug aber ich denke nicht, dass das die Lösung für das Problem ist oder sehe ich das falsch?
ich denke mal, das ist Bascom, oder? Damit habe ich noch nichts gemacht, daher muss ich etwas raten...
Mit On Timer1 Zeit definierst Du, dass bei einem Timer-Interrupt an das Label "Zeit" gesprungen wird, oder?
Was macht der Befehl? Timer1 = 3036
Ist das die Initialisierung, damit von diesem Wert aus bis 165535 gezählt wird und danach ein Überlauf passiert?
Wenn ich das Programm aber richtig interpretiere, dann hast Du eine Endlosschleife, die eigentlich ständig prüft, wie der Eingangspin geschaltet ist. Was Du aber machen solltest, wäre zu warten, bis ein Signal am Pin anliegt, von da ab die Zeit messen, bis der Pin wieder auf 0 geht. Und mit dieser gemessenen Zeit kannst Du weiterarbeiten (also daraus ermitteln, ob Links, Mitte oder Rechts übertragen wurde).
Wenn dieser Abschnitt abgearbeitet wurde, dann sind 22ms seit der vorherigen Verarbeitung vergangen. Diesen Wert kann man eigentlich einmal mit dem Oszilloskop ermitteln, aber für das Blinken sollte die Genauigkeit nicht ganz so wichtig sein. Das kriegt man auch mit Probieren raus.
Theoretisch kannst Du den Tiny auch schlafen schicken und bei dem externen Interrupt (Pin B1 ändert sich) aufwachen lassen. Das spart etwas Strom, kannst Du aber für später noch ignorieren.
richtig, On Timer1 Zeit ist der Punkt, an dem der Zähler nach seinem Überlauf hinspringt und die vorgelagerte Zahl mit 3036 ist, dass er gleich nen Überlauf hat ohne lange zu warten. Das ist nur das "Testprogramm" um die Schaltungen und den Timer1 zu überprüfen, die Zeitauswertungen von den einzelnen Signalen und Positionen vom Empfänger sind in einem anderem Programm bereits realisiert worden, sodass das Programm nicht andauern hin- und her springen muss. Komisch ist aber, wenn ich den Wert von Timer1 auf Timer0 umschreibe die LED´s extrem schnell blinken, beim gleichen Prescale und gleichen Ablaufzeiten, genau so wie ich haben will
Also, 8MHz wirst Du sicherlich nicht brauchen. Da laufen Dir die Timer vielleicht sogar zu schnell über. ;) Der Tiny2313 hat zwei Timer, wobei Timer0 nur ein 8-Bit-Timer ist, Timer1 ein 16-Bit-Timer.
Wie hast Du mit dem Oszilloskop denn die Frequenz gemessen? Du könntest jetzt ein Mini-Programm erstellen, das einen Port als Ausgang definiert und in einer Endlos-Schleife diesen auf 0 und auf 1 setzen. Aber an der Stelle kommt der Compiler ins Spiel, je nachdem, was er daraus macht. Weiterhin, wenn alles optimal in Maschinencode umgesetzt wird, kriegst Du 1/4 der Zeit den Ausgang eingeschaltet, und 3/4 der Zeit ausgeschaltet. Das sollte mit einem Osi zu sehen sein. Der Grund liegt im Rücksprung der Schleife, da ein Jump-Befehl eben zwei Takte braucht. 1 Takt: Ausgang einschalten 1 Takt: Ausgang ausschalten 2 Takte: Sprung
Mich hat es nur gewundert, dass der Timer0 die richtige Geschwindigkeit hat und ich beim Timer1 erstmal auf Prescale = 1 schalten muss, damit er annähernd schnell läuft. Würde ich den Prescale wieder auf 8 oder 16 hochsetzen, blinkt die LED selbst im kleinsten Wert (also Case 1 - Case 2) länger als 2 Sekunden pro Case. Das Oszilloskop hab ich parallel zur LED angeschlossen um die Signale auszuwerten.