Hallo werte Gemeinde,
ich beschäftige mich mit einer Schaltung, die das Summensignal eines
Fernsteuerempfängers einliest, die Servostellungen der einzelnen Kanäle
dekodiert, 4 davon nach gewissen Rechenalgorithmen verarbeitet und an
insgesamt 4 Servos wieder ausgibt.
Die Schaltung soll dazu dienen, mittels 4 Servos die Steuerknüppel in
einem Modellhubschraubercockpit sinnrichtig zu bewegen.
Da eine 3-Punkt-Anlenkung der Taumelscheibe angewand wird, überträgt der
Sender die Steuerfunktionen nicht einzeln sondern vermischt, daher die
Umrechnung im Controller. Um einem Vorschlag direkt entgegenzutreten: es
sind weder genügend freie Kanäle oder Empfängerausgänge vorhanden, um
die Steuerfunktionen unvermischt zu übertragen.
Die Software läuft prinzipiell schon, jedoch habe ich auf den
Servoausgängen regelmäßige Zuckungen, Jitter, Glitches.
Da ich seit über einer Woche vergeblich nach dem Fehler/den Fehlern
suche wende ich mich jetzt ans Forum.
Ich weiß nicht mehr, wo ich noch ansetzen kann und wäre schon froh um
ein paar Stichworte diesbezüglich.
Erfahrung mit Fernsteuerung und Oszilloskop sind vorhanden.
Vielen Dank
Du verwendest den internen RC-Oszillator? Falls dem so ist, das Problem
hatte ich auch schon, habe dann einen Quarz verwendet, damit war Ruhe.
Habe versucht, damals in diesem Forum dieser Frage nachzugehen, was
dabei allerdings raus kam, war nur totaler Müll von unseren so genannten
"Experten". Seitdem schaue ich nur noch sporadisch in diesem Forum
vorbei, getreu dem Motto. "Stick the Finger to the
mikrocontroller.net-Experts!" Traurig, aber wahr.
Erläuterung: im meinem Testaufbau ist lediglich ein Servo mit 500mA
Blockierstrom angeschlossen. Der Ripple auf den 5 Volt beträgt bei
blockiertem Servo 50 mV. Und auch bei 4 angeschlossenen Servos ändert
sich daran nichts wesentlich, da deren Ansteuerung sequenziell erfolgt.
Im Modell wird die Stromversorgung später für Servos und Controller
natürlich getrennt sein. Der Testaufbau laut Schaltplan dient lediglich
der Softwareentwicklung. Der interne Oszillator läuft nach Oszillogramm
stabil. Übrigens Bemerkungen, wie "das kannst du doch garnicht messen"
werde ich ignorieren.
Meine "üblichen Verdächtigen" sind in solchen Fällen zunächst mal
nicht-atomare 16-Bit-Zugriffe, also z.B. sowas in der Art:
(alter Eingangswert: 0x2FE)
- die Rechenroutine liest das LSB vom 16-bit Eingangswert,
- Interrupt-Routine empfängt und legt den neuen Eingangswert ab (z.B.
0x305),
- Rechenroutine holt das MSB vom Eingangswert, um die Berechnung des
Ausgabewertes fortzusetzen.
Ergebnis: die Rechenroutine verarbeitet als Eingangswert 0x3FE
Danke Thomas für deinen Hinweis. An atomare Zugriffe habe ich auch schon
gedacht, aber ich erkenne im Code diesbezüglich keine gefährliche
Stelle. Bei fehlendem Eingangssignal kommen die Ausgangssignale übrigens
fast stabil, jedenfalls so stabil, dass ich die Servos mittels kleiner
Hysterese ruhig bekomme.
Habe gerade auch mal den Code etwas überflogen. Eine "gefährliche"
Stelle könnte der Interrupt-Mechanismus zur Erzeugung/Verarbeitung des
timer0_h sein: Wenn die Flanken-ISR kurz vor Überlauf des Timer0
auftritt, könnte es evtl. sein, daß die ISR den falschen Wert für
timer0_h speichert?
Stabil ohne Eingangssignal spricht aber schon für ein Problem eben dort.
Wenn es statt DIP8 auch ein SO14 sein darf, dann besser ein
TINY24/44/84. Der hat einen 16bit-Timer1 mit Input-Capture. Damit kann
man exakte Zeitmessungen machen, auch wenn mal ein anderer Int
querschießt.
Dass dort ein Problem entstehen kann hatte ich nicht auf dem Schirm, ist
aber nachvollziehbar. Ich habe keine Idee wie ich in meiner Anwendung
den Timer0 "wasserdicht" auf 16Bit "aufgebohrt" bekomme. Vielleicht hat
da jemand eine Anregung. Ich werde zwischenzeitlich mal darüber
nachdenken, ob mir dort eine 8Bit-Auflösung genügt oder ich einen
anderen Controller nutze.
Danke bis hierhin.
Stefan K schrieb:> Dass dort ein Problem entstehen kann hatte ich nicht auf dem Schirm, ist> aber nachvollziehbar. Ich habe keine Idee wie ich in meiner Anwendung> den Timer0 "wasserdicht" auf 16Bit "aufgebohrt" bekomme. Vielleicht hat> da jemand eine Anregung.
Da es technisch überhaupt nur eine einzige vollständig zuverlässige
Möglichkeit zur Synchronisation mit ISRs gibt, ist eine Empfehlung hier
nicht schwer: Du benutzt einfach diese einzige Möglichkeit...
Sprich, bei allem, was nicht exklusiv läuft, sind die Zugriffe auf die
gemeinsam genutzten Resourcen in einem cli/sei Block zu verpacken.
Im konreten Fall ist es allerdings etwas komplizierter, weil ja auch
noch die Hardware direkt beteiligt ist und die kann man mit cli nicht
anhalten.
Das Designpattern zum Lesen muß also so aussehen:
1
getvirtcnt:
2
cli
3
;ab jetzt kann der Timer-Interupt nicht mehr reinpfuschen
4
;und du kämpfst nur noch mit der Hardware
5
in R16,Timer0_l ;erster Versuch
6
mov R17,Timer0_h
7
sbis TIFR0,TOV0 ;Check auf zwischenzeitlichen Timer-Überlauf
8
rjmp done ;war nich->OK
9
in R16,Timer0_l ;ansonsten nochmal HW-Teil lesen
10
inc R17 ;und virtuellen Teil eigenmächtig anpassen
11
done:
12
sei
13
ret ;nach dem ret holt die ISR das dann sofort für den
14
;tatsächlichen Timer0_h nach
Danach hast du in R17:R16 zuverlassig den korrekten Stand des Timers.
Voraussetzung dafür ist aber natürlich, daß an Timer0_l überhaupt
niemand rumpfuscht und an Timer0_h ausschließlich die Overflow-ISR ein
einfaches Increment vornimmt.
Dein Design hingegen ist extrem arg "von hinten durch die Brust in's
Knie". Ich hab's nicht näher analysiert, aber ich würde mal davon
ausgehen, daß dieses Design überhaupt nicht zuverlässig zum Laufen zu
bekommen ist. So wie fast immer, wenn schreibend an TCNT rumgepfuscht
wird...
Hallo,
das Thema hat mich neugierig gemacht. Ob es mit 8Bit-Timern und ohne
Quarz möglich ist, so etwas zu realisieren. Da ich eine Tiny85 habe
versuchte ich es einmal. Hier ist das Ergebnis.
Die Pinnbelegung ist wie bei Stefan K.
Meine getesteten Servos sind ziemlich ruhig.
Das Summensignal liefert ein Jeti/Duplex SAT
Programm ist nicht perfekt dokumentiert.
Ist halt nur ein Test.
Tiny muss mit 16Mhz laufen.
MFG Thomas
Ich melde mich nochmal:
@c-hater
mit einer Veränderung des Codes nach deiner Idee war die Sache schon
erheblich besser, aber noch nicht gut genug, da ist wohl wirklich
einiges von hinten herum durchs Knie programmiert.
@Thomas
ich habe mir den Code mal grob angesehen und kann daraus Anregungen für
die Zukunft nehmen, danke
@alle
ich bin auf den Mega8 umgeschwenkt (ja, ja, aber ich habe davon noch
viele hier und kenne mich ganz gut mit denen aus), benutze nur den 16
Bit-Timer und auch ausschließlich lesend. Da ich nun noch viele Pins
frei habe, wurde noch ein fünftes Servo für die Ansteuerung des Kopfes
der Pilotenpuppe etabliert.
Jetzt läuft der Code gut und so werde ich das dann später auch ins
Modell einbauen. Jetzt kann ich mir langsam überlegen, wie ich die
Gelenke und Anlenkgestänge herstelle und mit den 5 Servos unter den
Kabinenboden bekomme.
Danke euch.
Blöde Frage: Wie machen es eigentlich die anderen Modellbauer,
die nicht entwickeln und programmieren können?
Gibt es da ein extra Gerätchen in der Art, wie du es jetzt
nachbaust? Oder können andere Servos bereits das Summensignal
verarbeiten?
Peter P. schrieb:> Gibt es da ein extra Gerätchen in der Art, wie du es jetzt> nachbaust?
Die kommen mit einem simplen Zähler und Demultplexer aus, weil die die
Signale nicht verändern wollen.