Welche Auflösung benötigst du wirklich für deine Anwendung?Timer für Servos, läuft mit 1MHz, ergibt 1000 Schritte Auflösung pro ms
Hallo zusammen,
ich möchte mehrere RC Signale einlesen und auf mehrere Servos ausgeben. Leider ist es mir das nach 2 Wochen noch immer nicht gelungen.
Das ganze ist für eine Bagger Steuerung. Das fertige Programm soll 3 RC-Eingänge und 2 Poti-Eingänge einlesen, sowie 4 Servoausgänge ausgeben.
Ein RC-Eingang fragt den Betriebsmode (Fahrbetrieb/Baggerbetrieb) ab.
Zwei weitere RC-Eingänge bekommen die Signale von den Knüppelstellungen der Fernbedienung.
Die Potis dienen der Servowegbegrenzung (vergleichbar mit DualRate).
2 Servos gehen zum Baggerarm (je nach Betriebsmode aktiv).
2 Servos zum Kettenanrieb (je nach Betriebsmode aktiv).
Eine funktionierende ISR für die Servoausgabe habe ich bereits realisieren können, doch leider verträgt sich diese nicht mit dem Pulsein Befehl (die „romanartigen“ Kommentare im Programm sind nur für mich Voll-NOP, damit ich immer nachlesen kann, was das Programm gerade macht).
Im folgenden Programm ist die Routine für 4 Servos ersichtlich. Zu Testzwecken wollte ich nur mal ein RC-Signal einlesen und ein Servo damit speisen. Ein weiteres Servo wurde ebenfalls angeschlossen und mit einem Festwert (hier 1500 für Mittelstellung) gespeist. Die ISR wird dabei offensichtlich korrekt abgearbeitet (erkennbar an dem Servo, welches nur die Mittelstellung halten soll). Allerdings zuckt das andere Servo erheblich hin und her. Es reagiert zwar auf die Eingaben am RC-Eingang (Servo folgt „grob“ dem RC-Signal), ist aber ansonsten nicht zu gebrauchen. Ich „vermute“, das die Springerei in die ISR den Pulsein Befehl stört, dadurch falsche Werte eingelesen werden und in folge davon das Servo zuckt. Schade, denn die Funktion dieses Programms hätte ich ausnahmsweise mal nachvollziehen können.
Code:'=============================================================================== 'Baggersteuerung (ACHTUNG FUNKTIONIERT NICHT, SERVO RUCKELT EXTREM) 'RC Empfangskanal 1 an Pin 6 (PA7) 'RC Empfangskanal 2 an Pin 7 (PA6) 'RC Empfangskanal 3 (Mode-Schalter) an Pin 5 (PB2) 'Werte zwischen 100 und 200 entsprechen dem kompletten Knüppelweg 'Der Wert 150 entspricht dabei ca. Mittelstellung, der Wert 200 ca. Vollausschlag 'Poti Eingang 1 Pin 9 (PA4) 'Poti Eingang 1 Pin 8 (PA5) 'Servoausgang 1 Pin13 (PA0) 'Servoausgang 2 Pin12 (PA1) 'Servoausgang 3 Pin11 (PA2) 'Servoausgang 4 Pin10 (PA3) 'Made by Robert (www.roberts-r2d2-bau.de) '=============================================================================== $regfile = "attiny24.dat" $crystal = 8000000 'FuseBit CKDIV8 deaktivieren $hwstack = 32 $swstack = 20 $framesize = 40 '------------------------------------------------------------------------------------------------------------- 'Variablen definieren '------------------------------------------------------------------------------------------------------------- Dim Empfangskanal(3) As Word Dim Servo1_signal As Word Dim Kanal As Byte Dim Servo(4) As Word '------------------------------------------------------------------------------------------------------------- 'Ein- und Ausgang festlegen '------------------------------------------------------------------------------------------------------------- Ddra = &B00001111 'PA0, PA1, PA2 und PA3 werden Ausgänge, der restliche Port A bleibt Eingang Ddrb = &B00000000 'PortB bleibt Eingang '------------------------------------------------------------------------------------------------- 'Timer und Interrupt-Service-Routinen konfigurieren und freigeben '------------------------------------------------------------------------------------------------- Config Timer1 = Timer , Prescale = 8 'Timer für Servos, läuft mit 1MHz, ergibt 1000 Schritte Auflösung pro ms Enable Timer1 'schaltet den Timer1 Overflow-interrupt ein On Timer1 Servoausgabe 'Sprigt bei Timer1 Überlauf in die ISR Enable Interrupts ' Interrupts zulassen '------------------------------------------------------------------------------------------------------------- 'Einigen Variablen Werte zuweisen '------------------------------------------------------------------------------------------------------------- Kanal = 1 '------------------------------------------------------------------------------------------------------------- 'Hauptprogramm starten '------------------------------------------------------------------------------------------------------------- Do Pulsein Empfangskanal(1) , Pinb , 2 , 1 'Zählung läuft, solange der Empfänger Pegel auf 1 ist ' Pulsein Empfangskanal(2) , Pina , 7 , 1 ' Pulsein Empfangskanal(3) , Pina , 6 , 1 Servo1_signal = Empfangskanal(1) * 10 Servo(1) = Servo1_signal Servo(2) = 1500 Servo(3) = 1500 Servo(4) = 1500 Loop End Servoausgabe: '( Info Bei jedem Timer1 Überlauf wird in die ISR(Interrupt Service Routine) gesprungen und eine EINZIGE If -Bedingung erfüllt und abgearbeitet. Ablauf: Pin des ersten Servoausgangs einschalten. Gleichzeitig wird der Timer1 so vorgeladen, dass es nach einer bestimmten Zeit(Wert der Variable "Servo(1)") erneut zu einem Überlauf kommt. Da sonst keine weitere If -Bedingung erfüllt wird , gehts gleich wieder zurück ins Hauptprogramm. Beim folgenden Überlauf ist der erste Servoausgang bereits eingeschaltet , sodass nun die Else -Bedingung greift und der Ausgang wieder ausgeschaltet wird (somit ist das erste Servosignal (je nach Variablenwert 1ms -2ms) gesendet. Gleichzeitig wird die Variable "Kanal" um eins erhöht. Nun trifft die If -Bedingung für den zweiten Servoausgang zu (da die Variable "Kanal" ja nun auf 2 steht) und dieser wird eingeschaltet. Das Spiel wiederholt sich so lange , bis alle Kanäle durch sind. Die letzte If -Bedingung in dieser ISR füllt dann nur noch die verbleibende Zeit auf, um auf eine Wiederholungsfrequenz von ca 20ms zu kommen. ') If Kanal = 1 Then If Porta.0 = 0 Then 'wenn der Ausgangspin aus ist Load Timer1 , Servo(1) 'wird der Timer1 mit dem Wert der Variable "Servo(1)" vorgeladen Porta.0 = 1 'und der Ausgangspin eingeschaltet Else 'erst beim nächsten Timer1 Überlauf landen wir hier Porta.0 = 0 'Ausgangspin wird wieder ausgeschaltet Incr Kanal 'und der nächsten Kanal bearbeitet End If End If If Kanal = 2 Then If Porta.1 = 0 Then Load Timer1 , Servo(2) Porta.1 = 1 Else Porta.1 = 0 Incr Kanal End If End If If Kanal = 3 Then If Porta.2 = 0 Then Load Timer1 , Servo(3) Porta.2 = 1 Else Porta.2 = 0 Incr Kanal End If End If If Kanal = 4 Then If Porta.3 = 0 Then Load Timer1 , Servo(4) Porta.3 = 1 Else Porta.3 = 0 Incr Kanal End If End If '( Pausenauffüllung Jeder der oben angesteuerten Kanälen benötigt zwischen 1 -2ms. Die verbleibende Zeit wird nun hier eingegeben, um auf eine durchschnittliche Periodendauer von ca. 20ms zu kommen. Der eingegebene Zahlenwert entspricht dabei us, z.b. 13000 entspricht 13 ms. ') If Kanal = 5 Then Load Timer1 , 13000 'der Zahlenwert entspricht us Kanal = 1 End If Return
Eine weitere Möglichkeit wäre Hardware-PWM. Allerdings habe ich da noch praktisch keine Erfahrung. Hier im Forum fand ich ein Programm mit HW-PWM, verstehe aber nicht wirklich, was bestimmte einzelne Zeilen bewirken. Ich war ehrlich gesagt überrascht, dass es nach nur wenigen Änderungen auf meinem Attiny24 lauffähig war. Ich habe zwar Erklärungen dieser Abkürzungen in Datenblätter und einigen Seiten im www gefunden, aber zwischen lesen und verstehen ist leider ein erheblicher Unterschied.
Kann mir jemand erklären, was genau die folgenden Zeilen im Detail machen (bin noch Anfänger mit begrenzten Englischkenntnissen ohne Abi/ Studium, daher bitte nicht zu viel Fachwissen voraussetzen).Code:'=============================================================================== 'Servo an Pin 7 (PA6, OC1A) 'RC Empfangskanal an Pin 5 (PB2) '=============================================================================== $regfile = "attiny24.dat" $crystal = 8000000 'FuseBit CKDIV8 deaktivieren $hwstack = 32 $swstack = 20 $framesize = 40 Ddra.6 = 1 'PA6 (Ausgang vom OC1A) wird Ausgang Ddrb = &B00000000 'PortB bleibt Eingang Tccr1a = &B10000000 Tccr1b = &B00010001 Icr1h = &B11111111 Icr1l = &B11111111 Dim Empfangskanal As Word Do Pulsein Empfangskanal , Pinb , 2 , 1 Empfangskanal = Empfangskanal * 40 Ocr1ah = High(empfangskanal) Ocr1al = Low(empfangskanal) Loop
Gibt es dafür auch andere Schreibweisen in Bascom (wie z.B. Config Timer1 = PWM etc), die ich eher nachvollziehen kann?Code:Tccr1a = &B10000000 Tccr1b = &B00010001 Icr1h = &B11111111 Icr1l = &B11111111
Ich bin auch für andere Ideen offen (solange sie in irgendeiner Weise nachvollziehbar bleiben). Im ersten Schritt geht es mir zunächst „nur“ um eine ruckelfreie Ausgabe der Servoimpulse bei gleichzeitigem Einlesen von 3 RC-Signalen.
Mit freundlichen Grüßen
Robert
Welche Auflösung benötigst du wirklich für deine Anwendung?Timer für Servos, läuft mit 1MHz, ergibt 1000 Schritte Auflösung pro ms
Bild hier
Atmel’s products are not intended, authorized, or warranted for use
as components in applications intended to support or sustain life!
hallo radbruch,
ehrlich gesagt weiß ich nicht genau, bis zu welche Auflösung man runter gehen kann. Hängt mit Sicherheit auch von den verwendeteten Servos (Modellflug) oder Drehzahlreglern ab. Da ich die Routinen evt auch in Flugmodellen benutzen werde, müssen sie eben "einigermaßen" flüssig und ruckelfrei laufen.
Bei meinen verwendetet Werten hatte ich den Vorteil, dass ich nicht lange umrechnen muss, da 1000 einer ms entspricht (Anschlag auf der einen Seite) und 2000 zwei ms (Anschlag auf der anderen Seite) .
mfg
Robert
Bei wenigen verschiedenen Servos hatte ich Auflösung im Bereich rund 4 µs festgestellt, wobei ich die Servos in Schritten von 0,4 µs angesteuert hatte, siehe hier für nen schlechten Billigservo und hier für nen billigen Guten. Das macht dann aber wirklich nur Sinn, wenn Du das irgendwie nutzen kannst - ich habe es so ausgelegt, damit ich kleinste, zusätzlich auch langsam(st)e Bewegungen fahren kann.... weiß ich nicht genau, bis zu welche Auflösung man runter gehen kann ...
Wie das in Basic geht, kann ich aber nicht sagen.
Ciao sagt der JoeamBerg
Ungetestet:
Code:'=============================================================================== 'Baggersteuerung (ACHTUNG FUNKTIONIERT NICHT, SERVO RUCKELT EXTREM) 'RC Empfangskanal 1 an Pin 6 (PA7) 'RC Empfangskanal 2 an Pin 7 (PA6) 'RC Empfangskanal 3 (Mode-Schalter) an Pin 5 (PB2) 'Werte zwischen 100 und 200 entsprechen dem kompletten Knüppelweg 'Der Wert 150 entspricht dabei ca. Mittelstellung, der Wert 200 ca. Vollausschlag 'Poti Eingang 1 Pin 9 (PA4) 'Poti Eingang 1 Pin 8 (PA5) 'Servoausgang 1 Pin13 (PA0) 'Servoausgang 2 Pin12 (PA1) 'Servoausgang 3 Pin11 (PA2) 'Servoausgang 4 Pin10 (PA3) 'Made by Robert (www.roberts-r2d2-bau.de) 'Angepasst von radbruch 21.12.2013 'https://www.roboternetz.de/community/threads/63750-Mehrere-RC-Signale-einlesen-und-mehrere-Servos-ausgeben? '=============================================================================== $regfile = "attiny24.dat" $crystal = 8000000 'FuseBit CKDIV8 deaktivieren $hwstack = 32 $swstack = 20 $framesize = 40 '------------------------------------------------------------------------------------------------------------- 'Variablen definieren '------------------------------------------------------------------------------------------------------------- Dim Empfangskanal(3) As Word Dim Empfangskanal_temp_ein(3) As Word Dim Empfangskanal_temp_aus(3) As Word Dim Kanal As Byte Dim Servo(4) As Word '------------------------------------------------------------------------------------------------------------- 'Ein- und Ausgang festlegen '------------------------------------------------------------------------------------------------------------- Ddra = &B00001111 'PA0, PA1, PA2 und PA3 werden Ausgänge, der restliche Port A bleibt Eingang Ddrb = &B00000000 'PortB bleibt Eingang '------------------------------------------------------------------------------------------------- 'Timer und Interrupt-Service-Routinen konfigurieren und freigeben '------------------------------------------------------------------------------------------------- Config Timer1 = Timer , Prescale = 8 'Timer für Servos, läuft mit 1MHz, ergibt 1000 Schritte Auflösung pro ms Compare1a = 1000 ' Nach 1ms wird die ISR initialisiert Timer1 = 1 Enable Compare1a 'schaltet den Timer1 Compare1a Match-Interrupt ein On Compare1a Servoausgabe 'Springt bei Timer1 Compare1a Match in die ISR Enable Interrupts ' Interrupts zulassen '------------------------------------------------------------------------------------------------------------- 'Einigen Variablen Werte zuweisen '------------------------------------------------------------------------------------------------------------- Kanal = 0 ' Kanal startet jetzt bei 0 wegen porta.kanal in der ISR! Servo(1) = 1500 Servo(2) = 1500 Servo(3) = 1500 Servo(4) = 1500 Empfangskanal(1) = 0 Empfangskanal(2) = 0 Empfangskanal(3) = 0 Empfangskanal_temp_ein(1) = 0 Empfangskanal_temp_ein(2) = 0 Empfangskanal_temp_ein(3) = 0 Empfangskanal_temp_aus(1) = 0 Empfangskanal_temp_aus(2) = 0 Empfangskanal_temp_aus(3) = 0 '------------------------------------------------------------------------------------------------------------- 'Hauptprogramm starten '------------------------------------------------------------------------------------------------------------- Do If Pina.7 = 1 And Empfangskanal_temp_ein(1) = 0 Then Empfangskanal_temp_ein(1) = Timer1 End If If Pina.7 = 0 And Empfangskanal_temp_ein(1) <> 0 Then Empfangskanal_temp_aus(1) = Timer1 If Empfangskanal_temp_aus(1) < Empfangskanal_temp_ein(1) Then Empfangskanal_temp_aus(1) = Empfangskanal_temp_aus(1) + 20000 End If Empfangskanal(1) = Empfangskanal_temp_aus(1) - Empfangskanal_temp_ein(1) Empfangskanal_temp_ein(1) = 0 End If If Pina.6 = 1 And Empfangskanal_temp_ein(2) = 0 Then Empfangskanal_temp_ein(2) = Timer1 End If If Pina.6 = 0 And Empfangskanal_temp_ein(2) <> 0 Then Empfangskanal_temp_aus(2) = Timer1 If Empfangskanal_temp_aus(2) < Empfangskanal_temp_ein(2) Then Empfangskanal_temp_aus(2) = Empfangskanal_temp_aus(2) + 20000 End If Empfangskanal(2) = Empfangskanal_temp_aus(2) - Empfangskanal_temp_ein(2) Empfangskanal_temp_ein(2) = 0 End If If Empfangskanal(1) <> 0 Then Servo(1) = Empfangskanal(1) End If If Empfangskanal(2) <> 0 Then Servo(2) = Empfangskanal(2) End If Loop End '( Der Timer startet beim ersten Servo mit dem Zählwert 1, Das Compare-Register wird auf den Wert für die Impulslänge des ersten Servo gesetzt.In der Compere-ISR (wenn der Zählwert den Wert im Compareregister erreicht hat) wird dann ausgehend vom aktuelen Timerwert der Vergleichswert für die Impulslänge des nächsten Servo berechnet und gesetzt. Nach dem letzten Servo wird 20000 für die Wiederholfrequenz des Signals gesetzt ') Servoausgabe: Porta.0 = 0 'alle Servosignale ausschalten Porta.1 = 0 Porta.2 = 0 Porta.3 = 0 If Kanal < 4 Then ' Zeitpunkt für nächstes Servo setzen If Kanal = 0 Then Timer1 = 1 ' beim ersten Servo Timer Zähler zurücksetzen End If Compare1a = Timer1 + Servo(kanal + 1) ' aktueller Timerwert + Servo Impulslänge Porta.kanal = 1 ' Impuls ausgeben Incr Kanal ' nächstes Servo vormerken Else Compare1a = 20000 ' 50Hz Wiederholfrequenz setzen Kanal = 0 End If Return
Geändert von radbruch (21.12.2013 um 09:35 Uhr) Grund: Enable Compare1a
Bild hier
Atmel’s products are not intended, authorized, or warranted for use
as components in applications intended to support or sustain life!
Hallo radbruch,
habe Deinen Vorschlag mal gestestet, funktioniert ähnlich gut wie der Code, den ich in der Zwischenzeit mit Hilfe eines weiteren Forummitglieds gestrickt habe. Mit "ähnlich gut" meine ich, dass ein geringes, aber deutlich sichtbares Servozucken an den Servos vorhanden ist, welche mit den eingelesenen RC-Signalen versorgt werden. Servos, denen ich im Programm einen Festwert zuweise, zucken nicht. Daraus schliese ich, dass die Servoausgabe ISR korrekt und zuverlässig arbeitet, aber sich die Interrupts der RC Einleserei in die Quere kommen. Der folgende Code liest 3 RC-Signale ein und gibt 2 davon an 2 Servos weiter, während die anderen beiden Servos einen Festwert zugewiesen bekommen haben. Ich benutze TIMER1 für das Einlesen (tolle Auflösung) und TIMER0 für die Ausgabe (leider nur noch sehr bescheidene Auflösung).
Inzwischen ist die Auswertung der Poti's auch eingebaut und getestet (hier aber nicht gepostet, da es den Code nur unnötig unübersichtlich macht). Allerdings habe ich die Speicherkapazität des Attiny24 mittlerweile geprengt und warte nun auf die bestellten Attiny84.
Mein momentanes Problem ist das nicht ganz saubere Einlesen der RC Signale. Ich habe auch versucht, immer nur einen der drei Interrupts zuzulassen (z.B. mit "disable INT0" in der entsprechenden ISR) und die RC Signale hintereinander einzulesen, führte aber zu keiner Verbesserung.
mfg
Robert
Code:'=============================================================================== 'RC Eingang 1 an Pin 3 (PB1, PCINT9) 'RC Eingang 2 an Pin 7 (PA7, PCINT7) 'RC Eingang 3 an Pin 5 (PB2, INT0) 'Servo 1 an Pin 13 (PA0) 'Servo 2 an Pin 12 (PA1) 'Servo 3 an Pin 11 (PA2) 'Servo 4 an Pin 10 (PA3) '=============================================================================== $regfile = "attiny24.dat" $crystal = 8000000 'FuseBit CKDIV8 deaktivieren $hwstack = 32 $swstack = 20 $framesize = 40 '------------------------------------------------------------------------------------------------- 'Timer und konfigurieren '------------------------------------------------------------------------------------------------- Config Timer1 = Timer , Prescale = 8 'Timer für Einlesen RC Signale Start Timer1 Config Timer0 = Timer , Prescale = 64 'Timer für Servoausgabe, Wert 125 entspricht 1ms, Wert 250 entspricht 2ms Enable Timer0 On Timer0 Servoausgabe '------------------------------------------------------------------------------------------------------------- 'Variablen definieren '------------------------------------------------------------------------------------------------------------- 'Variablen fürs RC Einlesen Dim Rc_signal_1_start As Word Dim Rc_signal_2_start As Word Dim Rc_signal_3_start As Word Dim Impulslaenge_1 As Word Dim Impulslaenge_2 As Word Dim Impulslaenge_3 As Word 'Variablen für Berechnungen Dim Berechnung_1 As Word Dim Berechnung_2 As Word 'Variablen für Servoausgabe Dim Kanal As Byte Dim Servoausgabe_1 As Byte Dim Servoausgabe_2 As Byte Dim Servoausgabe_3 As Byte Dim Servoausgabe_4 As Byte Dim Pausen_variable As Byte '------------------------------------------------------------------------------------------------- 'Einigen Variablen Werte zuweisen '------------------------------------------------------------------------------------------------- Kanal = 1 Pausen_variable = 0 '------------------------------------------------------------------------------------------------------------- 'Ein- und Ausgang festlegen '------------------------------------------------------------------------------------------------------------- Ddra = &B00001111 'PA0 - PA3 werden Ausgänge Ddrb = &B00000000 'PortB bleibt Eingang '------------------------------------------------------------------------------------------------- 'Interrupt-Service-Routinen konfigurieren und freigeben '------------------------------------------------------------------------------------------------- 'Info: 'Alle Porta Pinchangeinterrupts sind in Bascom "PCINT0" zugeordnet. 'Alle Portb Pinchangeinterrupts sind in Bascom "PCINT1" zugeordnet. Pcmsk1.pcint9 = 1 'beim Flankenwechsel an PB1/PCINT9 (RC Eingang 1) Pinchangeinterrupt1 auslösen und in die Subroutine springen Enable Pcint1 'Pinchangeinterrupt1 (1 weil auf PortB) zulassen On Pcint1 Rc_eingang_1 Pcmsk0.pcint7 = 1 'beim Flankenwechsel an PA7/PCINT6 (RC Eingang 2) Pinchangeinterrupt0 auslösen und in die Subroutine springen Enable Pcint0 'Pinchangeinterrupt0 (0 weil auf PortA) zulassen On Pcint0 Rc_eingang_2 Config Int0 = Change 'beim Flankenwechsel an PB2/INT0 (RC Eingang 3) Int0 auslösen und in die Subroutine springen Enable Int0 On Int0 Rc_eingang_3 Enable Interrupts '====================================================== 'Hauptprogramm '====================================================== Do 'Umrechnung erstes RC Signal auf 8-Bit Berechnung_1 = Impulslaenge_1 / 8 'ergibt Werte zwischen 125 und 250 If Berechnung_1 > 255 Then 'zu hohe Werte abfangen Berechnung_1 = 255 End If If Berechnung_1 < 120 Then 'zu kleine Werte abfangen Berechnung_1 = 120 End If 'Umrechnung zweites RC Signal auf 8-Bit Berechnung_2 = Impulslaenge_2 / 8 'ergibt Werte zwischen 125 und 250 If Berechnung_2 > 255 Then 'zu hohe Werte abfangen Berechnung_2 = 255 End If If Berechnung_2 < 120 Then 'zu kleine Werte abfangen Berechnung_2 = 120 End If Servoausgabe_1 = Berechnung_1 Servoausgabe_2 = Berechnung_2 Servoausgabe_3 = 190 Servoausgabe_4 = 190 Loop '====================================================== 'ISR '====================================================== Rc_eingang_1: If Pinb.1 = 1 Then Rc_signal_1_start = Timer1 Else Impulslaenge_1 = Timer1 - Rc_signal_1_start End If Return Rc_eingang_2: If Pina.7 = 1 Then Rc_signal_2_start = Timer1 Else Impulslaenge_2 = Timer1 - Rc_signal_2_start End If Return Rc_eingang_3: If Pinb.2 = 1 Then Rc_signal_3_start = Timer1 Else Impulslaenge_3 = Timer1 - Rc_signal_3_start End If Return Servoausgabe: If Kanal = 1 Then If Porta.0 = 0 Then 'wenn der Ausgangspin aus ist Load Timer0 , Servoausgabe_1 'wird der Timer0 mit dem Wert der Variable "Servoausgabe_1" vorgeladen Porta.0 = 1 'und der Ausgangspin eingeschaltet Else 'erst beim nächsten Timer0 Überlauf landen wir hier Porta.0 = 0 'Ausgangspin wird wieder ausgeschaltet Incr Kanal 'und der nächsten Kanal bearbeitet End If End If If Kanal = 2 Then If Porta.1 = 0 Then Load Timer0 , Servoausgabe_2 Porta.1 = 1 Else Porta.1 = 0 Incr Kanal End If End If If Kanal = 3 Then If Porta.2 = 0 Then Load Timer0 , Servoausgabe_3 Porta.2 = 1 Else Porta.2 = 0 Incr Kanal End If End If If Kanal = 4 Then If Porta.3 = 0 Then Load Timer0 , Servoausgabe_4 Porta.3 = 1 Else Porta.3 = 0 Incr Kanal End If End If 'Pausenauffüllung If Kanal = 5 Then Timer0 = 0 '8-Bit Timer auf 0, Überlauf alle 2,048ms If Pausen_variable < 7 Then '2,048ms * 6 = 12,288ms Pausenfüllzeit Incr Pausen_variable Else Pausen_variable = 0 Kanal = 1 End If End If Return
MfG (Mit feinem Grübeln) Wir unterstützen dich bei deinen Projekten, aber wir entwickeln sie nicht für dich. (radbruch) "Irgendwas" geht "irgendwie" immer...(Rabenauge) Machs - und berichte.(oberallgeier) Man weißt wie, aber nie warum. Gut zu wissen, was man nicht weiß. Zuerst messen, danach fragen. Was heute geht, wurde gestern gebastelt. http://www.youtube.com/watch?v=qOAnVO3y2u8 Danke!
Hallo Robert,
wenn die RC Signale wie üblich nacheinander ankommen, dann kannst du das ganze doch mit dem Timer1 alleine hinkriegen. Erst die drei Kanäle einlesen, dann die beiden Potis auswerten und schließlich alles nacheinander an die Servos ausgeben.
3 x RC dauert max 6ms, Potis einlesen < 1ms und die Ausgabe an 4 Servos dauert maximal 8ms, also zusammen keine 15ms. Wenn dem so ist, wäre dies definitiv mein Weg, wie ich vorgehen würde. Und wenn du dann noch alle 3 RC Kanäle auf einen Eingang - vorzugsweise den ICP (PA.7) - legen kannst, ist das Einlesen auch eine saubere, weil in Hardware realisierte Lösung.
Alles würde dann synchronisiert durch den ersten RC Eingang. Genauer bekommst du die Intervalle sonst auf keinen Fall realisiert und du hättest wieder 1000 Schritte bei den Servos und nicht wie jetzt nur 125.
Solange du nicht synchron arbeitest, wird es dir immer wieder passieren, dass gerade eine ISR abgearbeitet wird, wenn ein RC Signal beginnt oder endet.
Und wenn du die Arbeit auf zwei Controller verteilst, müssen die eingelesenen Werte übertragen werden, was dann zu ähnlichen Problemen führt.
MfG (Mit feinem Grübeln) Wir unterstützen dich bei deinen Projekten, aber wir entwickeln sie nicht für dich. (radbruch) "Irgendwas" geht "irgendwie" immer...(Rabenauge) Machs - und berichte.(oberallgeier) Man weißt wie, aber nie warum. Gut zu wissen, was man nicht weiß. Zuerst messen, danach fragen. Was heute geht, wurde gestern gebastelt. http://www.youtube.com/watch?v=qOAnVO3y2u8 Danke!
Hallo zusammen,
mit "hintereinander Einlesen" meinte ich in meinem letzten Posting das Einlesen von 3 RC Signalen, und zwar unabhängig davon, WANN sie der Empfänger sendet (wir reden nicht von einem Summensignal, sondern von 3 getrennten Anschlüssen am Empfänger).
Es gibt Empänger, die ein Signal zu Ende senden, dann mit dem nächsten beginnen (am nächsten Ausgang des Empfängers) usw bis alle 4, 6 oder 8 Kanäle durch sind. Andere Empänger setzen die Kanäle nahezu zeitgleich auf 1 und wieder andere beginnen den nächsten Kanal nach einer vordefinierten Zeit. Manche käufliche V-Mischer hatten dann das Problem, dass sie nicht mehr funktionierten, wenn man die Reihenfolge der RC Kanäle veränderte.
Ich möchte meinen Code so gestalten, dass es egal ist, welchen Empfänger ich dran hänge. Wenn ich also vom Fall ausgehe, dass die einzelnen RC Signale nahezu gleichzeitig beginnen auf 1 (high) zu gehen, und ich sie dann HINTEREINANDER einlese, so dauert das Einlesen 3 x 20ms. Das kann ich nicht während der Pause der Servoausgabe einbauen, da diese ja spätestens nach 20ms wieder bedient werden möchten (müssen).
@ PICture
Das Problem liegt daran, das ich mehr als 1 Servosignal einlesen muss. Genauergesagt mindestens 2. Eines ist der Betriebsmode (also Baggerbetrieb oder Fahrbetrieb) und das zweite die eigentliche Steuereingabe. Deshalb versuche ich alles auf einen Chip zu bekommen.
Alternativ ginge es mit 3 Chips: Einer wertet nur den Betriebsmode aus und setzt einen Ausgang auf high oder low, die anderen steuern die Servos und werten nur den Ausgang des "Betriebsmode-Chips" aus.
Mal sehen, wie es weitergeht
mfg
Robert
mfg
Robert
Lesezeichen