Hallo,
habe ein Verstädnisproblem bzw. komme nicht auf die mögliche Lösung.
Zum Vorhaben: 1) 2 Schrittmotoren werden referenziert (Hartanschlag)
2) gefahrene Position wird genullt (
1
sMotor[0].ulPosition=0;sMotor[1].ulPosition=0;
)
3) [1 Position] Motor 1 wird auf Position 80000 gefahren &
Motor 0 auf 40000
4) [2 Position] wird angefahren M1 = 100000 und M0 =
60000
/***bis hierhin klappt es***/
5) Dann soll wieder zu Position 1 gefahren werden und
hier passt es nicht habe eine Differenz von bei M1 von 20000 bei M2
20000
6) es soll halt zwischen zwei Position hin und her
gefahren werden solange keine dritte position übermittelt wird z.B.
newPosition M1 30000 / M2 10000
Wieso klappt es bei mir nicht bzw. wie könnte man sowas realisieren ?
Das ist die Funktion für den Motor 0 die Funktion für Motor 1 ist
identisch
wobei es besser wäre eine Funktion für beide Motoren zu haben weiß aber
nicht wie ich das Programmieren könnte...daher hab ich halt zwei gleiche
Funktionen für jeweils den anderen Motor.
1
voidset_target_pos(uint32_tulNewPosition1)
2
{
3
4
//not referenced jump out
5
if(sMotor[0].ucReferenced==0)
6
{
7
return;
8
}
9
10
if(ulNewPosition1>sMotor[0].ulPosition)
11
{
12
sMotor[0].ulPosition=ulNewPosition1;
13
14
15
writeInt(XTARGET_1,-ulNewPosition1);//minus da in negative Fahrtrichtung
da aber niemand weiss was writeInt tatsächlich tut, ist das natürlich
geraten. Schrittmotore steuert man eigentlich mit step und dir an, nichz
mit writeInt.
MaWin schrieb:> Klingt falsch, eher> writeInt(XTARGET_1, ulNewPosition1-sMotor[0].ulPosition);>> sMotor[0].ulPosition = ulNewPosition1;> da aber niemand weiss was writeInt tatsächlich tut, ist das natürlich> geraten. Schrittmotore steuert man eigentlich mit step und dir an, nichz> mit writeInt.
writeInt schreibt eine int32_t Variable über SPI ins XTARGET_1 Register
von der Schritmotorsteuerung (TMC 5072)
Wieso
? Da der zweite Parameter von writeInt signed long ist wird über plus
oder minus die Drehrichtung entsprechend ausgeführt von der
Schrittmotorsteuerung...
Wieso klappt es bei mir zwei mal die Position (neue Position) richtig
anzufahren wenn ich aber wieder die Ursprungsposition anfahren möchte
habe ich immer eine Differenz von der Position davor.. Irgendwo ist ein
Logikfehler denn ich nicht sehe -.-
Walter schrieb:> uint32_t ulNewPosition1Walter schrieb:> writeInt(XTARGET_1, -ulNewPosition1); //minus da in negative> Fahrtrichtung
"uint32_t" aka. "unsigned long" und "-" verträgt sich nun nicht so
wirklich.
Walter schrieb:> habe ich immer eine Differenz von der Position davor.. Irgendwo ist ein> Logikfehler denn ich nicht sehe -.-
Soviel ich weiss, haben die Dinger eingebaute Encoder, wie wäre es
mit auslesen ?
Marc V. schrieb:> Walter schrieb:>> habe ich immer eine Differenz von der Position davor.. Irgendwo ist ein>> Logikfehler denn ich nicht sehe -.->> Soviel ich weiss, haben die Dinger eingebaute Encoder, wie wäre es> mit auslesen ?
Was meinst du mit "Dinger"?
Die Motoren? Welche sind das? Weißt du das?
Oder meinst du die Steuerung mit "Dinger"?
Sind die Encoder der Motoren (falls vorhanden) auch an die Steuerung
angeschlossen oder nur die Schrittmotoren selbst?
Wie kommst du darauf, das die Motoren des OP Encoder hätten? So wie ich
das sehe hat er das nirgends geschrieben...
Mit freundlichen Grüßen
Thorsten Ostermann
Huh schrieb:> Sind die Encoder der Motoren (falls vorhanden) auch an die Steuerung> angeschlossen oder nur die Schrittmotoren selbst?Thorsten O. schrieb:> Wie kommst du darauf, das die Motoren des OP Encoder hätten? So wie ich> das sehe hat er das nirgends geschrieben...Marc V. schrieb:> Soviel ich weiss, haben die Dinger eingebaute Encoder, wie wäre es> mit auslesen ?
Wie sich herausgestellt hat, weiss ich darüber nicht viel...
Irgendjemand hat mir vor ein paar Wochen diese Dinger (TMC5072) ;-)
erwähnt und hat in diesem Zusammenhang auch über Encoder geredet.
Mea culpa...
Walter schrieb:> TMC5072
Der nimmt die Position absolut, du ruiniert sie wenn du mit dem
höchstwertigen bit spielst.
Lass deinen ganzen if Unsinn weg und schreibe einfach:
MaWin schrieb:> Der nimmt die Position absolut, du ruiniert sie wenn du mit dem> höchstwertigen bit spielst.>> Lass deinen ganzen if Unsinn weg und schreibe> einfach:writeInt(XTARGET_1, ulNewPosition1);> (Maximal 2^31).
Und wie erkenne ich dann die Richtung? Denn die Positionswerte sind bei
mir immer positiv die reinkommen und entsprechend angefahren werden
sollen Bsp.
[1 CMD] M0 = 4k M1 = 8k -> fahre in negative Richtung
[2 CMD] M0 = 6k M1 = 10k -> fahre in negative Richtung
[3 CMD] M0 = 4k M1 = 8k -> fahre in positive Richtung
[4 CMD] M0 = 6k M1 = 10k -> fahre in negative Richtung
usw .....
Walter schrieb:> Und wie erkenne ich dann die Richtung? De
Die erkennt der TMC: Ist der Wert kleiner (signed long) als die aktuelle
Position, dreht er rückwärts.
Ich habe das Datenblatt des TMC 5072 nur mal schnell überflogen - dabei
sind mir zwei Dinge aufgefallen.
- die Position (XACTUAL), wie auch die Target Position (XTARGET) werden
vom IC als singend betrachtet - ich würde sie deshalb auch als solche
führen.
- beide sind absolut Werte, ich sehe deshalb keinen Grund, weshalb die
Funktion eine Fallunterscheidung bzw. eine Invertierung benötigen würde.
Zu beachten ist lediglich, dass Dich nach einer Positionierung auf
0x7FFFFF0
ein Anfahren der Position 0x80000010 nicht auf 0x80000010 bringen wird,
sondern auf 0x180000010 - der Motor wird also um 32 Schritte nach vorne
fahren (wrap around) und nicht "ewig" weit zurück.
Ein einzelner Move ist als auf eine Strecke von 0x7FFFFFF beschränkt.
MaWin schrieb:> Die erkennt der TMC: Ist der Wert kleiner (signed long) als die aktuelle> Position, dreht er rückwärts.
ich habe es gerade getestet aber ist nicht der fall denn:
[1 CMD] M0 = 4k M1 = 8k -> fahre in negative Richtung
[2 CMD] M0 = 6k M1 = 10k -> fahre in negative Richtung
//beim dritten Befehl fährt der Motor wieder in negative Richtung,
sollte aber positiv M0 = 6k M1 = 10k sein damit wieder die Position vom
[1 CMD] erreicht wird
[3 CMD] M0 = 4k M1 = 8k -> fahre in positive Richtung
Das ist meine Sequenz die ich über SPI sende ( minus ulnewPosition1 da
beim ersten CMD der Motor IMMER in negative Richtung fahren soll):
Walter schrieb:> Und wie erkenne ich dann die Richtung?
Das macht der TMC schon selber!
Er bildet intern die signed Differenz von NeuerPosition - AlterPosition.
dlchnr schrieb:> Das macht der TMC schon selber!> Er bildet intern die signed Differenz von NeuerPosition - AlterPosition.
Okay das ist noch besser nur hab ich folgende Situation:
Die Positionswerte für die Motoren M0 und M1 bekomme ich untergebracht
in 5 Bytes Bsp.:
// M0 M1
0x09C40 13880
40000 80000
Diese bereite ich vor in dem ich jeweils die Positionen von M0 und M1
aus den 5 Bytes extrahiere M0 = 0x09C40 und M1 = 0x13880, das klappt
soweit.
Aber wie übergebe ich das jetzt dem TMC 5072 ?
Das funktioniert nicht:
1) [1 CMD] XTARGET_1 = 0x13880 (M1 fährt Pos 80000 an) {soll aber
NEGATIV Pos 80000}
2) [2 CMD] XTARGET_1 = 0x186A0 (M1 fährt Pos 100000 an) {soll aber
NEGATIV Pos 100000}
// in Schritt 1 und 2 konnte ich einfach den Wert als nagativ übergeben
als -80000 & -10000 dann passt die Fahrtrichtung
//wie erkenne ich hier jetzt aus dem Wert 0x13880, dass die Richtung
positiv sein soll und an Pos 80000 gefahren werden soll?
3) [3 CMD] XTARGET_1 = 0x13880 (M1 fährt Pos 80000 an) {soll aber
POSITIV Pos 100000, damit Schritt 1 erreicht wird [erste Position
80000]}
Vllt denke ich auch zu kompliziert Fakt ist aber, dass ich die
Positionswerte im 5 Byte Buffer bekomme wobei dieses aufgeteilt ist in
MSB 2Byte+ 1/2Byte (nibble) für Motor 0 und LSB 2Byte + 1/2 (nibble)
für Motor 1, dieses muss ich jetzt entsprechend in das XTARGET Register
vom TMC übergeben....
Jemand noch eine Idee?
Walter schrieb:> Okay das ist noch besser nur hab ich folgende Situation:
Wie wäre es, das ganze Problem an Anfang zu beschreiben nicht nicht eine
halbe Salamischeibe nach der anderen anzuliefen ?
Walter schrieb:> 1) [1 CMD] XTARGET_1 = 0x13880 (M1 fährt Pos 80000 an) {soll aber> NEGATIV Pos 80000}> 2) [2 CMD] XTARGET_1 = 0x186A0 (M1 fährt Pos 100000 an) {soll aber> NEGATIV Pos 100000}
Wohl eher nicht negativ, denn da ist doch dein Anschlag.
Walter schrieb:> writeInt(XTARGET_1, -2147483647); // zum Anschlag fahren
P.S.: Man sollte hier warten bis man auch wirklich am Anschlag ist
(stall, XACTUAL ändert sich beim auslesen nicht mehr) bevor man nullt
> writeInt(XACTUAL_1, 0); // Position nullen
Versuch es mal mit positiv.
Hi
Habe ich wohl wieder was verpasst ...
Dein Code weiter oben fuhr nicht mehr auf die Anfangsposition zurück,
warum auch immer.
Das ist behoben?
Ich gehe Mal von 'Ja' aus, sonst wäre es nämlich nicht sonderlich
schlau, eine neue Baustelle aufzureißen.
Ließ nach, wie Du eine Position >16bit übergeben kannst, dabei kann auch
ein 'Nein, geht nicht' raus kommen - kA, so weit habe ich mich in Deine
Datenblätter noch nicht eingearbeitet.
MfG
Michael B. schrieb:> Wohl eher nicht negativ, denn da ist doch dein Anschlag.
Referenzfahrt wurde schon davor ausgeführt.
Michael B. schrieb:> P.S.: Man sollte hier warten bis man auch wirklich am Anschlag ist> (stall, XACTUAL ändert sich beim auslesen nicht mehr) bevor man nullt
das mache ich auch so in der homing(); Fuinktion aber hier geht es darum
nach der erfolgreich abgeschlossenen Referenzfahrt die Positionen
anzufahren...abhängig vom eintreffenden Wert
Hab mal aus Verzweifelung sowas probiert...funktioniert aber nur halt 6
mal
[beim 7 Befehl (M0 = 40000 M1 = 80000) wird wieder die falsche Position
angefahren)
Ich möchte doch nur nach der Referenzfahrt absolute Positionen anfahren
stehe auf dem Schlauch kann bitte jemand helfen?
Walter schrieb:> das mache ich auch so in der homing(); Fuinktion aber hier geht es darum> nach der erfolgreich abgeschlossenen Referenzfahrt die Positionen> anzufahren
Also NATÜRLICH mal wieder NICHT den GANZEN initialisierenden Code
gepostet obwohl du es so drangeschrieben hast.
Bei dir ist nicht nur die Lösung Murks, sondern auch die
Fragestellungen.
Welchen Sinn soll es machen, nach dem Homing eine negative Position
anzufahren ? Wenn man bei 0 am Anschlag steht, möchtest du tiefer in den
Anschlag reinfahren ?
Oder hast du aus Versehen die Kabel am Schrittmotor falschrum
angeschlossen und er fährt in positive Richtung an den Anschlag....
Walter schrieb:> Das ist meine Sequenz die ich über SPI sende
Wenn das nicht deine Initilisierung ist sondern JEDESMAL gemacht wird,
> writeDatagram(SWMODE_1, 0, 0, 0, 0); //sg_stop
:
> writeInt(XACTUAL_1, 0);
dann hast du dir mit
writeInt(XACTUAL_1, 0);
natürlich völlig die Position vergniesgnaddelt.
Da steht ja nicht ohne Grund im Datenblatt ddaß man den Wert nur setzen
darf zu Beginn und niemals mehr später.
Walter schrieb:> Das funktioniert nicht:> 1) [1 CMD] XTARGET_1 = 0x13880 (M1 fährt Pos 80000 an) {soll aber> NEGATIV Pos 80000}> 2) [2 CMD] XTARGET_1 = 0x186A0 (M1 fährt Pos 100000 an) {soll aber> NEGATIV Pos 100000}> // in Schritt 1 und 2 konnte ich einfach den Wert als nagativ übergeben> als -80000 & -10000 dann passt die Fahrtrichtung>> //wie erkenne ich hier jetzt aus dem Wert 0x13880, dass die Richtung> positiv sein soll und an Pos 80000 gefahren werden soll?> 3) [3 CMD] XTARGET_1 = 0x13880 (M1 fährt Pos 80000 an) {soll aber> POSITIV Pos 100000, damit Schritt 1 erreicht wird [erste Position> 80000]}
Wenn ich das richtig verstehe, sind bei Dir einfach die Richtung Deiner
Detenquelle und die des TMC vertauscht.
Du negierst also einfach die aus der Datenquellle extraierten Werte und
übergibst sie in das XTARGET-Register - also -8000, -10000, -8000
Du must nicht erkennen, dass die Richtung positiv sein muss, dass macht
der TMC! Einfach alle Werte negieren, übergeben und fertig ;-)
Patrick J. schrieb:> Hi>> Was übergibst Du genau?>> Referenzieren, dadurch Positionen 0 und 0> 1. 80k 40k> 2. 100k 60k> 3. ?? und ??> und Du kommst wo dabei an?>> MfG
1. Referenzfahrt: M0 = Pos 0 / M1 = Pos 0
2. Positionen: M0 = 40k / M1 = 80k
3. Positionen: M0 = 60k / M1 = 100k
//Bis Punkt 3 klappt es soweit ab Punkt 4 wird M0 40k & M1 80k
angefahren
müsste aber M0 = 60k & M1 = 100k sein damit man wieder auf punkt 2 der
Positionen landet.
4. Positionen: M0 = 40k / M1 = 80k
5. Positionen: M0 = 60k / M1 = 100k
usw..
Die Motor Fahrtrichtung sollte abhängig von den Positionen so sein:
1. M0 & M1 positiv Richtung (nach oben) [klappt]
2. M0 & M1 negative Richtung (nach unten) [klappt]
3. M0 & M1 negative Richtung (nach unten) [klappt]
4. M0 & M1 positiv Richtung (nach oben)[klappt nicht da M0 & M1 da 20000
zu wenig]
usw.
Oder - vielleicht einfacher für Dich - vergiss das mit dem Negieren und
klemme einfach eine der beiden Wicklingen Deines Schrittmotors andersrum
an - dann kannst Du 8000, 10000, 8000 übergeben.
1. Referenzfahrt: M0 = Pos 0 / M1 = Pos 0 (= 0/0)
2. Positionen: M0 = 40k / M1 = 80k (=40k/80k)
3. Positionen: M0 = 60k / M1 = 100k (=60k/100k ??)
4. Positionen: M0 = 40k / M1 = 80k (was kommt hier? so ca.)
5. Positionen: M0 = 60k / M1 = 100k
Ist mir nicht ganz klar, was hier wirklich gewollt ist und was passiert.
Was passiert, wenn Du die Motoren einzeln nacheinander verfahren lässt?
Befürchte, daß Du die Soll und Ist-Positionen zwischen den Motoren
vertauscht.
Was passiert, wenn Du
- M0=0
- M1=5k
- M0=1k
- M0=2k
- M0=3k
- M0=2k
- M0=1k
- M0=0
machst?
Bewegt sich ggf. Motor 1 (statt dem Init) bei einer der Bewegungen?
Gleicher mit M1 (dann M0 zuvor frei fahren)
MfG
> 1. M0 & M1 positiv Richtung (nach oben) [klappt]> 1) [1 CMD] XTARGET_1 = 0x13880 (M1 fährt Pos 80000 an) {soll aber> NEGATIV Pos 80000}
Bring' doch mal ein saubere Beschreibung zu Papier, was der Motor machen
soll, unabhängig davon, was der Motor auf Grund des Programmes macht -
denn die beiden Beschreibung oben scheinen sich ja mal zu widersprechen.
Was ist für Dich positive Richtung - das, was der Motor macht, wenn du
ihn von 0 auf 80000 bewegst, oder musst Du von 0 auf -80000 gehen, damit
der Motor "nach oben" verfährt?
Hier noch der Quellcode vllt ist dann das Problem eindeutiger zu sehen:
1
ucRxBuffer[8]
ändert sich natürlich mit jeder neuen Position die gesendet wird z.B.
so:
1
// 1.Positionen M0&M1
2
ucRxBuffer[0]=0x57;
3
ucRxBuffer[1]=0x03;
4
ucRxBuffer[2]=0x92;
5
6
ucRxBuffer[3]=0x09;
7
ucRxBuffer[4]=0xC4;
8
ucRxBuffer[5]=0x01;
9
ucRxBuffer[6]=0x38;
10
ucRxBuffer[7]=0x80;
11
12
13
// 2.Positionen M0&M1
14
ucRxBuffer[0]=0x57;
15
ucRxBuffer[1]=0x03;
16
ucRxBuffer[2]=0x92;
17
18
ucRxBuffer[3]=0x0E;
19
ucRxBuffer[4]=0xA6;
20
ucRxBuffer[5]=0x01;
21
ucRxBuffer[6]=0x86;
22
ucRxBuffer[7]=0xA0;
23
24
25
// 3.Positionen M0&M1
26
ucRxBuffer[0]=0x57;
27
ucRxBuffer[1]=0x03;
28
ucRxBuffer[2]=0x92;
29
30
ucRxBuffer[3]=0x09;
31
ucRxBuffer[4]=0xC4;
32
ucRxBuffer[5]=0x01;
33
ucRxBuffer[6]=0x38;
34
ucRxBuffer[7]=0x80;
35
36
37
// 4.Positionen M0&M1
38
ucRxBuffer[0]=0x57;
39
ucRxBuffer[1]=0x03;
40
ucRxBuffer[2]=0x92;
41
42
ucRxBuffer[3]=0x0E;
43
ucRxBuffer[4]=0xA6;
44
ucRxBuffer[5]=0x01;
45
ucRxBuffer[6]=0x86;
46
ucRxBuffer[7]=0xA0;
47
48
49
// 5.Positionen M0&M1
50
ucRxBuffer[0]=0x57;
51
ucRxBuffer[1]=0x03;
52
ucRxBuffer[2]=0x92;
53
54
ucRxBuffer[3]=0x09;
55
ucRxBuffer[4]=0xC4;
56
ucRxBuffer[5]=0x01;
57
ucRxBuffer[6]=0x38;
58
ucRxBuffer[7]=0x80;
Der Quellcode unten funktioniert wenn sich Position 4 Mal ändert beim 5
mal ändern wird eine falsche Position angefahren und zwar um jeweil M0 &
M1 20000 Differenz
1
//Im ucRxBuffer[3..7] sind die Positionen der Motoren enthalten
Wie könnte ich das Lösen? Wie schon erwähnt wäre es zudem optimal wenn
man die zwei Funktionen die ja das selbe machen für den jeweilen Motor
irgendwie zusammen fassen könnte ...
Wobei das
uint8_t Motornummer
bestimmt verbessert werden kann :)
Davon ab - wenn der Wert uint ist, sollte die Zahl Vorzeichenlos sein -
da dürften Negativ-Werte doch gar nicht funktionieren, oder??
MfG
Walter schrieb:> Wie könnte ich das Lösen?
In dem du spassenhalber mal die Antworten liest und versuchst zu
verstehen, die dir schon gegeben worden sind ?
Walter schrieb:> writeInt(XTARGET_1, -ulNewPosition1);
Falsch: > writeInt(XACTUAL_1, 0);
Walter schrieb:> writeInt(XTARGET_1, ulNewPosition1);
Falsch: > writeInt(XACTUAL_1, 0);
Walter schrieb:> writeInt(XTARGET_2, -ulNewPosition);
Falsch: > writeInt(XACTUAL_2, 0);
Walter schrieb:> writeInt(XTARGET_2, ulNewPosition);
Falsch: > writeInt(XACTUAL_2, 0);
Wie kommt man überhaupt auf die abstruse Idee, die aktuelle Position
ständig überschreiben zu wollen während der Motor noch läuft ?
Auch der Rest vom Programm ist weitgehend schlecht programmiert, man
muss nicht ständig alles neu initialisieren, und die Positionsangabe
dermassen oft abzuändern ist natürlich verwirrend. Alleine die Funktion
stepper_set_target_position die einen ominösen ucCounter mitführt damit
sie bei jedem Aufruf anders reagiert ist ein wahnwitziges Beispiel
völlig abstrusen Programmierstils.
1
voidwaitUntilNoMovement(charmotor)
2
{
3
intpos;
4
do
5
{
6
pos=readInt(motor);// wie auch immer readInt realisiert wäre, du hast offenbar einen ucRxBuffer
beratungsresistent!?
immer noch das "if", immer noch das "-"!
ein "-" könnte ins Spiel kommen, wenn der TMC und du grundsätzlich
anderer Meinung seit, was "positiv" ist, aber dann immer!
Michael B. schrieb:> Auch der Rest vom Programm ist weitgehend schlecht programmiert, man> muss nicht ständig alles neu initialisieren, und die Positionsangabe> dermassen oft abzuändern ist natürlich verwirrend. Alleine die Funktion> stepper_set_target_position die einen ominösen ucCounter mitführt damit> sie bei jedem Aufruf anders reagiert ist ein wahnwitziges Beispiel> völlig abstrusen Programmierstils.
Hab' ich mir auch gedacht - allein hab' ich Zweifel, ob das verstanden
wird, sonst hätte ich mich auch dazu geäußert - ich wäre froh, wenn mal
die Fallunterscheidung und die Fallweise Negieren verschwinden würden.