PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : "Config Servo" in Bascom - Warum so krumme Werte??



m@rkus33
16.02.2009, 19:58
Hallo zusammen,

nach langer Zeit beschäftige ich mich mal wieder mit meinen Megas. So nun spiele ich gerade ein wenig mit dem Befehl "Config Servo".

Soweit ist alles klar, nur eins ist mir nicht ganz verständlich. Warum brauche ich so "krumme" Servowerte? Wenn ich das richtig verstanden habe bastelt Bascom anhand der $crystal=XX, dem Preload = 10 die Timereinstellung so, das der Servowert eigentlich doch so um 100 (=1ms), 150 und 200 liegen sollte.

Ich habe schon mit versch. Takten und $crystal Werten gespielt. Die Werte sind immer "krumm".

Ich benutze:

1. Mega8
2. Internen Oszilator mit 8Mhz
3. Ein Graupner Digi-Servo DS361
4. Das ganze auf nem STK500
5. Terminalprogramm auf PC

Mit den paar Codezeilen hier, (nur zum Spielen) gebe ich übers Terminal die Werte fürs Servo vor.

Framesize; HW-Stack usw. habe ich mal weggelassen.



$regfile = "m8def.dat"
$crystal = 8000000
$baud = 9600

Dim Servowert As Byte
Dim Links As Byte
Dim Mitte As Byte
Dim Rechts As Byte

Dim Rc_ch1_out As Word
Dim Rc_ch1_in As Word

Config Pinb.0 = Output 'LED
Config Pinc.0 = Input 'Servo in
Config Pinc.2 = Output 'Servo out

Config Servos = 1 , Servo1 = Portc.2 , Reload = 10

Enable Interrupts

Portb.0 = 0

Links = 132
Mitte = 87
Rechts = 43

'+++++++++Werte bei 3.6864 Mhz und Preload =10++++++++++++++++
'Links = 97
'Mitte = 66
'Rechts = 36
'+++++++++++++++++++++++++++++++++++++++++++++++++ ++++++++++++

Servo(1) = Mitte

Do

Pulsein Rc_ch1_in , Pinc , 0 , 0
Print "R/C- Impuls Input:" ; Rc_ch1_in

Input "Bitte Servoinput (132- 43 bei 8Mhz Prozessortakt) : " , Servowert
Servo(1) = Servowert

Loop


End



Die Werte sind immer so entstanden: Ich habe mit den Endausschlagswerten so lange gespielt, bis das Digi-Servo ausgestiegen ist. Die Werte sind also die Maximalwerte die das Servo noch verarbeitet.

Gibt es einen Trick um "saubere" Werte zu bekommen die so in etwa an die 100, 150, 200 kommen? Die Auflösung ist zudem jetzt doch recht bescheiden. Kann man die mit dem Preloadwert (auf 5) noch erhöhen? Ich möchte in Zukunft ein wenig mit Servomanipulation arbeiten. Also die Signale vom Empfänger verändern und je nach dem manipuliert an die Servos weiterleiten.


Merci schon mal

Gruß
Markus

PicNick
17.02.2009, 09:13
Bei 10 µS und 8 MHZ vergehen bei der Bascom-Servo-Methode
https://www.roboternetz.de/wissen/index.php/Bascom_Inside-Code#SERVO
gerade mal 800 Cycles von einem Intgerrupt zum nächsten. Das ist eine knappe Sache, wenn noch was anderes zu tun ist.

m@rkus33
17.02.2009, 09:49
Hi PickNick,

danke für die Antwort. Dann ist es, wenn man etwas komplexere Aufgaben zu erledigen hat, nicht sinnvoll die Bascom Servo Methode oder eine Messmethode mit Interrupts zu verwenden?

Habe auch nachgedacht das über den mitlaufenden Timer zu machen der bei Flankenwechsel abgefragt wird. Das ganze dann über einen Atmega88 mit Pin Change. Glaube das ist sicher der bessere Weg, oder?

Kein Interrupt belegt, der Timer ist auch noch für andere Sachen zu gebrauchen und die Messungen werden zuverlässiger.

PicNick
17.02.2009, 10:18
Hat der µC ausser der Impulsbearbeitung noch was (zeitkritisches) zu tun ?
Wenn nicht, ist die von dir angedachte Methode sicher am besten, denk' ich.

m@rkus33
17.02.2009, 11:52
Na ja,

er soll im Endausbau eine kleine autom. Fluglagensteuerung übernehmen.
Er muss bis zu 4 R/C- Kanäle einlesen,
Sensoren abfragen, (z.B. Geschwindigkeit, Höhe usw. )
und nach Bedarf die vier R/C Kanäle an- bzw übersteuern. Also entweder die Impulse "durchschleifen"oder eigene saubere R/C Impulse ausgeben.

Wird noch ne Menge Arbeit, ich möchte mich im Vorfeld nur auf ein sinnvolles Grundgerüst einlassen und mir nicht selbe ein Bein stellen.

PicNick
17.02.2009, 12:13
uiuiui. Naja, der Weg ist das Ziel :-)

m@rkus33
17.02.2009, 12:30
so ist es! ;) Erst mal die vielen kleinen Teile einzeln ausprobieren und dann schön langsam Stück für Stück zusammenführen.... so habe ich es mir zumindest gedacht.

Was denkst Du, ist die Vorgehensweise mit der R/C- Signalausleserei sinnvoll mit der Geschichte ständig laufender Timer und PinChange? Ich denke schon.

Habe bisher mit der Servosignal - Geschichte nix gemacht. Sonst schon (fast) alles....

PicNick
17.02.2009, 13:33
Ein ständig laufender Time/Counter ist sicher gut, mach ich auch immer. Denn für fast alles braucht man eine Time-Line.
Und bei PinChange brauchst du nur die Zeit übernehmen.

Sauerbruch
17.02.2009, 13:46
Hi M@rkus,

hast Du schon mal PWM in Betracht gezogen? Ich weiß, "machs-doch-ganz-anders" - Lösungen sind immer doof, aber Hardware-PWM besticht durch zwei Vorteile: Es ist sehr fein abstufbar, und es kostet keine Rechenlesitung. Mit einem Mega88 könntest Du 4 Kanäle nutzen und hättest trotzdem noch einen Timer frei, um die Eingangssignal-Längen zu messen.

Ich habe vor einem Jahr mal für einen Modellflieger-Kollegen etwas gelötet und programmiert, das qualitativ ähnlich war wie Dein Problem (wenn auch mit weniger Kanälen - dafür läuft´s auch mit einem Tiny25):

Mit einem senderseitigen Kippschalter (ein-aus) sollte das Hauptfahrwerk einer Scale-ME109 ein- und ausgefahren werden. Im Modell war es dafür notwendig, dass erstens ein Servo das Fahrwerk ein- bzw. ausfährt, wobei nach einem bestimmten Teilweg eine kurze Pause gemacht werden musste (für die Fahrwerksklappen). Danach musste zweitens ein weiteres Servo die Ver- bzw. Entriegelung übernehmen - nicht zu früh, aber auch nicht zu spät...

Und was soll ich sagen - sie fliegt noch heute :-)





Habe bisher mit der Servosignal - Geschichte nix gemacht. Sonst schon (fast) alles....

Und PWM??

Gruß,

Daniel

m@rkus33
17.02.2009, 17:07
Hallo Daniel,

PWM - Ja daran habe ich auch gedacht und nein ich habe damit noch nicht wirklich viel damit gemacht.

Das Ganze wird eine automatisierte, Speedabhängige Klappensteuerung mit Throttle- und Höhenruder- Kompensierung. Uff.... da hab ich mir was angetan.... ;)

Das Flußdiagramm steht, jetzt muss ich mir schön langsam Gedanken machen wie ich die R/C Signale auslese und zum Schluß wieder ausgebe.

Das ganze muss dann noch einen "Notaus" haben, per Schalter am Sender komplett wegschaltbar. Auch Hardwaremäßig, alle R/C Signale 1 zu 1 an die Servos.

Wir ein größeres und längeres Projekt.........

Sauerbruch
19.02.2009, 16:36
Wir ein größeres und längeres Projekt.........

...das scheint mir allerdings auch so :-)
Wenn sich so etwas überhaupt mit einem einzigen Controller lösen lässt.

Vielleicht hilft Dir PWM ja ein wenig weiter - ich wünsch´ jedenfalls gutes Gelingen!

Daniel

m@rkus33
21.02.2009, 22:17
... also mit PWM die Ansteuerung zu realisieren ist ja recht einfach. Aber....

auch mit dieser Auflösung bin ich nicht zufrieden. Warum? Na beim 10bit PWM habe ich bei 1.0ms einen Comparewert von 966, bei 1,5ms - 935 und bei 2,0ms Compare von 908. Somit über den gesamten Servoweg nur 58 Schritte Auflösung.

Gibt es eine Möglichkeit die Auflösung weiter zu erhöhen? Steh jetzt echt auf dem Schlauch....
:-k

Dirk
21.02.2009, 22:39
mit PWM die Ansteuerung zu realisieren ist ja recht einfach. Aber.... auch mit dieser Auflösung bin ich nicht zufrieden.
Mit Hardware-PWM kann man (je nach Taktfrequenz) auch eine Auflösung von 1 us erreichen (also 1000 Schritte über den ganzen Servoweg).
Damit kann man z.B. einen sehr genauen Servotester bauen.

Gruß Dirk

Willa
21.02.2009, 22:44
Hi! Ich habe kürzlich einen Tricopter gebaut. Hier ist das Auslesen des RC Empfängers sowie das erzeugen von RC-Signalen sehr zeitkritisch. Außerdem muss die Auflösung hoch sein. Das ist nicht unbedingt trivial, da man meistens ja nur einen 8bit (=256 Schritte) und einen 16bit (=65536 Schritte) Timer hat. 256 Schritte für das Servosignal oder das Empfängersignal waren mir z.B. zu wenig.
Zum Auslesen des Empfängers habe ich kürzlich einen Artikel im Wiki geschrieben. Zum erstellen der RC-Signale gibt es sehr viele unterschiedliche Möglichkeiten, wenn du willst kann ich dir meine Lösung schicken (schreib mir dafür am besten per PN deine email adresse)

Sauerbruch
22.02.2009, 09:48
@ Markus:

Eine Möglichkeit, mehr aus dem 16bit-Timer herauzuholen besteht darin, das Impuls-Pausen-Verhältnis des Signals zugunsten des Impulses zu verändern (z.B. durch einen halbierten Prescaler und entsprechend abgesenkte Compare-Werte). Dadurch fallen mehr Takte aud die High-Phase.

In allen Datenblättern steht außerdem "True 16bit design (i.e. allows 16bit PWM)".
Ich vermute daher, dass diese Begrenzung auf 10 bit ein Bascom-Problem ist. Leider hat mir bisher die Zeit gefehlt einmal auszuprobieren, ob man auf Registerebene nicht doch eine 16bit-Auflösung hingekommen kann. Vielleicht wäre das genau das richtge für diesen verregneten Sonntag heute :-)

Sauerbruch
22.02.2009, 12:24
...und es geht doch:


$regfile = "m8def.dat"
$crystal = 4000000

DDRB.1 = 1

TCCR1A = &B10000000
TCCR1B = &B00010001

ICR1L = &B11111111
ICR1H = &B11111111


Dim Phase As Word

Do

For Phase = 2000 To 4000
Waitms 2
OCR1AH = High(phase)
OCR1AL = Low(phase)
Next Phase

Loop

Dieser kleine Code erzeugt ein PWM-Signal mit ca. 30Hz, wobei die High-Zeit in 2000 (!) Stufen zwischen 1 und 2 ms variiert wird (pro Durchlauf etwa 4 Sekunden). Also echtes 16bit-PWM...

m@rkus33
23.02.2009, 17:13
Jungs Ihr seid Spitze!!! :D

@William: Hast ne PM

@Daniel: Wow werde ich heute abend gleich mal ausprobieren! Vielen Dank auch Dir für den Tipp (und gleich den Praxisversuch!!!))


1000end Dank.

Markus

m@rkus33
23.02.2009, 20:17
Hallo Daniel,

ich habe jetzt mal Deinen Code 1 zu 1 kopiert. Ich bekomme leider kein PWM Signal an Pin B.1 (OC1A) gemessen. Er bleibt nur auf "high". ??

Sauerbruch
23.02.2009, 20:50
Hi Markus,

sorry - da ist mit trotz "Copy - Paste" ein kleiner Dreher mit großer Folge unterlaufen:
Die ICR1-Register müssen in umgekehrter Reihenfolge beschrieben werden, also erst das ICR1H und dann ICR1L.



ICR1H = &B11111111
ICR1L = &B11111111


Das klingt jetzt zwar fast esoterisch :-) (zumal sie beide 0xFF enthalten), ist aber so. Wenn man zuerst das "Low"-Register beschreibt, läuft´s schief...

Gruß,

Daniel

m@rkus33
23.02.2009, 22:26
Hi Daniel,

...ahhh, das muss man wissen. Das funktioniert echt gut! Ok eine 2000er Auflösung muss net sein aber ich habe hier schon einiges rumgespielt und das sieht sehr sehr gut aus. Das Servo ist so butterweich oder schnell und immer super präziese zu steuern. Muss mal mit nem größeren Code rundrum und mehr Kanälen spielen...:)

Merci

Gruß
Markus

Willa
24.02.2009, 16:54
Vielleicht kann ich an dieser Stelle mal eben alle Interessierten aufs Wiki verweisen, denn ich habe einen Beitrag über das Ansteuern von Servos geschrieben:
https://www.roboternetz.de/wissen/index.php/Servoansteuerung
Sauerbruchs Code mag wunderbar funktionieren, für einige Anwendungen kommt er aber wegen dem Befehl "Waitms" nicht in Frage.

Sauerbruch
24.02.2009, 19:49
Klar sind Pausen von 2ms für Servoansteuerungen nicht akzeptabel. Zum Glück ist ja aber sofort zu erkennen, dass waitms2 in meinem Beispielcode nur dazu dient, die 2000 Abstufungen zwischen 1ms und 2ms Impulsdauer über 4 Sekunden durchlaufen zu lassen.

Und ein schöner Artikel im Wiki, btw...

Gruß et al.,

Daniel

Willa
24.02.2009, 19:56
Lol, ich habe 20ms gelesen und nicht gesehen dass das nur zur soll-signal generierung dient.... Bei 20ms denkt man ja automatisch an die Servorefreshrate....
Aber deine Ansteuerung läuft nur mit 30Hz? Geht das auch schneller...? Ich habe bei meinem Code einen ziemlichen Unterschied z.B. zwischen 80Hz und 20Hz Ansteuerungsrate festgestellt (Haltekraft)... Wieviele Servos kannst du mit dieser Methode ansteuern? Kannst ja den Wiki-Artikel noch erweitern, wäre ja schön wenn da mehrere Methoden vorgestellt werden. Dein Ansatz scheint ja nur sehr wenig Code zu benötigen.

m@rkus33
25.02.2009, 14:22
...und er erzeugt ein perfektes Signal am Oskar.... Die 30Hz stellten noch kein Problem dar. Mir wären 50 zwar auch lieber, aber man kann nicht alles haben... ;) Mit 8Mhz müssten doch dann 60 Hz rauskommen wenn ich mich jetzt Gedanklich nicht komplett vertan habe, oder?

Es gehen allerdings nur Servos am Compare1a, 1b und 2 (beim Mega8) da die durch die Timer-Hardware PWM gesteuert werden. Aber wie William schon bemerkt hat, ganz wenig Code ist nötig und schön einfach zu handeln.

Gruß
Markus

Sauerbruch
25.02.2009, 18:00
@ Markus:

Exakt - bei 8MHz dürften es so etwa 60 Hz sein - und die Abstufung verfeinert sich auf 4000. Der Nachteil bleibt natürlich, dass in der Tat nur 2 1/2 Servos angesteuert werden können. Das halbe bezieht sich auf den Timer2, der zwar PWM-fähig ist, aber halt nur 8 Bit hat. Vielleicht reicht das ja für was "grobes"...

@ Willa:

Das war ja nur ein wenig über PWM - und darüber ist ja schon viel & gut im RN-Wiki geschrieben worden. Und so schöne Dinge wie softwareseitiges "durchschleifen" der Eingangsimpulse - das kann mein Codeschnipsel natürlich nicht. Sollte auch nur eine Art Beleg dafür sein, dass man die vollen 16 Bit des Timer1 für PWM ausnutzen kann...

Bleibt bedeutsam,

Daniel

m@rkus33
26.02.2009, 15:42
@Daniel

ohne Deinen Hinweis und Versuch wäre ich gar nicht auf die Idee gekommen, das man auch mit Bascom den Timer für PWM auf die vollen 16Bit bekommt. Wer weis für was wir/ich das noch gebrauchen werde.

Eines ist mir aber schon klar geworden, öfters doch mal ins Datenblatt schauen und die Register evtl. gleich direkt per Hand setzten..... ;)

Also nochmals vielen Dank für den Hinweis!

@Willa

Ich habe gestern mal mit Deiner Variante gespielt. Auf Mega8 und 3,686400 Mhz umgeschrieben. Funktioniert auch sehr gut! Schön hier ist tatsächlich die "freie" Anzahl der Servos und der Anpassung der Periodenzeit. Habe es auf ca. 55 (1ms Impulslänge)Hz bzw. 49,5 Hz (2ms Impulslänge) laufen. Damit funktioniert fast alles im R/C-Bereich. Die Aktuelle Servoauflösung liegt hier bei 3686. Das reicht, glaube ich ;)

Ich werde Deine Lösung verwenden und weiter ausbauen.

Vielen Dank dafür und Grüße

Markus