Hallo zusammen, trotz fortgeschrittenem Alters und immer wieder Berührung mit Microcontrollern in den letzten 20 Jahren, bleibe ich irgendwie bekennender Laie... Für meine aktuelle Hobby-Aufgabe habe ich mir den Arduino Uno geschnappt. Die Aufgabe: 5 RC-Empfänger Kanäle auslesen, mit Sensorwerten verwursteln, einen einfachen P-Regler für eine Lageregelung, und die Ergebnisse wieder als 5 RC-Signale ausgeben. Bei der Online-Suche bin ich mit hunderten Triviallösungen für EINEN Servo und wenigen unbefriedigenden Ansätzen für mehrere Kanäle, sowie der Ahnung, daß der hübsch einfach zu programmierende Arduino dafür doch zu lahm wegen Overhead ist, hängengeblieben. Meine momentane Idee fürs Einlesen: Alle 5 Signale mit Dioden und Pulldown verodern. Und fünfmal PulseIn() am gleichen Pin aufrufen. Die Signale sind nämlich auch bei modernen 2,4GHz-Empfängern schön nacheinander und durch ca. 40us Pausen voneinander getrennt. Dazu Detailfrage: Reicht diese Pause, um PulseIn() abzuschließen, den Wert einer Variablen zu übergeben und das nächste PulseIn() zu starten, ohne daß man einen der 5 Werte "verschluckt" und PulseIn() erst den nächsten sieht? Für das Berechnen hätte ich dann ca. 10ms Zeit und würde wieder das erste PulseIn() aufrufen, das dann halt wartet, bis das nächste 5er Paket Impulse kommt. Damit würde sich die loop im Arduino automatisch auf die 20ms/50Hz Wiederholrate der RC-Impulse synchronisieren. So weit, so gut. Ihr könnt mir sicher erzählen, ob das Unsinn ist oder so geht. Dann kommt die AUSGABE. Da gibt es die wunderbare Servo.h, aber da weiß ich wieder überhaupt nicht, wie die intern funktioniert, wieviel Zeit und Interrupt-Ressourcen die verbraucht. Einfach fünfmal hinereinander servo.WriteMicroseconds() raushauen und klappt schon im Hintergrund, ohne das andere zu stören? Oder verbrauchen die fünf Aufrufe 5 mal ca. 1,5ms in der loop?
Tom H. schrieb: > Alle 5 Signale mit Dioden und Pulldown verodern. Dann musst du noch den "Anfang" finden, denn falls du da einen Puls verlierst oder zu viel siehst (EMV...) dann bist du neben der Rolle... > Oder verbrauchen die fünf Aufrufe 5 mal ca. 1,5ms in der loop? Geh einfach mal genau davon aus. Das ist Arduino. > aber da weiß ich wieder überhaupt nicht, wie die intern funktioniert Du hast als zentrales Problem die Eingabe und die Ausgabe und weißt nicht, ob oder wie das mit dem Arduino geht. Das ist eine schlechte Basis... Ich würde das Ding direkt auf dem uC ohne die Klassenbibliotheken des arduino aufsetzen. Dann bin ich selber schuld, wenn etwas nicht klappt, muss aber auch selber das Datenblatt lesen. Der Hardwareaufwand wäre dann 6 Eingangspins 1 Timer A für die Zeitmessung 6 Ausgangspins für das PWM Signal 1 Timer B mit Interrupt für die Pulsausgabe Die Programmstruktur etwa so: Es wird gewartet, ob irgendwo ein Servopuls aktiv wird (Polling). Dann wird zuerst ein Zeitstempel vom Timer A genommen und dann genau am "selben" Servo gleich mal ein Impuls ausgegeben. Die Dauer für diesen Puls wird in den Timer B eingetragen. Jetzt wird gewartet, bis entweder der Puls am Eingang weggeht (z.B. Polling), oder der Timer B abläuft (Timerinterrupt). Wenn der Puls weggeht wird ein erneuter Zeitstempel genommen und die Differenz berechnet --> Eingabe beendet. Wenn der Timer B abläuft werden alle Ausgänge inaktiv geschaltet. Mit ein paar (Pinchange-)Interrupts lässt sich das Ganze noch verfeinern. Das wars und das packt jeder schäbige AVR mit 1MHz...
Tom H. schrieb: > Die Aufgabe: 5 RC-Empfänger Kanäle auslesen, mit Sensorwerten > verwursteln, einen einfachen P-Regler für eine Lageregelung, und die > Ergebnisse wieder als 5 RC-Signale ausgeben. Auch wenn dir Lothar M. schon beantwortet hat: Was, womit und wie willst du genau "verwursteln" ?
Nackter AVR schön und gut, aber ich habe keine Entwicklungsumgebung, keinen Pragrammer und vor allem nicht die Eier in der Hose, mich darin einzuarbeiten. Den Arduino habe ich erstmals vor zwei Wochen angefaßt und seitdem in Summe drei Stunden damit verbracht. Für mich sehr angenehmes Spielzeug, genau meine Kragenweite. Eine einkanalige Lösung (Lageregelung eines kleinen Getriebemotors, der mit einem Modellbaufahrtregler gesteuert wird) steht auch schon. Das mit dem erstmaligem Erkennen des ersten Impulses stimmt, das ist ein Problem. Dirty Lösung: Was nach den fünf PulseIn() in der loop kommt, dauert immer ca. 10ms. Dann würden bei falscher Synchronisierung gewisse Impulse verschluckt, die Synchronisierung ändert sich, bis die lange Pause des Empfängers mit der langen Verarbeitungs/Wartezeit in der loop zusammenpasst. Andere Lösung: Doch die 5 Empfängerkanäle auf 5 Pins legen. Dann muß man aber auf die Reihenfolge der PulseIn()-Aufrufe achten, daß diese zeitlich eng aufeinanderfolgen können.
Klar kann ich die Anwendung noch näher beschreiben, ich wollte nur den Anfangspost nicht so ellenlang werden lassen. Es geht um ein Kinderfahrzeug (Trettraktor), das mit Elektromotor und Servolenkung versehen wird. Es soll reiner Fernsteuerbetrieb und Bedienung durch ein draufsitzendes Kind möglich sein, und sogar gemischt (durch Fernsteuerung bremsen oder gegenlenken, wenn das Kind Mist baut :-) ) Deshalb auch die hochtrabende "Servolenkung". Kanal 1: Gasgeben Eingänge, die verwurstet werden: Gaspedal-Poti und Empfängerimpuls. Ein Bewegen des Knüppels an der Fernsteuerung sperrt die Bedienung durch das Gaspedal, eine Zeitlang in Ruhe lassen läßt das Gaspedal wieder zu. Ausgabe: RC-Impuls für einen Modellbau-BLDC-Regler (Flugregler, eine Fahrtrichtung) Kanal 2: Schalten vor- rückwärts und 2. Gang vorwärts Eingänge: Analogeingang über Schalter auf GND-2,5V-5V gelegt, und Empfängerimpuls. Ob Fernsteuerung oder Schalter am Fahrzeug das Sagen haben, wird auch über den Kanal 1 getriggert. Ausgaben: Schaltkanal für Relais, die 2 Motorphasen vertauschen und RC-Impuls für ein Modellbauservo, das die Gänge schaltet. Kanal 3: Lenkung Eingänge: Empfängerimpuls, Poti für Ist-Stellung der Lenkung und Drehmomentsensor an der Lenkradwelle. Lageregelung der Lenkung. Verhalten Fernsteuerung/Kind ähnlich wie beim Gasgeben. Evtl. Lenkausschlag-Begrenzung bei höheren Geschwindigkeiten. Ausgabe: RC-Impuls für einen kleinen Modellbau-Fahrtregler für DC-Motoren, der den Getriebemotor der Lenkung steuert. Kanäle 4 und 5: Reserve für spätere Anbaugeräte. Eingänge: jeweils Empfängerimpuls und ein Poti eines lokalen Joysticks oder Schalters. Ausgabe: RC-Impuls für kleine Modellbau-Fahrtregler. Das Umschalten des Modus "Kind" oder "Fernsteuerung" kann eigentlich gemeinsam für alle Kanäle passieren.
ich glaube, ich würde mir als "Startpunkt" anschauen, wie die Receiver-Auswertung bei "MultiWii" (RC-Controller auf Arduino-Basis) gelöst wurde. Möglicherweise liesse sich gleich das ganze Ding auf die eigenen Zwecke umbiegen; das allerdings dürfte etwas mühsam sein, da eigentlich auf Multicopter ausgelegt...
Tom H. schrieb: > Es geht um ein Kinderfahrzeug (Trettraktor), das mit Elektromotor und > Servolenkung versehen wird. 5 PWM Ausgänge hast du ja beim UNO. (Kanäle 1-3, 2xRes. Kanäle) 6 ADC Eingänge auch. (1xGas, 1xSchalten, 1xLenk, 1xSensor, 2xRes) 2 Digitale Ausgänge auch. ( 2xRelais) 5 Digitale Eingänge auch (Empfängerimpuls Kanäle 1-3, 2xRes. Kanäle) Mit Interrupts wird es schlecht gehen, Polling oder Abfragen ist m.E. viel besser. Wenn es nur ein Empfänger ist, erstmal Kanaltrennung rausfinden. Das ist auch der Grund, warum Polling besser ist als Interrupts. Wenn Fernsteuerung stumm ist (Mittellage bei allen Kanälen), werden die Ausgänge entsprechend der Poti- oder Schalterstellungen am Auto per PWM angesteuert. Sobald sich bei der Fernsteuerung etwas ändert, werden die Fernsteuer eingänge 1:1 übertragen. Nachdem alle wieder in Mittellage sind, etwa 1s abwarten und dann dem Kind die Kontrolle zurückgeben. Bleiben nur noch die Begrenzungen (Lenkung, Geschwindigkeit), das muss aber in beiden Modis kontrolliert werden, kann als gemeinsame Routine bleiben. Und die evtl. 20ms Verzögerung ist nicht so schlimm, oder ?
Ich denke auch, mit der Ausstattung an Anschlüssen (Pins) ist das schon möglich. Aber das Timing... Dem Fahrzeug wird ein bestimmtes Sender-Empfänger-Paar zugeordnet und bleibt auch so. (Spektrum DX5e) Auf verschiedene Fernsteuersysteme muß sich das System gottseidank nicht einstellen. Wie muß ich das mit dem Polling verstehen? In der loop alles nacheinander abfragen, wenn sich an einem Eingangspin was getan hat, irgendwie den Timerwert (micros) merken und Variablen mit den Zeitdifferenzen belegen? Wird denn die loop schnell genug durchlaufen, daß sich da eine vernünftige Auflösung ergibt? Oder alle Impulse nacheinander auf Anfang und Ende abfragen, wie PulseIn(), nur zu Fuß? Was wäre der Vorteil? Mir scheint, ich habe ein generelles Timing-Problem, wenn ich das alles per "Pin Banging" erledigen will: Da sind 5 Impulse von 1-2ms Dauer nacheinander, wenn ich die ganz sauber nach meinem Programmierverständnis reinkriegen will, verbrauche ich damit max. 10ms. Dann will ich 5 ähnliche Impulse erzeugen, nach dem was das Tömchen kann und versteht dauert das auch max. 10ms. Bleibt also in der 20ms Wiederholrate keine Luft zum Rechnen und Synchronisieren. Will ich nun in die Trickkiste einsteigen, versuche ich die 5 zu erzeugenden Impulse gleichzeitig zu starten. Aber da bekomme ich doch Ungenauigkeiten, wenn alle etwa gleichzeitig zu Ende sein sollen und die Abfragen mit ihrer eigenen Abarbeitungszeit sich um den selben Zeitpunkt tummeln. Oder sehe ich das zu eng? Ist die Ausführungsgeschwindigkeit so hoch, daß da nichts jittert? Oder will ich Timer und Hardware-PWM nutzen. Entweder implizit, wenn ich die Funktionen PulseIn() und servo.Microseconds() nutze - wobei man irgendwie nirgends sichere Informationen findet, welche Ressourcen des ATMega328 dabei verwendet werden. Das muß man sich unglaublich mühsam zusammenklamüsern. Oder explizit, aber ich sehe da momentan keine Möglichkeit für mich mit meinen Kenntnissen, in der Arduino-Programmiersprache da ranzukommen.
Hier habe ich es für einen Roboter mit zwei Kanälen gemacht: https://github.com/ChrisMicro/freiBot/blob/master/Example_RadioControl/Example_RadioControl.ino Nicht optimal, funktioniert aber.
Im Allgemeinen ist es so, das die einzelnen PWM signale durch den Sender auch hintereinander gesendet und im Empfänger auseinander gewutstelt werden. Früher (in zeiten analoger Fernsteuerungen) wurde der erste Kanal dadurch idendifiziert, das die Pause vor diesem Signal länger war als die zwischen den andern. Dieses gesamtsignal konnte man an einigen Empfängern irgendwo abgreifen und so selbst auseinander wursteln und weiter verarbeiten. Wenn das nicht mehr der Fall ist, kann man ja das signal des Ersten Kanals mit einer Diode auf einen zweiten Eingang legen und dieses als Startsignal dafür verwenden das nun das Telegramm anfängt. Frank
Tom H. schrieb: > Wie muß ich das mit dem Polling verstehen? > In der loop alles nacheinander abfragen, wenn sich an einem Eingangspin > was getan hat, irgendwie den Timerwert (micros) merken und Variablen mit > den Zeitdifferenzen belegen? Polling deswegen, damit nicht bei Kanal1_ISR Kanal2 dazwischenfunkt. Eigentlich (soweit ich mich noch erinnern kann), ist der Abstand zwischen den Kanälen etwa 0,5 bis 1ms. Das ergibt im schlimmsten Fall 2ms + 1ms Pause * 5 etwa 15ms. Aber egal, selbst wenn es nicht so sein soll, ist die Pause vor dem ersten Kanal immer die längste, muss mindestens 5ms betragen. Bei Kanal_1 Timer1 auf Null setzen, danach einfach den Timerwert für den und die anderen Kanäle nacheinander ubernehmen, (Ende - Start) ergibt Impulsdauer. Wenn der entsprechende Kanal in Neutralposition ist, hast du mindestens 1ms um den Input vom Auto einzulesen, entsprechend vorzubereiten und als PWM auszugeben. Da der Input über ADC geschieht, ist es normalerweise kein Problem (max.67us). Bleiben mehr als 900us um den Wert zu prüfen, evtl. zu korigieren und impuls rauszuschicken. Wie ich gerade gesehen habe, steuert der Arduino die PWM-Ausgänge mit fixen 490Hz, die sind also unbrauchbar, die Ausgänge musst du manuell ein- und ausschalten. In Assembler oder sogar in normalem C kein Problem, aber mit Arduino overhead ist es mehr als fraglich...
Ich bin ab jetzt im Wochenende ohne PC (Ferienhaus) und kann nicht mehr so gut mitquatschen... Erstens, Impulstelegramm und Pause. Die Pulse sind nicht in einem festen Raster von 2ms, sondern hängen direkt hinteteinander. D.h. sind alle zufällig 1ms lang, verdichten sie sich auf ein Paket von 5ms + 4•40us Gesamtlänge. Da is nix mit "normalerweise hat man 500us Zeit zum Verarbeiten. In 40us muß die fallende Flanke des einen, die Dauer des einen über Zähler auslesen oder Differenzbildung erfasst sein, in Variable abgespeichert und die steigende Flanke drs nächsten erfasst sein. Um das Einlesen der Impulse und Synchronisieren mit der Pause würde ich mir alleine keine Sorgen machen.Aber wenn ich danach nochmal fünf so Pulse generieren muss und es dank interferierender Interrupts oder interferierender Timerbenutzung der Arduino-Funktionen nur zu Fuss geht und hintereinander, dann reicht es nicht in 20ms...
Tom schrieb: > Erstens, Impulstelegramm und Pause. Die Pulse sind nicht in einem festen > Raster von 2ms, sondern hängen direkt hinteteinander. D.h. sind alle > zufällig 1ms lang, verdichten sie sich auf ein Paket von 5ms + 4•40us Wie gesagt, ich kann mich nicht mehr genau erinnern, aber es ist ja trotzdem nicht so schlimm, vorausgesetzt man arbeitet nicht mit Arduino IDE. Bestenfalls hast du ein Paket mit 7660us Lange, schlimmstenfalls ein Paket mit 10160us Lange. Wobei es schlimmstenfalls gar nicht geben kann - schon beim ersten Impuls der ungleich 1.5ms ist, wird auf 1:1 Übertragung übergegangen. Und 40us sind im Assembler 640 Takte oder im Schnitt etwa 500 Befehle. Da kann man ADC einlesen, Timer einlesen, starten, stoppen, auf Null setzen, Werte prüfen, einschreiben, Impuls vorbereiten, raussenden...
:
Bearbeitet durch User
Tom H. schrieb: > wobei man irgendwie nirgends sichere Informationen findet, welche > Ressourcen des ATMega328 dabei verwendet werden. Geh davon aus, dass diese Funktionen während ihrer Ausführungszeit annähernd 100% der Ressourcen verwenden. Und lediglich von OS Interrupts unterbrochen werden. Tom schrieb: > dann reicht es nicht in 20ms... Mit dem von mir anfangs skizzierten Konzept reicht das locker. Und natürlich geht das auch mit Arduino. Nur muss man dort die Hardware eben auch selbst in die Hand nehmen. Aber das ist ja nicht schlimm, es istnur ein einziger Timer...
Gestern abend hatte ich wieder Zeit, ein bißchen Arduino zu spielen. Das Aufnehmen von 5 RC-Impulsen funktioniert so, wie ich es mir gedacht hatte. 1. Alle 5 Kanäle mit Dioden verodert und auf Pin 3 des Arduino gelegt. Leider läßt der Spektrum AR600 Empfänger nur 3v-Impulse raus, nach den Dioden hat es nicht mehr gereicht, den Arduino-Eingang sicher zu schalten. Also noch eine Inverterstufe mit BC548 und Pullup nach 5V, dann gings. 2. Nacheinander 5 mal mit PulseIn(3,LOW) verschiedenen Integer-Variablen die Kanalwerte zuweisen. Danach die Werte erstmal seriell ausgeben. 3. Die Synchronisierung klappt 100%ig. Das serielle Ausgeben dauert ca. 1,2ms (38400Baud, keine Ahnung, ob das bei der USB-Anbindung überhaupt relevant ist). Diese feste Zeit im Ablauf der Schleife reicht, um einen auf den (bei Falschsync vemeintlich) letzten Impuls folgenden weiteren Impuls nicht mitzubekommen. D.h. die Falschsync verändert sich so lange, bis es passt: Die serielle Ausgabe liegt zeitlich in der langen Pause zwischen den 5er-Paketen und stört da nicht. 4. Die gelesenen Werte scheinen mir stark zu zittern, das muß ich noch untersuchen. Z.B. indem ich mir die Abweichung von einem 1s-Mittel ausgeben lasse. 5. Ergebnisse nebenbei: 5a. Für die Timing-Untersuchungen habe ich per "Bit-Banging" (mir gefällt dieses Wort) kurze Peaks auf einem anderen Pin ausgegeben. Also nur zwei aufeinanderfolgende Zeilen mit WriteDigital(13,HIGH) und WriteDigital(13,LOW). So ein kurzer Puls dauert relativ zuverlässig 5us, nur manchmal verlängert er sich ca. aufs doppelte, da spukt dann wohl das "Arduino-Betriebsystem" rein. 5b. Die Wiederholzeit des Empfängers beträgt sogar 22ms statt 20ms, also noch ein Quentchen mehr Luft für die Impulsausgabe, die ich jetzt dann anpacken muß.
> nur manchmal verlängert er sich ca. aufs doppelte, da spukt dann wohl > das "Arduino-Betriebsystem" rein. Ja, die Arduino Laufzeitumgebung (runtime environment). Noch was Generelles: den einzelnen Servos/Drehzahlsteller ist es letztendlich egal ob sie die Steuerpulse gestaffelt nacheinander (wie vom RC-Empfänger) bekommen oder simultan. D.h. m.M.n. um Jitterfreiheit + Präzision bei der Ausgabe der Steuerpulse zu erreichen dürfte es wohl am besten sein etwas eigenes zu Schreiben; basiert auf des 328'er Timer und/oder PWM-Ausgabe UND dies darf ruhig in anderer Zeitlicher Reihenfolge als wie vom RC-Rx ausfallen. Nur die Wiederholrate würde ich nicht allzuviel langsamer als die üblichen 50Hz werden lassen. (wobei ein Servo bei Pulsausfall in seiner letzten Position bleibt, ein Drehzahlsteller jedoch den Motor ausschaltet)
Ok, korrekter Ausdruck für das, was ich meinte: Laufzeitumgebung und nicht "Betriebssystem". :-) Das mit der Reihenfolge und Staffelung ist mir klar. Nur zum Auseinanderklamüsern der Empfängersignale brauche ich die Reihenfolge. Der einzelne Servo sieht natürlich an seinem Anschluß nur seinen wiederholenden Impuls ohne weiteren zeitlichen Bezug zu einem Synchronsignal. Der braucht nur die Breite des Impulses als Information. Gestern hatte ich nicht so viel Zeit zum Basteln. Hab nur kurz zwei Dinge ausprobiert. 1. Von einem der 5 Kanäle zunächst einen Mittelwert gebildet und mir dann die Differenz zu diesem Mittelwert anzeigen lassen. Die vom Arduino mittels PulseIn() gemessene Pulsbreite schwankt ca. um +-3 us. (Zur Erinnerung: Der Wertebereich liegt bei ca. 1000us bis 2000us für die beiden Servo-Endstellungen). Also erträglich. Müßte mal messen, wie stabil der vom Empfänger gelieferte Puls eigentlich ist. 2. Mal spaßeshalber mit der Servo.h Bibliothek 5 Servosignale rausgelassen an den PWM-fähigen Pins 3, 5, 6, 9 und 10. Und zwischen den Aufrufen von writeMilliseconds() jeweils einen kurzen Puls an Pin13 geschrieben, den ich mit dem Oszi sehen kann. Ergebnis: Natürlich dauert das Aufrufen dieser writeMilliseconds() nur wenige us und scheint nur den Wert an die im Hintergrund laufende Routine zu übergeben. Also so doof, daß der Aufruf die gesamte Pulsbreite als Ausführungszeit bräuchte, ist die Routine auch wieder nicht. Insgesamt kam das kurze Paket an Debug-Impulsen nach wie vor im 22ms-Raster wie vom Empfänger vorgegeben, das Timing ist nicht aus dem Ruder gelaufen. Die Ausgabeimpulse für die Servos folgen dieser Synchronisierung nicht genau - ich vermute, sie halten sich eigenständig streng an das 20ms-Raster. Also alles in allem gar nicht so übel. Nun kann ich nochmal die Schwankung der gemessenen Impulsbreite ausgeben lassen, vielleicht wackelt das durch die gestiegene Timer- und Interruptbelastung jetzt stärker. Und mal sehen, wie ich die Stabilität der Servosignale mit dem Oszi untersuchen kann. Sollte eigentlich kein Problem sein mit einem Picoscope.
Du könntest Dein aktuelle Arduino Script posten, damit man mal auf den Code gucken kann. Das macht die ganze Sache einfacher.
Nun muß ich aber doch mal ein bißchen patzig werden. Aber da ich zu meinen konkreten Fragen bis jetzt keine Antworten erhalten habe und dazu übergehen mußte, mir alles schrittweise selbst zu erarbeiten und eher nur die Ergebnisse hier zu posten... Also, was soll das bringen, das Script hier zu posten? Habe ich ein Problem mit dem Programm, daß es nicht tut was es soll? Habe ich überhaupt derzeit eine Frage á là "wie programmiere ich das"? Nein. Was soll man an einem Script sehen, das so einfach und geradeaus ist, wie wenn man auf einen Lichtschalter drückt? Und funktioniert? Soll es besser funktionieren, wenn ich die Funktionsaufrufe kursiv oder groß schreibe? Oder geht es doch eher um die Feinheiten der Arduino Laufzeitumgebung, inwiefern die Jitter verursacht? Oder um beim Lichtschalter-Beispiel zu bleiben: Ich drücke auf den Schalter, das Licht geht an, aber manchmal flackert es etwas, weil irgendwo weiter hinten in der Leitung ein Wackler ist. Jetzt soll ich zeigen, wie ich auf den Lichtschalter drücke. Damit mir dann jemand sagt: Ah neee, du mußt das Bein heben und unterm Knie durchfassen und auf den Lichtschalter drücken, dann gehts ohne Flackern. Kapiert? Bringt nichts. Bisher gab es viele Antworten á là "du mußt den Lichtschalter selbst bauen, dann hat er keinen Wackler." Ok, verstehe ich. Kann sogar ungefähr ermessen, wieviel Aufwand und Kenntnis dazu nötig ist. Aber bis jetzt möchte ich es mit dem vorhandenen Lichtschalter lösen und es scheint, als würde es gehen. Denn der andere Aufwand ist mir zu viel.
Vom Schimpfen zurück zum Thema. Ich schreib einfach weiter von meinen Ergebnissen oder auch einfach nur "Erlebnissen" vielleicht kann ja irgendwann jemand was damit anfangen. Gestern Abend schnell ein "breakout board" zum Anschluß von 5 Servos gelötet. Und mit der zuletzt beschriebenen Programmversion betrieben. Ergebnis: 1. Die Servos zittern leicht. 2. Die Servos "pulsieren" gemeinsam mit einer Frequenz von ca. 2Hz. 3. Die agileren der 4 angeschlossenen Servos machen ab und zu (alle paar Sekunden) auch einen richtig heftigen Zuckerer. Für meine Zwecke könnte ich mit 1. und vielleicht sogar 2. leben, denn an den Servo-Ausgängen hängen ja fast nur Modellbau-Fahrtregler. Die könnten mit entsprechendem Totband um die Nullzone herum trotzdem ruhig bleiben, und Geschwindigkeitsschwankungen beim Aussteuern wird man wohl nicht so leicht merken. Aber 3. wird dann wohl doch der Sache den Garaus machen. Also zumindest so wie ich es bis jetzt angegangen bin. Zum Vergleich habe ich dann schnell ein Sketch erstellt, das ausschließlich die 5 Servos betreibt und keinerlei Einlesen von RC-Impulsen mittels PulseIn(). Zunächst nur einmal im setup einen Wert zugewiesen - Ergebnis: Servos stehen absolut still und zittern kein bißchen. Dann in der loop einen hin- und her-Sweep gefahren mit Increment von 1us alle 22ms. Ergebnis: Servos fahren ganz langsam und ruhig, kein Pulsieren, kein Zucken. Die Ausgabe der Servoimpulse geschieht übrigens offenbar hintereinander versetzt. Ein Verbreitern eines vorangehenden Impulses versetzt auch den Start des nachfolgenden auf einem anderen Pin. Meine laienhafte Analyse: PulseIn() und der Betrieb von Servos teilen sich halt doch die gleichen Ressourcen oder interferieren bei den Interrupts. Dadurch, daß der Zyklus vom RC-Empfänger aus 22ms dauert und die Servos aber mit einer Zykluszeit von 20ms angesteuert werden (das habe ich jetzt nachgemessen), entsteht eine Art Schwebung. Alle halbe Sekunde trifft die Phase des Einlesens blöd auf die Phase des Ausgebens und sie stören sich gegenseitig. Ich kann noch ein bißchen mehr herausfinden, was dabei gestört wird. Ich werde mir die gemessenen Pulszeiten ausgeben lassen und aufzeichnen - dann sehe ich, ob an diesen Störungsstellen zu große Werte für die Impulszeiten aufgzeichnet werden. In dem Fall könnte man evtl. filtern. Sollten die gelesenen Impulszeiten halbwegs sauber sein, muß es so sein, daß die Ausgabe gestört wird. Daran werde ich nicht drehen können. Evtl. müßte ich dann eine Servosignal-Ausgabe "zu Fuß" programmieren. Die Zeit, die in der 22ms-Schleife zur Verfügung steht, könnte reichen.
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.