Forum: Mikrocontroller und Digitale Elektronik Absolute Position mit Schrittmotor


von Walter (Gast)


Lesenswert?

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
void set_target_pos (uint32_t ulNewPosition1)
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    
16
    
17
  }
18
  else if(ulNewPosition1 < sMotor[0].ulPosition)
19
  {
20
    sMotor[0].ulPosition = ulNewPosition1;    
21
    
22
    writeInt(XTARGET_1, ulNewPosition1); //Positive Fahrtrichtung      
23
  }        
24
}

von MaWin (Gast)


Lesenswert?

Walter schrieb:
> writeInt(XTARGET_1, -ulNewPosition1)

Klingt falsch, eher
1
writeInt(XTARGET_1, ulNewPosition1-sMotor[0].ulPosition);
2
3
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.

von Walter (Gast)


Lesenswert?

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
1
 writeInt(XTARGET_1, ulNewPosition1-sMotor[0].ulPosition);

? 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 -.-

von Wolfgang (Gast)


Lesenswert?

Walter schrieb:
> uint32_t ulNewPosition1

Walter schrieb:
> writeInt(XTARGET_1, -ulNewPosition1); //minus da in negative
> Fahrtrichtung

"uint32_t" aka. "unsigned long" und "-" verträgt sich nun nicht so 
wirklich.

von Patrick J. (ho-bit-hun-ter)


Lesenswert?

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

von Marc V. (Firma: Vescomp) (logarithmus)


Lesenswert?

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 ?

von Huh (Gast)


Lesenswert?

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?

von Thorsten O. (Firma: mechapro GmbH) (ostermann) Benutzerseite


Lesenswert?

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

von Marc V. (Firma: Vescomp) (logarithmus)


Lesenswert?

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...

von MaWin (Gast)


Lesenswert?

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:
1
writeInt(XTARGET_1, ulNewPosition1);
(Maximal 2^31).

von Walter (Gast)


Lesenswert?

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 .....

von MaWin (Gast)


Lesenswert?

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.

von Walter (Gast)


Lesenswert?

Walter schrieb:
>> einfach:writeInt(XTARGET_1, ulNewPosition1);
>> (Maximal 2^31).

XTARGET ist -2^31..+(2^31)-1

von dlchnr (Gast)


Lesenswert?

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.

von Walter (Gast)


Lesenswert?

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):
1
  writeDatagram(SWMODE_1, 0, 0, 0, 0); //sg_stop
2
    
3
    writeDatagram(CHOPCONF_1 , 0, 1, 1, 213); //TOFF: 5, HSTRT: 5, HEND: 3, TBL: 2
4
    writeDatagram(IHOLD_IRUN_1 , 0, 7, 2, 0);
5
    writeInt(VHIGH_1, 256);
6
    writeInt(VCOOLTHRS_1, 256);
7
    writeDatagram(PWMCONF_1,0,20,4,0);//PWM_GRAD: 4, pwm_autoscale: 1, FREEWHEEL: 1
8
    writeDatagram(RAMPMODE_1, 0, 0, 0,MODE_POSITION);
9
    writeInt(VSTART_1, 0);
10
    writeInt(A1_1, 40000);
11
    writeInt(V1_1, 50000);
12
    writeInt(AMAX_1, 40000);
13
    writeInt(VMAX_1, sMotor[0].ulNormalSpeed);
14
    writeInt(DMAX_1, 40000);
15
    writeInt(D1_1, 40000);
16
    writeInt(VSTOP_1, 10);
17
    writeInt(TZEROWAIT_1, 0);
18
    
19
    writeInt(XTARGET_1, -ulNewPosition1);
20
    
21
    writeInt(XACTUAL_1, 0);

von dlchnr (Gast)


Lesenswert?

Walter schrieb:
> Und wie erkenne ich dann die Richtung?

Das macht der TMC schon selber!
Er bildet intern die signed Differenz von NeuerPosition - AlterPosition.

von dlchnr (Gast)


Lesenswert?

wenn also abwechselnd die Positionen 8k und 4k angefahren werden sollen, 
dann beschreibe das XTARGET einfach abwechselnd mit 8k und 4k.

von Walter (Gast)


Lesenswert?

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?

von Michael B. (laberkopp)


Lesenswert?

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.

von Patrick J. (ho-bit-hun-ter)


Lesenswert?

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

von Walter (Gast)


Lesenswert?

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?
1
void stepper_set_target_position_0 (uint32_t ulNewPosition)
2
{    
3
  ucCounter0++;
4
  
5
  if (ucCounter0 == 2)
6
  {    
7
    sMotor[1].uiPosBuffer = ulNewPosition;
8
  }
9
  else if (ucCounter0 == 3)
10
  {
11
    ulNewPosition = sMotor[1].uiPosBuffer;
12
    sMotor[1].ulPosition = 270000;
13
  }
14
  else if (ucCounter0 == 4)
15
  {
16
    sMotor[1].ulPosition = 0;
17
  }
18
  else if (ucCounter0 == 5)
19
  {
20
    ulNewPosition = sMotor[1].uiPosBuffer;
21
    sMotor[1].ulPosition = 270000;
22
  }
23
  else if (ucCounter0 == 6)
24
  {
25
    sMotor[1].ulPosition = 0;
26
  }
27
  
28
  
29
  if (ulNewPosition > sMotor[1].ulPosition)
30
      {        
31
         ulXtarget2 = (-ulNewPosition);          
32
      } 
33
      else if(ulNewPosition < sMotor[1].ulPosition)
34
      {        
35
        
36
        ulXtarget2 = ulNewPosition;          
37
      }        
38
}

von Michael B. (laberkopp)


Lesenswert?

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.

von dlchnr (Gast)


Lesenswert?

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 ;-)

von Walter (Gast)


Lesenswert?

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.

von dlchnr (Gast)


Lesenswert?

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.

von Patrick J. (ho-bit-hun-ter)


Lesenswert?

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

von dlchnr (Gast)


Lesenswert?

> 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?

von dlchnr (Gast)


Lesenswert?

Patrick J. schrieb:
> Ist mir nicht ganz klar, was hier wirklich gewollt ist und was passiert.

und vorallem, passiert das mit oder ohen dem "if Unsinn"

von Walter (Gast)


Lesenswert?

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   
2
uint8_t ucRxBuffer[8] = {0x57,     0x03, 0x92,    0x09, 0xC4,   0x01,    0x38, 0x80};
3
4
  
5
ulTemp0 =  (uint32_t) ucRxBuffer[7] & 0x00FF;
6
ulTemp0 |= ( (uint32_t) ucRxBuffer[6] << 8 ) & 0xFF00;
7
ulTemp0 |= ( (uint32_t) ucRxBuffer[5] << 16) & 0xF0000;
8
         
9
stepper_set_target_position_0(ulTemp0);
10
         
11
        
12
ulTemp1 =  ( (uint32_t) ucRxBuffer[3] << 12) & 0xFF000;
13
ulTemp1 |= ( (uint32_t) ucRxBuffer[4] << 4 ) & 0x00FF0;
14
ulTemp1 |= ( (uint32_t) ucRxBuffer[5] >> 4 ) & 0x0000F;  
15
      
16
stepper_set_target_position_1(ulTemp1);    
17
18
19
void stepper_set_target_position_1 (uint32_t ulNewPosition1)
20
{    
21
  
22
  //not referenced jump out
23
  if ( sMotor[0].ucReferenced == 0 )
24
  {
25
    return;
26
  }  
27
  
28
  ucCounter1++;
29
  
30
  if (ucCounter1 == 3)
31
  {
32
    sMotor[0].ulPosition = 270000;    
33
    ulNewPosition1 = sMotor[0].uiPosBuffer;
34
  }
35
  else if (ucCounter1 == 4)
36
  {
37
    sMotor[0].ulPosition = 0;
38
    sMotor[0].uiPosBuffer = 0;
39
  }  
40
  
41
  
42
  if (ulNewPosition1 > sMotor[0].ulPosition)
43
  {
44
    sMotor[0].ulPosition = ulNewPosition1;
45
    sMotor[0].uiPosBuffer = ulNewPosition1;
46
    
47
    writeDatagram(SWMODE_1, 0, 0, 0, 0); //sg_stop
48
    
49
    writeDatagram(CHOPCONF_1 , 0, 1, 1, 213); //TOFF: 5, HSTRT: 5, HEND: 3, TBL: 2
50
    writeDatagram(IHOLD_IRUN_1 , 0, 7, 2, 0);
51
    writeInt(VHIGH_1, 256);
52
    writeInt(VCOOLTHRS_1, 256);
53
    writeDatagram(PWMCONF_1,0,20,4,0);//PWM_GRAD: 4, pwm_autoscale: 1, FREEWHEEL: 1
54
    writeDatagram(RAMPMODE_1, 0, 0, 0,MODE_POSITION);
55
    writeInt(VSTART_1, 0);
56
    writeInt(A1_1, 40000);
57
    writeInt(V1_1, 50000);
58
    writeInt(AMAX_1, 40000);
59
    writeInt(VMAX_1, sMotor[0].ulNormalSpeed);
60
    writeInt(DMAX_1, 40000);
61
    writeInt(D1_1, 40000);
62
    writeInt(VSTOP_1, 10);
63
    writeInt(TZEROWAIT_1, 0);
64
    
65
    writeInt(XTARGET_1, -ulNewPosition1);
66
    
67
    writeInt(XACTUAL_1, 0);    
68
  }
69
  else if(ulNewPosition1 < sMotor[0].ulPosition)
70
  {
71
    sMotor[0].ulPosition = ulNewPosition1;
72
    sMotor[0].uiPosBuffer = ulNewPosition1;
73
    
74
    writeDatagram(SWMODE_1, 0, 0, 0, 0); //sg_stop
75
    
76
    writeDatagram(CHOPCONF_1 , 0, 1, 1, 213); //TOFF: 5, HSTRT: 5, HEND: 3, TBL: 2
77
    writeDatagram(IHOLD_IRUN_1 , 0, 7, 2, 0);
78
    writeInt(VHIGH_1, 256);
79
    writeInt(VCOOLTHRS_1, 256);
80
    writeDatagram(PWMCONF_1,0,20,4,0);//PWM_GRAD: 4, pwm_autoscale: 1, FREEWHEEL: 1
81
    writeDatagram(RAMPMODE_1, 0, 0, 0,MODE_POSITION);
82
    writeInt(VSTART_1, 0);
83
    writeInt(A1_1, 40000);
84
    writeInt(V1_1, 50000);
85
    writeInt(AMAX_1, 40000);
86
    writeInt(VMAX_1, sMotor[0].ulNormalSpeed);
87
    writeInt(DMAX_1, 40000);
88
    writeInt(D1_1, 40000);
89
    writeInt(VSTOP_1, 10);
90
    writeInt(TZEROWAIT_1, 0);
91
    
92
    writeInt(XTARGET_1, ulNewPosition1);
93
    
94
    writeInt(XACTUAL_1, 0);    
95
  }          
96
}  
97
98
void stepper_set_target_position_0 (uint32_t ulNewPosition)
99
{    
100
  
101
  //not referenced jump out
102
  if ( sMotor[1].ucReferenced == 0 )
103
  {
104
    return;
105
  }
106
  
107
  ucCounter0++;
108
  
109
  if (ucCounter0 == 3)
110
  {
111
    sMotor[1].ulPosition = 270000;
112
    //PORTB.OUTSET = PIN2_bm; //rot
113
    ulNewPosition = sMotor[1].uiPosBuffer;
114
  }
115
  else if (ucCounter0 == 4)
116
  {
117
    sMotor[1].ulPosition = 0;
118
    sMotor[1].uiPosBuffer = 0;;
119
  }  
120
  
121
  ulNewPosition &= (unsigned long)(~1);
122
  
123
  if (ulNewPosition > sMotor[1].ulPosition)
124
  {        
125
    sMotor[1].ulPosition  = ulNewPosition;
126
    sMotor[1].uiPosBuffer = ulNewPosition;
127
    
128
    writeDatagram(SWMODE_2, 0, 0, 0, 0); //sg_stop  
129
    
130
    writeDatagram(CHOPCONF_2 , 0, 1, 1, 213); //TOFF: 5, HSTRT: 5, HEND: 3, TBL: 2/
131
    writeDatagram(IHOLD_IRUN_2 , 0, 7, 2, 0);
132
    writeInt(VHIGH_2, 256);
133
    writeInt(VCOOLTHRS_2, 256);
134
    writeDatagram(PWMCONF_2,0,20,4,0);//PWM_GRAD: 4, pwm_autoscale: 1, FREEWHEEL: 1  //
135
    writeDatagram(RAMPMODE_2, 0, 0, 0,MODE_POSITION);
136
    writeInt(VSTART_2, 0);
137
    writeInt(A1_2, 40000);
138
    writeInt(V1_2, 50000);
139
    writeInt(AMAX_2, 40000);
140
    writeInt(VMAX_2, sMotor[1].ulNormalSpeed);
141
    writeInt(DMAX_2, 40000);
142
    writeInt(D1_2, 40000);
143
    writeInt(VSTOP_2, 10);
144
    writeInt(TZEROWAIT_2, 0);
145
    
146
    writeInt(XTARGET_2, -ulNewPosition);
147
    
148
    writeInt(XACTUAL_2, 0);    
149
  } 
150
  else if(ulNewPosition < sMotor[1].ulPosition)
151
  {
152
    sMotor[1].ulPosition = ulNewPosition;
153
    sMotor[1].uiPosBuffer = ulNewPosition;
154
    
155
    writeDatagram(SWMODE_2, 0, 0, 0, 0); //sg_stop  
156
    
157
    writeDatagram(CHOPCONF_2 , 0, 1, 1, 213); //TOFF: 5, HSTRT: 5, HEND: 3, TBL: 2
158
    writeDatagram(IHOLD_IRUN_2 , 0, 7, 2, 0);
159
    writeInt(VHIGH_2, 256);
160
    writeInt(VCOOLTHRS_2, 256);
161
    writeDatagram(PWMCONF_2,0,20,4,0);//PWM_GRAD: 4, pwm_autoscale: 1, FREEWHEEL: 1
162
    writeDatagram(RAMPMODE_2, 0, 0, 0,MODE_POSITION);
163
    writeInt(VSTART_2, 0);
164
    writeInt(A1_2, 40000);
165
    writeInt(V1_2, 50000);
166
    writeInt(AMAX_2, 40000);
167
    writeInt(VMAX_2, sMotor[1].ulNormalSpeed);
168
    writeInt(DMAX_2, 40000);
169
    writeInt(D1_2, 40000);
170
    writeInt(VSTOP_2, 10);
171
    writeInt(TZEROWAIT_2, 0);
172
        
173
    writeInt(XTARGET_2, ulNewPosition);
174
        
175
    writeInt(XACTUAL_2, 0);
176
    
177
  }  
178
      
179
  
180
}


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 ...

von Patrick J. (ho-bit-hun-ter)


Lesenswert?

Hi
1
void stepper_set_target_position (uint8_t Motornummer,uint32_t ulNewPosition)
2
{    
3
  
4
  //not referenced jump out
5
  if ( sMotor[Motornummer-1].ucReferenced == 0 )
6
  {
7
    return;
8
  }
9
.....
10
}
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

von Michael B. (laberkopp)


Lesenswert?

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
void waitUntilNoMovement(char motor)
2
{
3
    int pos;
4
    do
5
    {   
6
        pos=readInt(motor); // wie auch immer readInt realisiert wäre, du hast offenbar einen ucRxBuffer
7
        delay(10);
8
    }
9
    while(pos!=readInt(motor));
10
}
11
12
void init(void)
13
{
14
    writeDatagram(SWMODE_1, 0, 0, 0, 0); //sg_stop
15
    writeDatagram(CHOPCONF_1 , 0, 1, 1, 213); //TOFF: 5, HSTRT: 5, HEND: 3, TBL: 2
16
    writeDatagram(IHOLD_IRUN_1 , 0, 7, 2, 0);
17
    writeInt(VHIGH_1, 256);
18
    writeInt(VCOOLTHRS_1, 256);
19
    writeDatagram(PWMCONF_1,0,20,4,0);//PWM_GRAD: 4, pwm_autoscale: 1, FREEWHEEL: 1
20
    writeDatagram(RAMPMODE_1, 0, 0, 0,MODE_POSITION);
21
    writeInt(VSTART_1, 0);
22
    writeInt(A1_1, 40000);
23
    writeInt(V1_1, 50000);
24
    writeInt(AMAX_1, 40000);
25
    writeInt(VMAX_1, sMotor[0].ulNormalSpeed); // welcher Wert auch immer
26
    writeInt(DMAX_1, 40000);
27
    writeInt(D1_1, 40000);
28
    writeInt(VSTOP_1, 10);
29
    writeInt(TZEROWAIT_1, 0);
30
    writeInt(XTARGET_1, -2147483647);
31
    waitUntilNoMovement(XACTUAL_1);
32
    writeInt(XACTUAL_1, 0);    
33
    writeDatagram(SWMODE_2, 0, 0, 0, 0); //sg_stop  
34
    writeDatagram(CHOPCONF_2 , 0, 1, 1, 213); //TOFF: 5, HSTRT: 5, HEND: 3, TBL: 2/
35
    writeDatagram(IHOLD_IRUN_2 , 0, 7, 2, 0);
36
    writeInt(VHIGH_2, 256);
37
    writeInt(VCOOLTHRS_2, 256);
38
    writeDatagram(PWMCONF_2,0,20,4,0);//PWM_GRAD: 4, pwm_autoscale: 1, FREEWHEEL: 1  //
39
    writeDatagram(RAMPMODE_2, 0, 0, 0,MODE_POSITION);
40
    writeInt(VSTART_2, 0);
41
    writeInt(A1_2, 40000);
42
    writeInt(V1_2, 50000);
43
    writeInt(AMAX_2, 40000);
44
    writeInt(VMAX_2, sMotor[1].ulNormalSpeed); // welcher Wert auch immer
45
    writeInt(DMAX_2, 40000);
46
    writeInt(D1_2, 40000);
47
    writeInt(VSTOP_2, 10);
48
    writeInt(TZEROWAIT_2, 0);
49
    writeInt(XTARGET_2, -2147483647);
50
    waitUntilNoMovement(XACTUAL_2);
51
    writeInt(XACTUAL_2, 0);    
52
}
53
54
void move(void)
55
{
56
    writeInt(XTARGET_1, 0);
57
    writeInt(XTARGET_2, 0);
58
    waitUntilNoMovement(XACTUAL_1);
59
    waitUntilNoMovement(XACTUAL_2);
60
    writeInt(XTARGET_1, 40000);
61
    writeInt(XTARGET_2, 80000);
62
    waitUntilNoMovement(XACTUAL_1);
63
    waitUntilNoMovement(XACTUAL_2);
64
    writeInt(XTARGET_1, 60000);
65
    writeInt(XTARGET_2, 100000);
66
    waitUntilNoMovement(XACTUAL_1);
67
    waitUntilNoMovement(XACTUAL_2);
68
    writeInt(XTARGET_1, 40000);
69
    writeInt(XTARGET_2, 80000);
70
    waitUntilNoMovement(XACTUAL_1);
71
    waitUntilNoMovement(XACTUAL_2);
72
    writeInt(XTARGET_1, 60000);
73
    writeInt(XTARGET_2, 100000);
74
    waitUntilNoMovement(XACTUAL_1);
75
    waitUntilNoMovement(XACTUAL_2);
76
}

von dlchnr (Gast)


Lesenswert?

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!

von dlchnr (Gast)


Lesenswert?

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.

von dlchnr (Gast)


Lesenswert?

und die fallweise Negierung

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.