Forum: Mikrocontroller und Digitale Elektronik TMC222 am PIC (in Assembler), zu kleiner Wertebereich


von Mario G. (rodenberger)


Lesenswert?

Hallo
Brauche dringend Eure Hilfe.
Ich bin nur Gelegenheitsprogrammierer und das auch "nur" in Assembler.

Es geht um die Ansteuerung eines TMC222 (Schrittmotortreiber) mit einem 
PIC.
Soweit funktioniert alles. Initialisierung und auch die Ansteuerung über 
I2C selbst.
Mein Problem ist der kleine Wertebereich von ca. -32000 bis +32000.
Ich benötige etwa 5x so viel.
Die Umsetztung ist für Mich ein Problem ..... und in Assembler sicher 
auch nicht so einfach.....schon gar nicht wenn man so wenig programmiert 
wie ich.
Hat eventuell schon jemand das Problem gelöst und dazu eine Routine 
geschrieben?
Ich möchte ungern auf einen anderen Treiber umsteigen, da mir der TMC222 
soweit sehr zusagen würde, da ich auch recht wenig Platz für eine große 
Platine habe, die soweit eigentlich auch schon fertig ist.
Bin auch gerne breit eine kleine Spende zu zahlen ;o).

Vielen Dank für Eure Hilfe!!!!!

von Иван S. (ivan)


Lesenswert?

Mario G. schrieb:
> Mein Problem ist der kleine Wertebereich von ca. -32000 bis +32000.
> Ich benötige etwa 5x so viel.

Gibt denn die Datenquelle überhaupt genauere Werte her? Ansonsten 
nimm/definiere/bastle Dir einfach einen größeren Datentyp, zum Beispiel 
nimmst Du 24 statt 16 Bits. Dürfte doch in Assembler kein Problem sein.

> Die Umsetztung ist für Mich ein Problem ..... und in Assembler sicher
> auch nicht so einfach.....schon gar nicht wenn man so wenig programmiert
> wie ich.

Wo genau hakt's denn? Ich kenne zwar den PIC-Assembler nicht, aber ohne 
Code wird dir auch keiner helfen können, der den PIC-Assembler 
beherrscht.

> Ich möchte ungern auf einen anderen Treiber umsteigen, da mir der TMC222
> soweit sehr zusagen würde, da ich auch recht wenig Platz für eine große
> Platine habe, die soweit eigentlich auch schon fertig ist.
> Bin auch gerne breit eine kleine Spende zu zahlen ;o).

Der TMC222 hat (soweit ich das nach erstem Überfliegen sehe) einen 16 
bit breiten Positionszähler. Du wirst den Baustein also wohl oder übel 
wechseln müssen.

Iwan

von Steffen H. (avrsteffen)


Lesenswert?

Was soll er denn machen mit noch mehr Positionsschritte? Wenn er einfach 
nur drehen soll hab ich noch was.

Grüße Steffen

von Mario G. (rodenberger)


Lesenswert?

Hallo,
da kommen ja ganz schnell ein paar Antworten.

Ich fasse mal kurz zusammen. Werte gerundet.

Der Motor soll von 0 bis ca. 200.000 fahren.
Nun kann ich die 200.000 nicht direkt an den TMC senden, sondern muss 
erst mal eine 32.000 senden. Eh der Motor die 32000 erreicht hat (noch 
vor der Rampe), muss ich einen neuen Positions-Wert senden , der 
unterschied aber nicht größer sein darf als 32767. sonnst läuft der 
Motor plötzlich rückwärts.

Die  Übergang erfolgt von +32766,+32767 nach -32768,-32767...
Das ganze muss ich dann so oft machen bis ich da bin wo ich hin will.
Vom Prinzip brauch ich eigentlich nur einen weiteren Zähler im PIC, 
sowie die ständige Abfrage der Position und der änderung dieser, bis ich 
bei 200.000 schritten bin.

von Steffen H. (avrsteffen)


Lesenswert?

Tja, wenn du mit Rampe fahren willst, dann musst du das alles selber im 
PIC durchrechnen. Der Ansatz geht aber schon die richtige Richtung.

von Mario G. (rodenberger)


Lesenswert?

ja, nur hilft mit das leider gar nicht weiter

von Steffen H. (avrsteffen)


Lesenswert?

Willst du denn mit Rampe verfahren?

von Matthias H. (mheininger)


Lesenswert?

Mario G. schrieb:
> Hallo,
> da kommen ja ganz schnell ein paar Antworten.
>
> Ich fasse mal kurz zusammen. Werte gerundet.
>
> Der Motor soll von 0 bis ca. 200.000 fahren.
> Nun kann ich die 200.000 nicht direkt an den TMC senden, sondern muss
> erst mal eine 32.000 senden. Eh der Motor die 32000 erreicht hat (noch
> vor der Rampe), muss ich einen neuen Positions-Wert senden , der
> unterschied aber nicht größer sein darf als 32767. sonnst läuft der
> Motor plötzlich rückwärts.
>
> Die  Übergang erfolgt von +32766,+32767 nach -32768,-32767...
> Das ganze muss ich dann so oft machen bis ich da bin wo ich hin will.
> Vom Prinzip brauch ich eigentlich nur einen weiteren Zähler im PIC,
> sowie die ständige Abfrage der Position und der änderung dieser, bis ich
> bei 200.000 schritten bin.

Das ist richtig, der Weg zu einer 32-Bit Position sollte in Abschnitte 
kleiner 30000 (das Limit, das ich verwende) unterteilt werden und 
jeweils rechtzeitig (vor Beginn der Bremsrampe!) neu an den TMC 
uebertragen werden.

Das ganze funktioniert dann etwa wie folgt:
1
static int16_t    gLastActualPos;
2
static int16_t    gStatActualPos;
3
static int32_t    gPosition;
4
5
static uint8_t _tmcSetPosition(int16_t pos) {
6
    if (i2cStart(TMC_ADR)) return 1;
7
    if (i2cWrite(tmcSET_POSITION_CMD)) return 1;
8
    if (i2cWrite(0xFF)) return 1;
9
    if (i2cWrite(0xFF)) return 1;
10
    if (i2cWrite(pos >> 8)) return 1;
11
    if (i2cWrite(pos & 0xFF)) return 1;
12
    i2cStop();
13
    return 0;
14
}
15
16
static uint8_t _tmcGetPosition() {
17
    // Senden des Kommandos
18
    if (i2cStart(TMC_ADR)) return 1;
19
    if (i2cWrite(tmcGET_FULL_STATUS2_CMD)) return 1;
20
    i2cStop();
21
    // Empfangen und speichern der Antwort
22
    if (i2cStart(TMC_ADR + 1)) return 1;
23
    uint8_t data[9];
24
    data[1] = i2cReadAck();
25
    data[2] = i2cReadAck();
26
    data[3] = i2cReadAck();
27
    data[4] = i2cReadAck();
28
    data[5] = i2cReadAck();
29
    data[6] = i2cReadAck();
30
    data[7] = i2cReadAck();
31
    data[8] = i2cReadNak();
32
    i2cStop();
33
    // Dekodieren der Antwort
34
    gStatActualPos = (data[2] << 8) + data[3];
35
    // update position
36
    gPosition += (gStatActualPos - gLastActualPos);
37
    gLastActualPos = gStatActualPos;
38
    return 0;
39
}
40
41
uint8_t tmcMoveTo(int32_t pos) {
42
    do {
43
        _tmcGetPosition();
44
        if (pos == gPosition) break;
45
        int16_t hpos = gStatActualPos + (int16)((pos - gPosition)%0x4000);
46
        _tmcSetPosition(hpos);
47
        /*
48
           Die Wartezeit orientiert sich an der maximalen
49
           Geschwindigkeit und an den 16384 Schritten
50
        */
51
        WARTEN!
52
    } while(1);
53
}

Das Schema geht davon aus, dass einer gobalen 32-Bit Position von 0 auch 
eine 0 beim Schrittzaehler im TMC entspricht.

von Mario G. (rodenberger)


Lesenswert?

Hallo Steffen.
Ja, Rampen brauche ich.
Hätte sonnst irgend einen L-Typ als Treiber genommen und den Rest im Pic 
gemacht. So was hab ich schon.


Hallo Matthias,
in C sieht das alles etwas einfacher aus, wenn ich auch nicht jede Zeile 
genau verstehe. Habe leider kein Prog. womit ich deinen Code so in 
meinen Assembler übernehmen kann.

Oder hast Du solche Möglichkeiten????
Würde Dir dann mein Prog schicken !!!???...........

von Steffen H. (avrsteffen)


Lesenswert?

Hallo Mario

Na sag ich doch. Du must alles nochmal selber rechnen im PIC. Und vor 
allem ganz wichtig:
>Position sollte (vor Beginn der Bremsrampe!) neu an den TMC uebertragen >werden
Und da ist die Schwierigkeit. Leider hab ich da jetzt auch noch keinen 
Ansatz..

Steffen

von Matthias H. (mheininger)


Lesenswert?

Steffen H. schrieb:
> Hallo Mario
>
> Na sag ich doch. Du must alles nochmal selber rechnen im PIC. Und vor
> allem ganz wichtig:
>>Position sollte (vor Beginn der Bremsrampe!) neu an den TMC uebertragen >werden
> Und da ist die Schwierigkeit. Leider hab ich da jetzt auch noch keinen
> Ansatz..
>
> Steffen

Hallo,

im Datenblatt des TMC222 stehen die Formeln, die es Erlauben je nach 
eingestelltem Vmax (Kapitel 5.1.4) und Beschleunigungsparameter (Kapitel 
5.1.6) die Schritte waehrend einem normalen Fahren (aus Vmax) und dem 
Abbremsen (Seite 12, am Ende von 5.1.6) zu Berechnen und aus der 
maximalen Laenge eines Abschnittes (ca 16000 Schritte) die dafuer 
benoetigte Zeit zu berechnen. Die neuen Position muessen jeweils vor 
Ablauf dieser Zeit an den TMC gesendet werden.

In der Tabelle 3 auf Seite 10 steht, dass die maximale Geschwindigkeit 
15564 Microschritte (1/16) pro Sekunde betraegt. Bei einer maximalen 
Abschnittslaenge von 16000 Mikroschritten ergibt sich, dass mindestens 
einmal pro Sekunde die neue Position an den TMC222 uebertragen werden 
muss. Ich hatte damals in der Hauptschleife 5 mal pro Sekunde die neue 
Position uebertragen.

Die Rampe faehrt der TMC222 dann selbst, da z.B. bei einem kurzen Weg 
nur einmal eine Position an den TMC gesendet wird (sofern er diese in 
1/5 Sekunde erreichen kann).

Bei meinem C-Code von oben ist nicht beruecksichtigt, dass die Position 
nur einmal an den TMC gesendet werden muss, falls der Abstand von der 
aktuellen Position maximal 32000 Schritte betraegt.

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.