PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Anspruchsvolle Servoansteuerung mit BASCOM



Brantiko
22.12.2007, 20:34
Hallo,
Hat Jemand eine Idee wie ich möglichst einfach ein programm schreiben kann wo meine Servos bestimmte positionenen mit bestimmten Geschwindigkeiten anfahren? Am besten mit Beschleunigung und abremsen damit es nicht so abrupt aussieht.

Mit Waitms kommt man ja nicht weit. Im Moment teste ich mit Timer1 rum, alles nicht so einfach.

Über Tips oder Beispielprogramme freut sich,

Alex

Ratber
22.12.2007, 23:02
Wie du bestimmte Positionen ansteuerst weißt du ja schon.
Jedenfalls entnehme ich das deinem Post.

Jetzt mußt du einfach nur die Positionsausgaben "timen" und darüber deine Rampen ausgeben.

Im Grunde nur einige verschachtelte Schleifen und anfangs die Berechnung der Schrittweiten,Richtung innerhalb der vorgegebenen Eckpositionen plus der Rampenform selber (Zeit,Linear,logarytmisch oder wie auch immer gewünscht).

Fang einfach mit einer simplen Folge an bei der du Start/Stoppositione,Richtung,Zahl der Zwischenschritte und Zeitintervalle zwischen den Schritten bzw. die Gesamtlaufzeit für den Vorgang angibst.

So kompliziert ist das wirklich nicht.

Später kannst du ja noch einige Features und Sicherungen (zb. Maximale Geschwindigkeit,Endpositionen des Servos usw.) einpflegen.

Brantiko
23.12.2007, 13:39
Hallo,
Vielen Dank, aber was meinst du mit Rampe?

Gruss

Alex

Ratber
23.12.2007, 14:02
Einem stinknormalen Servo kannst du nur Punkte also Positionen mitteilen.
Anfahren tut er diese mit seiner bauartbedingten Maximalgeschwindigkeit auf die du keinen Einfluss hast.

Wenn du also die Drehgeschwindigkeit ändern willst dann geht das nur als "Emulation" indem du ihm den Weg als Punkte gibst die in zeitlichen abständen geliefert werden.

Probiers doch einfach mal mit ner einfachen Schleife.

Beispiel (Pseudocode)

Rem Der Servo kann zb. zwischen den Positionen 30 und 210 gestellt
Rem werden.
Rem Ausserhalb ändert sich nix.
Rem Die Auflösung beträgt 5 (digitalservos sind da besser aber teurer
Rem Einfache Strecke

Y=100
For x= 50 to 200 step 5
Servo x
Waitms y
Next x

Beispiel Ende

In diesem Beispiel würde er 30 Punkte anfahren und dafür 3 Sekunden brauchen.
Das sieht schon geschmeidig aus.

Jetzt,zur verdeutlichung,reduzieren wir die Schrittzahl um den Faktor 10 und die Wartezeit wird auf 1 Sekunde (Waitms 1000) erweitert.
Das ist jetzt natürlich übertrieben aber du sollst ja sehen was wirklich passiert
Damit macht der Servo 3 Schritte und braucht am ende wieder 3 Sekunden für den Weg.
Jetzt aber kann man sehen das er sich in wirklichkeit immer mit der gleichen Geschwindigkeit bewegt.

Probiers einfach und experimentier mit den Werten.

Zu "Rampe"

Wenn du die Wartezeiten ebenfalls mit der Zeit änderst dann ändert sich auch die scheinbare Geschwindigkeit.
Das würdest du sicher sofort als "Rampe" anerkennen.
aber wenn die Zeit sich nicht ändert ist das auch eine Rampe.
Sier hat eben nur eine unendliche Steigung (Positiv wie Negativ)


Wie gesagt.
einfach mal aufbauen und probieren.
Is ganz einfach.

Brantiko
23.12.2007, 14:58
Hallo,
Dass ich die Geschwindigkeit nur durch das Schrittweise vergrößern der PWM Impulse hinbekomme weiss ich auch. Am einfachsten ist es die Servo Variable hochzuzählen (Incr I) und dann eine gewisse Zeit zu warten. Dann erhöht sich die Impulsbreite immer um eine ms in einer bestimmten Zeit (Zb 200ms)

Aber was ich benötige ist ein gespeicherter Bewegungsablauf zweier Servos.
Also keine bestimmten Bewegungsabläufe auf "Knopfdruck".
Einmal gestartet sollen mir zwei Servos ein Weissbier einschenken ;-)

Beim Baden kam mir folgender Gedanke:
Eine Word Variable zählt in einem Timer Abzweig eine Zeit Variable bis 1024 hoch. In einer Tabelle kann ich nun anlegen welche Servo Positionen zu welcher Zeit angefahren werden sollen ( Bei I= 5 Servo(1) = 150 Bei I= 6 Servo(1)= 155 usw)

Ist zwar unelegant und viel Tiparbeit, aber es sollte klappen.
Ich kann dann nämlich ganz Analog eine Kurve auf Milimeterpapier zeichnen und die Werte dort ablesen und in die Tabelle übertragen.

Gruss

Alex

PicNick
23.12.2007, 15:13
.. unelegant ..
Isses absolut nicht. Du brauchst eine "Timeline" wie bei Videoschneiden oder so.
Zu jedem Zeitpunkt gibt's einen Punkt, wo jedes Servo sein soll.
Das, was Ratber meint, ist, wie du bei jedem Servo von dem einen Punkt zu nächsten kommst.
Da kannst du eben einfach die "Timeline" mit feinerer Auslösung machen (-->Tiparbeit) oder eben eine Art automatik, wo die "Zwischenpunkte" vom µC errechnet werden.

Brantiko
23.12.2007, 15:19
Hallo,
Ich könnte ja sogar eine zusammengesetzte Funktion berechnenen lassen, aber dann brauch ich auch wiederum eine Tabelle aus denen die einzelnen Intervalle ihre Funktionen bekommen. Da geht die Zeit zum Tippen dann beim Rechnen drauf. Ich denke ich mache is mit der Timeline. Ist eine Case-Tabelle für sowas geeignet?

Gruss

Alex

Ratber
23.12.2007, 16:15
Aber was ich benötige ist ein gespeicherter Bewegungsablauf zweier Servos.
Also keine bestimmten Bewegungsabläufe auf "Knopfdruck".
Einmal gestartet sollen mir zwei Servos ein Weissbier einschenken ;-)

Beim Baden kam mir folgender Gedanke:
Eine Word Variable zählt in einem Timer Abzweig eine Zeit Variable bis 1024 hoch. In einer Tabelle kann ich nun anlegen welche Servo Positionen zu welcher Zeit angefahren werden sollen ( Bei I= 5 Servo(1) = 150 Bei I= 6 Servo(1)= 155 usw)

Ist zwar unelegant und viel Tiparbeit, aber es sollte klappen.
Ich kann dann nämlich ganz Analog eine Kurve auf Milimeterpapier zeichnen und die Werte dort ablesen und in die Tabelle übertragen.

Gruss

Alex

Ich verstehe nicht warum du dir soviel Arbeit machen willst wenn es doch soviel einfacher geht.

Die subroutine bekommt die Parameter (Welcher Servo Von Wo nach Wo wie schnell mit welcher auflösung) übergeben und arbeitet diese einfach ab.
die Routine wäre dann universell.

Die Datensätze der einzelnen Bewegungen selber legst du dann letztendlich ins interne (oder Extern) EEprom oder nen externes Flash ab.
so bist du superfelxibel und kannst die Daten sogar einfach transportieren.

Wenn mehrere Servos ihre aktionen gleichzeitig ausführen sollen schreibst du die subroutinen so um das pro durchlauf nur ein Schritt abgearbeitet wird und du klapperst alle subroutinen nacheinander ab.

Für mich recht einfach oder schwebe ich schon zu hoch ?
Eigentlich hatte ich das eingangs da oben schon ganz bewust einfach gehalten.


Wie gesagt,probier einfach mal etwas herum dann bekommst du ein Gefühl dafür.

Brantiko
23.12.2007, 17:00
Hallo,
Ich verstehe. Du meinst nur eine Tabelle nach Schema "Bei Sekunde 10 gehe mit der Geschwindigkeit X nach Position B"
Dann müsste ich irgendwo im Programmcode die eine Funktion schreiben die die Geschwindigkeit bestimmt: Habe jetzt mal folgendes getestet:



Do
Servo(1) = A
R1 = 0.01 * I
R2 = Sin(r1)
R3 = R2 * 60
R4 = R3 + 100
A = R4
Loop


Eine Sinuswelle die von 40 bis nach 160 oszilliert und somit den Servo von Links nach rechts fahren lässt, natürlich mit beschl und abbremsen.
I wird im 100Hz Takt um einen erhöht.
Leider ruckelt das sehr stark. Ist der uC überfordert?
hab gehört dass die Bascom Servo funktion nicht so gut funktioniert wenn man noch andere Sachen im Programm hat.

Edit: Bringt es evtl was wenn ich mit einem ext. Quarz den uC mti ner höheren Taktung betreibe? Im moment sind es 8Mhz
Gruss

Alex

Ratber
23.12.2007, 17:16
Hallo,
Ich verstehe. Du meinst nur eine Tabelle nach Schema "Bei Sekunde 10 gehe mit der Geschwindigkeit X nach Position B"
Dann müsste ich irgendwo im Programmcode die eine Funktion schreiben die die Geschwindigkeit bestimtm:


Ja,so in etwa.
Du kannst es ja anopassen wie du es magst.