PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Schrittmotor mit Rampen ansteuern ?



Roberto
29.09.2006, 07:49
Hallo Leute (ist schon länger her..:-b )

Ich möchte quasi ein Ansteuerung für Schrittmotoren mit dem Mega 8 machen.
Pro Motor brauche ich da Takt und ein Richtungs- Signal.

Mir geht es jetzt um die Taktausgabe.

Das Taktsignal müsste jetzt eine start Rampe (frequenzanstieg), normale Frequenz und dann eine fallende Rampe (Frequenzabfall) haben.

Für die Takterzeugung dachte ich , das ich sie in einer Interruptschleife mache. (damit sie taktmässig immer korrekt ist)

Aber wie kann ich da die Rampen einbringen ?

Hat jemand einen Lösungsansatz wie man das in etwa machen könnte ?

Noch dazu müsste ich min. drei Taktsignale (Drei Motoren) mit unterschiedlichen Frequenz auch noch ausgeben können... :-k
(= die Rampen liegen zeitlich nicht immer gleich an..)

Zuerst dachte ich, für die Rampen vielleicht die Aufrufrutiene in der Zeit verändern... (kann man das überhaupt mit einer Variablen?)
Aber das würde höchstens für einen Motor reichen und ich brauche min. 3

Andere Idee: ein übergeordnetes Taktsignal mit Interrupt machen und für die Rampen dann ein vielfaches davon verwenden.... :-k
(auch nicht so schön)

Hat jemand dazu vielleicht einen Lösungsansatz oder Idee?

Wäre um jeden Tipp dankbar \:D/

l.G. Roberto

PicNick
29.09.2006, 07:56
Andere Idee: ein übergeordnetes Taktsignal mit Interrupt machen und für die Rampen dann ein vielfaches davon verwenden.... (auch nicht so schön)
Wieso nicht schön ? Bei jedem Timer passiert genau das Gleiche (Clock/teiler)

Roberto
29.09.2006, 08:08
Hallo Robert

Weis nicht so genau... ;-)
* Vielleicht wird die Rampe so zu grob.
* sollte vielleicht mal eine Sinusrampe werden..
* Habe noch keine Idee, wie das konkret funktionieren könnte ;-)

l.G.

PicNick
29.09.2006, 08:30
..Sinusrampe werden

Wenn, dann doch wohl eine Kurve für gleichbleibende/einstellbare Beschleunigung ?

Roberto
29.09.2006, 10:15
Hi

Wenn, dann doch wohl eine Kurve für gleichbleibende/einstellbare Beschleunigung ?
..mmmhh.. Kurve.. Wie meinst Du das jetzt
Meine z.B. ein Rampe die Flach anfängt und dann in der Mitte Steil und oben wieder flach aufhört.. Aber derzeit egal ;-)

Derzeitige Überlegung für die Start Rampe:

Interrupt mit hoher Frequenz = maximale Schrittfrequenz.

Für die Startrampe, zwei Variablen im Interrupt.
Variable z.B A und B

A= 255
B = 0


Interrupt:
decr A
if A = 0 then A= 255 -B:
B= B+5
If B >254 then B= 255
end if

.

.
.

magnetix48
29.09.2006, 10:56
Hallo Roberto,

ich hätte das Problem hardwaremäßig gelöst, indem ich für die Takterzeugung U/F Wandler nehme. Sie bringen auf eine anloge Eingangsspannung eine proportionale Frequenz am Ausgang. Die Typenbezeichnung habe ich nicht im Kopf, aber wenn Interesse besteht, würde ich sie heraussuchen.

Gruß
Detlef

Roberto
29.09.2006, 11:34
Hallo Detlef.

Wie sollte das den dann funktionieren ?

Ich muss ja sagen können, fahre mir 10000 Schritte nach vorne, 10 zurück u.s.w.
Mit U/F Wandler könnte ich mir das höchstens mit einem zusätzlichen Encoder vorstellen..

l.G.

magnetix48
29.09.2006, 11:42
Hallo Roberto,

das sollte nur ein Denkanstoß für die Erzeugung unterschiedlicher Frequenzen sein. Du hast schon Recht, eine schrittgenaue Ansteuerung ist so kaum möglich. Mit dem Zusatzsignal Vorwärts und Rückwärts könne man schon einen Motor steuern, bräuchte dann aber, wie du schon schreibst, einen zusätzlichen Encoder, um die wirkliche Lage exakt zu bestimmen.

Gruß
Detlef

Ruppi
29.09.2006, 13:29
hallo,
der ansatz war schon richtig: du gibst in bascom einfach den überlauf vor, sodass der timer nach einer bestimmten zeit überläuft und den interrupt auslöst. nach jedem neuen interrupt prüfst du deine aktuelle position und beschleunigst oder verzögerst den ablauf durch änderung des timerwertes, also etwa so:
interrupt:
timer1=newValue
......
-> neuen timerwert berechnen und in newValue speichern
return:
du brauchst auch keine zusätzlichen timer, weil du ja im interrupt eine vektorinterpolation vornehmen kannst, so mache ich das auch. willst du z.b. eine strecke fahren, die in x-richtung 1000 schritte und in y-richtung nur 500 schritte beträgt, wird der motor für die y-achse nur in jedem zweiten interruptaufruf bewegt. such am besten mal nach bresenham-algorithmus, dieser wird eigentlich für die darstellung von linien auf einem bildschirm verwendet, es ist ja das gleiche problem! dieser bietet den vorteil, dass die vektorinterpolation auf integerbasis berechnet wird und er daher sehr schnell ist.
übrigens: für die ausgabe weiterer taktsignale hast du ja zwei timer im atmega8 - nur mal so als denkanstoß...
hoffe, ich konnte dir helfen und hab dich nicht nur verwirrt!

Ruppi

Roberto
29.09.2006, 13:57
Hallo Ruppi (Danke für die Antort)

Werde mir das mal durchkauen.

Brauche ich für weitere Taktsignale eigendlich zwingend mehr Timmer oder ginge das alles in einem Interrupt ?

Weil ich bräuchte dann mehr als 3 Achsen...
(Soll eigentlich ein Roboterarm werden mit Servomotoren und Harmonicdrive getrieben... ;-) )
l.G. Roberto

Roberto
29.09.2006, 15:15
kurze Frage:
Ich probiere gerade mit den maximalen Taktfrequenzen:

Kann es sein, dass in einer ISR Routine, diese fertig gearbeitet wird, auch wenn der Load-Wert vom Timer Kürzer ist ?

Ich dachte immer, wenn der Load-wert zu kurz ist, dass es dann die ISR abschneidet weil ja schon der nächste Überlauf da ist....?!

(Lade am Anfang der ISR schon den Timer neu)

Scheint aber nicht so zu sein.

Ruppi
29.09.2006, 16:44
hmm, war eigentlich auch davon ausgegangen, dass die isr einfach von vorne beginnt... hast du die nosave-option verwendet? glaube, könnte damit zusammenhängen, bin mir aber nicht sicher.
mehrere timer benötigst du nicht unbedingt, um mehrere motoren anzusteuern, die taktsignale dürfen nur nicht bei jedem durchlauf des interrupts erzeugt werden. bisher habe ich mich immer auf 3 achsen beschränkt, aber das sollte trotzdem gehen.

Ruppi

Roberto
30.09.2006, 00:01
Hallo Ruppi


hast du die nosave-option verwendet?
nein, eigentlich ganz normal..


Hättest Du vielleicht ein bisschen Code zum anschauen..? O:)

Derzeit habe ich es mal so gemacht.
Leider in der ISR... (Sonst fällt mir nix besseres ein)



Also ca. in der Art:

----------------ISR----------------
Load Timer1,...

If B < 100 Then
A = A + B
If A > 1000 Then
B = B + 1
A = 0
End If
End If

hier die Takausgabe..
Return
------------------

Das läuft so, dass der Takt jedesmal ausgegeben werden kann, wenn A = 0
Zuerst ist das eher selten, weil B noch klein ist und A und B summiert wird.
Dann erhöht sich B und erhöht damit immer schneller das A und somit eine schnellere Taktausgabe.
Solange bis B auf Maximum ist, dann wird die Rampenschleife nicht mehr durchlaufen..


Leider fällt mir nix besseres ein..:-k

l.G. Roberto

Ruppi
30.09.2006, 09:53
moin,
auf diese art wirst du nie eine saubere rampe fahren können, du möchtest ja eine lineare Geschwindigkeitsrampe erreichen. leider ist die gleichung, die du dafür nutzen musst, für einen controller zu aufwendig zu berechnen, da man in jedem interrupt eine wurzel berechnen müsste. allerdings gibt es dafür eine geeignete approximation, sodass man die berechnung mit ganzzahlen erschlagen kann.
ich habe hier einen schönen link von atmel, dort ist alles genau beschrieben:
atmel.com/dyn/resources/prod_documents/doc8017.pdf

Ruppi

Roberto
30.09.2006, 19:08
Hallo Ruppi

Danke für den Link.
Leider hilft mir das auch nicht viel, weil Englsich schlecht und mit Formeln auch :-(

Habe jetzt einen Load-Wert in der ISR von 440 Eingestellt
(ist 20kHz Ausgabe bei 10Mhz Q)

Also darf ich nur ganz wennig in der ISr Machen, sonst kann ich im normalem Programm nicht mehr viel machen...

Meine letzte Idee ist alle Werte (Ramp, normal u.s.w.) irgendwie in einen so Art Ringspeicher abzulegen, die die ISR nacheinander abarbeidet.

Aber noch keine Ahnung, ob sowas überhaupt irgendwie geht :-(

Hat noch jemand einen Tipp für mich..... ? :-)

l.G. Robert

Roberto
01.10.2006, 23:08
Hallo

Keine eine Tip ?

Habe inzwischen meine Rampen zusammenbekommen.
Ausgabe mit 20 kHz


'######################## Interrupts ###########################################

'######################### Timer1 Anfang #######################################
Takt:
Load Timer1 , 440 ' 440= Bei Prescale 1 und 10Mhz Q, = 20 Khz Takt


If Fahre > 0 Then 'ist was zum fahren da ?

If A < 255 Then A = A + 1 '---Rampe EIN ----


If A > 254 Then '---Rampe AUS ----
'------------------------------------------
Portd.0 = 0 '=======TAKT EIN===

If Rampe = 1 And B < 24 Then
'--nächsten Rampenwert holen---
A = Lookup(b , Rampe_rauf)
B = B + 1
End If

If Rampe = 0 And B < 24 Then
'--nächsten Rampenwert holen---
A = Lookup(b , Rampe_runter)
B = B + 1
End If

If Fahre < 24 Then ' Rampe umschalten
Rampe = 0
B = 0
A = 255
End If

'--Zählen---
Decr Fahre
Portd.0 = 1 '=======TAKT AUS===
'---------------------------------------------

If Fahre = 0 Then
Disable Timer1
B = 0
Rampe = 1 'Rampe RAUF vorwählen
End If

End If
End If


Return
'######################### Timer1 Ende #########################################

Rampe_rauf:
Data 10 , 20 , 30 , 40 , 50 , 60 , 70 , 80 , 90 , 100 , 110 , 120 , 130 , 140 , 150 , 160 , 170 , 180 , 190 , 200 , 210 , 220 , 230 , 240 , 250

Rampe_runter:
Data 250 , 240 , 230 , 220 , 210 , 200 , 190 , 180 , 170 , 160 , 150 , 140 , 130 , 120 , 110 , 100 , 90 , 80 , 70 , 60 , 50 , 40 , 30 , 20 , 10



Habe die Rampen jetzt in einer Data-Zeile abgelegt
(Werte nur mal zum probieren)

Leider musste ich in der ISR noch immer ein paar Rechnungen einbauen, aber zumindest einige zwischen dem Ein und Ausschalten vom Takt.
Da brauche ich eh ein bisschen Zeit, für einen längeren Puls.

Übergabe der Schritte mit der Variable "Fahre"


Was haltet ihr davon ?
Kritik ? Vorschläge ? :-)

L.G. Roberto

Gento
01.10.2006, 23:20
Hat keiner einen TIP Deine Frage.

Mein Tip :Kein Schrittmotor hat eine Lineare Rampe .
Deine 10,20,30 ist nur Plazebo wenn Du SM RICHTIG nutzen willst.
Legst Du nur H/L am SM an oder FRQ Modulierte H/L ?

Richtig oder Nicht , was willst du ist hier die Frage !

lg gento

Roberto
01.10.2006, 23:34
Hallo gento

Es geht nicht so richtig um Schrittmotoren.
Es wird damit ein Servomotor (mit Takt/Richtung) angesteuert.
Der verträgt schon einiges an Anlauffrequenz, aber für die Maximale Frequenz brauche ich doch Rampen.
(2000 *4 Encoder und 1:50 Getriebe)

Mir geht es eher um die best mögliche Programmierung der Takterzeugung! (Da habe ich keine Erfahrung)
(Optimal wäre halt so 40kHz Taktausgabe (+Rampen))

Derzeit sollten zumindest 3 Motoren mit 20kHz Ausgabe zu steuern sein..
Aber wie macht man das am besten ?
Lösungsansätze?
Was muss ich in der ISR rechnen und was herausen ?
u.s.w. :-)

Übergebe ich die Richtung auch gleich an die ISR oder schalte ich das Dir Signal im Programm..

Fragen über fragen ;-)

Ein Beispielprogramm wäre auch sehr hilfreich, wie es andere vielleicht gemacht haben ;-)

l.G. Roberto

Gento
02.10.2006, 00:06
Ich gehe davon aus das Du für Deine Arbeit /Aufgabenstellung nicht nach 1 Euro Job bezahlt wirst , sondern Lösungen/Arbeit gerne anderen überläst?

Gento

Roberto
02.10.2006, 00:40
??? ..................:-(