STM32 counter up/down mit Step/Dir Signalen

OP #7425983
Lesenswert?

Hallo Leute,

ich suche , wie im Betreff geschrieben , eine Möglichkeit beim STM32F411 die HW-counter für Step/Dir Signale zu realisieren (5 Stück !). Es geht um das Lesen der Signale für die Steuerung einer 5-Achs CNC Fräsmaschine. (5 Step/Dir Signale mit max. 250 kHz) Derzeit mache ich es mittels ext. Interupt möchte aber die Möglichkeit nutzen die Timer 1,2,3,4,5 zu verwenden , ähnlich den HW-Countern für Quadrature Encoder. Diese hab ich getestet , laufen perfekt mit den A/B Signalen von den Encodern. Gibt es eine Möglichkeit die Timer Register so zu konfigurieren dass sie auch mit STEP/DIR Signalen so problemlos umgehen können ?
Ich finde keine Möglichkeit das Richtungssignal einzubinden um den Counter ab- , bzw. aufwärts zählen zu lassen. Bin für jede Hilfe dankbar. Ich benutze MikroBasic , erhalte leider im MikroE Forum keinerlei Hilfe zu dem Thema.

Schönes Wochenende, Gerhard

#7426100
Lesenswert?

Gerhard H. schrieb:

Gibt es eine Möglichkeit die Timer Register so zu konfigurieren dass sie auch mit STEP/DIR Signalen so problemlos umgehen können ?

Nein.

Gerhard H. schrieb:

Würde für den Fall , wenns wirklich keine Möglichkeit mittels HW-counter beim STM32 gibt , ein paar AVR's verwenden.

Bei 250 kHz mußt Du die in Assembler programmieren und per IIC auslesen. Eine kompakte Lösung wäre mit einem Pico-Board mit RP2040 möglich. Reicht Dir denn der relative langsame Zugriff per IIC-Bus?

Oder anstatt diskreter Logik ein 8-pol. AVR zur Umsetzung Step/Dir -> PhaseA/PhaseB verwenden und dann auf die STM-Timer geben.

OP #7426132
Lesenswert?

Mi N. schrieb:

Oder anstatt diskreter Logik ein 8-pol. AVR zur Umsetzung Step/Dir -> PhaseA/PhaseB verwenden und dann auf die STM-Timer geben.

Genau so hab ich es vor wenn es keine interne Möglichkeit im STM32 gibt. Die AVR's in Assembler für die Wandlung Step/Dir --> A/B zu programmieren, da sehe ich kein Problem. Jedoch kann ich es kaum glauben dass die Timer des STM32 bei der Vielfalt an Möglichkeiten nicht zu konfigurieren sind um STEP/DIR zu lesen. Warscheinlich sehe ich den Wald vor lauter Bäumen nicht .... oder so ähnlich. Außerdem beschäftige ich mich erst seit 2 Wochen mit dem 32bitter , also bin da recht neu dabei. (hobbymäßig..)

BG Gerhard

#7426174
Lesenswert?

Gerhard H. schrieb:

Genau so hab ich es vor wenn es keine interne Möglichkeit im STM32 gibt. Die AVR's in Assembler für die Wandlung Step/Dir --> A/B zu programmieren, da sehe ich kein Problem.

Da wäre ich bei 250kHz VORSICHTIG. Ausser für unserem heldenhaften C-hater ist das auch in ASM schon sportlich. Aber vor allem, warum? Sind ZWEI kleine CMOS-ICs / Kanal zuviel? Es reichen sogar weniger, siehe Anhang! 9 Stück für 5 Kanäle.

Jedoch kann ich es kaum glauben dass die Timer des STM32 bei der Vielfalt an Möglichkeiten nicht zu konfigurieren sind um STEP/DIR zu lesen.

Beim ATXmega kann man die IOs so konfigurieren, daß man damit steigende und fallende Flanken erkennt und Hardware-Events auslöst, welche direkt den Timer ansteuern. Vermutlich können das auch die STM32.

Warscheinlich sehe ich den Wald vor lauter Bäumen nicht .... oder so ähnlich.

Zeig mal einen Link auf ein Datenblatt.

Angehängte Dateien:
#7426184
Lesenswert?

Gerhard H. schrieb:

Jedoch kann ich es kaum glauben dass die Timer des STM32 bei der Vielfalt an Möglichkeiten nicht zu konfigurieren sind um STEP/DIR zu lesen.

Wenn man genauer hinsieht, sind die Möglichkeiten doch begrenzt, wie auch andere Sachen bei den STM32. Es fällt meist erst dann auf, wenn man gezielt eine Lösung braucht. Wenn Du den F411 erst kurz kennst, plane die Verwendung der IO-Pins sorgfältig, damit Du die benötigte Peripherie auch voll nutzen kannst.

Die AVR's in Assembler für die Wandlung Step/Dir --> A/B zu programmieren, da sehe ich kein Problem.

Mit einem guten C-Compiler ginge das vielleicht auch schon. Es wäre einen Versuch wert - aber nicht bei schönem Sonnenwetter ;-)

OP #7426201
Lesenswert?

(Firma: egal) #7426243
Lesenswert?

Falk B. schrieb:

Beim ATXmega kann man die IOs so konfigurieren, daß man damit steigende und fallende Flanken erkennt und Hardware-Events auslöst, welche direkt den Timer ansteuern. Vermutlich können das auch die STM32.

Damit kannst du Zählen, aber nicht zusätzlich mit einem zweiten Pin die Zählrichtung umzuschalten. Für das Umschalten wird man um einen Interrupt und eine paar Zeilen Programmcode wohl nicht drumherum kommen, wenn man nicht noch etwas zusätzliche Hardware spendieren will.

Die Wahrscheinlichkeit das es sowas fertig gibt dürfte arg gering sein weil es wohl keinen Sensor gibt er sowas ausgibt und eine µC das verarbeiten/zählen müsste. Zur Kommunikation zwischen zwei µC wäre sowas als Protokoll noch absurder. Gray-Code ist dagegen recht gebräuchlich und wird daher auch von etlichen µC in Hardware unterstützt.

#7426315
Lesenswert?

Mich hat einfach selber interessiert, ob man es bei hinreichender Ausführungszeit noch in C formulieren kann.

Bleibt noch offen, ob Dir die teilweise nur 16 Bit breiten Zähler im F411 auch reichen. Diese per Software zu vergößern könnte wegen up/down-Richtungswechsel heikel werden. Packt man die Zähler in einen kl. AVR sind 32 Bit kein Problem, der Zugriff per IIC dauert aber deutlich länger.

#7426336
Lesenswert?

Mi N. schrieb:

Die war aber sehr klein, weshalb ein Test entfallen mußte

Folglich werden in Zeile 21 noch + und - Flanken erkannt. Das muß noch angepaßt werden, erhöht die Laufzeit aber nur minimal.

Ja. Aber man sollte nicht nur die Abtastung in der Schleife machen, auch den alten Wert kopieren. Eher so.

1
  while(1) {
2
    do {
3
      alt_step = temp;
4
      temp = PINB;
5
    } while( temp & ~alt_step & BIT(STEP) );  // auf +Flanke von STEP warten

Klar, wenn man vor weiß, da STEP auf LOW ist, muss man nur prüfen, ob es jetzt HIGH ist. Geht einfacher und schneller, erst recht in ASM. Aber bleibt das Problem, daß man DIR zur richtigen Zeit abtasten muss, um es dann auszuwerten. Naja, da hier noch Luft ist, sollte man es mit der Microoptimierung nicht übertreiben und eher auf Nummer sicher gehen.

Beitrag #7426339 wurde von einem Moderator gelöscht.
OP #7426389
Lesenswert?

Mi N. schrieb:

Bleibt noch offen, ob Dir die teilweise nur 16 Bit breiten Zähler im F411 auch reichen. Diese per Software zu vergößern könnte wegen up/down-Richtungswechsel heikel werden.

Das hab ich bereits per Overrun/Underrun Interrupt gelöst, funktioniert einwandfrei.

Falk B. schrieb:

Hier mal als ASM. Kann man kaum schneller machen.

Danke, kann ich ev. gebrauchen.

Walter T. schrieb:

Geht es nur ums Mitschreiben, oder sollen die Signale im STM32F411 erzeugt werden?

Der STM32F411 muss (soll ;-) ) folgendes machen: 5x Step/Dir Signale einlesen ---> Im Hauptprogramm werden diese Werte verrechnet , dh. es wird die Nullpunktverschiebung der X,Y u. Z Achse in Bezug auf die Drehwinkel der A- u. C-Achse berechnet (nennt man TCPM oder RTCP ) Daraus resultierend werden dann wieder STEP/DIR Signale für die 5 Endstufen generiert und in (fast) Echtzeit ausgegeben. Derzeit lese ich die 5x STEP/DIR Signale mittels Interrupt ein, das frisst aber zuviel an Ressourcen. Der Debugger von MikroE sagt mir dass er ca. 120 Takte braucht um in die ISR rein u. raus zu kommen. Deswegen muss das im Hintergrund ablaufen. Wenns eben nicht anders geht dann mit zus. AVR's od. Logic IC's über die quadratur Encoder Eingänge. Dann hab ich genug Zeit für die trigonometrischen Berechnungen frei.

#7426439
Lesenswert?

Wenn's nur ein Kanal wäre, könnte man STEP auf zwei Timer geben, einen davon im gated mode mit DIR. Mit ein wenig Mathematik kann dann der gewünschte Wert berechnet werden. Beim Auslesen muß man aufpassen, daß nicht ein STEP dazwischenfunkt, z.B. indem man in einer Schleife Zähler A, B und wieder A ausliest, bis man zweimal denselben Wert für Zähler A liest.

Leider ist das nicht auf 5 Kanäle skalierbar, weil das Routing für die Zählereingänge doch arg beschränkt ist und die STM32F4-Serie eh nur 8 Zähler hat.

#7426484
Lesenswert?

Gerhard H. schrieb:

Der Debugger von MikroE sagt mir dass er ca. 120 Takte braucht um in die ISR rein u. raus zu kommen.

Das klingt viel, aber weniger als die Hälfte wird es wohl nicht. Sind da die 24 Takte, um die ISR zu starten und zu verlassen schon dabei?

Sind alle Eingänge an einem Port, daß Du die Dekodierung direkt parallel mit allen Pins gleichzeitig in einem Datenwort machen kannst?

#7426486
Lesenswert?

Walter T. schrieb:

Sind alle Eingänge an einem Port, daß Du die Dekodierung direkt parallel mit allen Pins gleichzeitig in einem Datenwort machen kannst?

Unsinn. Es gibt eine solide Lösung mit externer Hardware. Da muss man keine Handstände und Krampfaktionen in der Software machen und kann die CPU zu 100% mit sinnvollen Aufgaben auslasten. Problem gelöst.

OP #7426487
Lesenswert?

Hallo,

hab mal einen Arduino Nano mit Bascom/ASM programmiert. Der soll die 5 Stp/Dir Kanäle einlesen und Quadrature Signale ausgeben. Läuft am Simulator , kann aber erst heute abend testen.

1
$regfile = "m328pdef.dat"
2
$crystal = 16000000                               '16Mhz Quarz
3
$hwstack = 100 : $swstack = 200 : $framesize = 200
4

5
'-----------------------------------------------------------
6
'
7
'                          ___________
8
' C-out A      TXD    D1 -|           |-      V_IN
9
' C-out B      RXD    D0 -|   o o o   |-      GND
10
'              Reset  C6 -|   - o +   |- C6   Reset
11
'              GND       -|           |-      5V  out
12
' X-Step       INT0   D2 -|  Arduino  |-
13
' Y-Step       INT1   D3 -|           |-
14
' Z-Step       T0     D4 -|     N     |- C5   Z-out B
15
' A-Step       T1     D5 -|     A     |- C4   Z-out A
16
' C-Dir               D6 -|     N     |- C3   Y-out B
17
' C-Step              D7 -|     O     |- C2   Y-out A
18
' X-Dir               B0 -|           |- C1   X-out B
19
' Y-Dir               B1 -|           |- C0   X-out A
20
' Z-Dir               B2 -|    ___    |-
21
' A-Dir               B3 -|   |   |   |-      3v3 out
22
' A-out A             B4 -|   |   |   |- B5   A-out B  onboardLED
23
'                          -----------
24
'
25
'-------------------------------------------------------------------------------
26

27
Config Portb = &B1111_1111                        ' alle Pins output
28
Config Portc = &B0011_0000                        ' 4+5 output , Rest input
29
Config Portd = &B0000_0011                        ' 0+1 output , Rest input
30

31
'--- Config Interrupts -------------------------------------
32

33
Config Int0 = Falling
34
On Int0 X_step Nosave
35
Enable Int0
36

37
Config Int1 = Falling
38
On Int1 Y_step Nosave
39
Enable Int1
40

41
Config Timer0 = Counter , Edge = Falling
42
On Timer0 Z_step Nosave
43
Enable Timer0
44

45
Config Timer1 = Counter , Edge = Falling
46
On Timer1 A_step Nosave
47
Enable Timer1
48

49

50
Config Aci = On , Compare = On , Trigger = Falling
51
Acsr.acbg = 1                                     ' Int.Ref
52
On Aci C_step Nosave
53
Enable Aci
54

55
Enable Interrupts
56

57
Portb = 0
58
Timer0 = 255
59
Timer1 = 65535
60

61
$asm
62
ldi r28,&B00000001                                '1
63
ldi r29,&B00000100                                '4
64
ldi r30,&B00010000                                '16
65
ldi r31,&B01000000                                '64
66
SER R26                                           '256
67
$end Asm
68

69
' --- Do - Loop   ------------------------------------------
70
Do
71
Loop
72
End
73

74
' --- INTERRUPTS  ------------------------------------------
75

76
X_step:
77
$asm
78
in r8,SREG
79
sbic pinB , 0                                     'Dir Pin
80
Subi R16 , 2                                      '-2
81
add r16,r28                                       '+1
82
mov r17,r16                                       'copy
83
ANDI r17, &B00000011                              'bit 0 und 1 isolieren
84
sbrc r17,1
85
eor r17,r28                                       'unteres Bit umdrehen wenn oberes Bit 1
86
in r27 , portC
87
ANDI r27, &B11111100                              'output Register isolieren
88
add r27 , r17                                     'bit 0 u 1 out
89
Out Portc , R27
90
Out Sreg , R8
91
$end Asm
92
Return
93

94
Y_step:
95
$asm
96
in r8,SREG
97
sbic pinB , 1                                     'Dir Pin
98
Subi R18 , 8                                      '-8
99
add r18,r29                                       '+4
100
mov r19,r18                                       'copy
101
ANDI r19, &B00001100                              'bit 2 und 3 isolieren
102
sbrc r19,3
103
eor r19,r29                                       'unteres Bit umdrehen wenn oberes Bit 1
104
in r27 , portC
105
ANDI r27, &B11110011                              'output Register isolieren
106
add r27 , r19                                     'bit 2 u 3 out
107
Out Portc , R27
108
Out Sreg , R8
109
$end Asm
110
Return
111

112
Z_step:
113
$asm
114
in r8,SREG
115
Out Tcnt0 , R26                                   'timer auf 255 setzen
116
sbic pinB , 2                                     'Dir Pin
117
Subi R20 , 32                                     '-32
118
add r20,r30                                       '+16
119
mov r21,r20                                       'copy
120
ANDI r21, &B00110000                              'bit 4 und 5 isolieren
121
sbrc r21,5
122
eor r21,r30                                       'unteres Bit umdrehen wenn oberes Bit 1
123
in r27 , portC
124
ANDI r27, &B11001111                              'output Register isolieren
125
add r27 , r21                                     'bit 4 u 5 out
126
Out Portc , R27
127
Out Sreg , R8
128
$end Asm
129
Return
130

131
A_step:
132
$asm
133
in r8,SREG
134
Out Tcnt1l , R26                                  'timerL auf 255 setzen
135
Out Tcnt1l , R26                                  'timerH auf 255 setzen
136
sbic pinB , 3                                     'Dir Pin
137
Subi R22 , 32                                     '-32
138
add r22,r30                                       '+16
139
mov r23,r22                                       'copy
140
ANDI r23, &B00110000                              'bit 4 und 5 isolieren
141
sbrc r23,5
142
eor r23,r30                                       'unteres Bit umdrehen wenn oberes Bit 1
143
in r27 , portB
144
ANDI r27, &B11001111                              'output Register isolieren
145
add r27 , r23                                     'bit 4 u 5 out
146
Out Portb , R27
147
Out Sreg , R8
148
$end Asm
149
Return
150

151
C_step:
152
$asm
153
in r8,SREG
154
sbic pinD , 6                                     'Dir Pin
155
Subi R24 , 2                                      '-2
156
add r24,r28                                       '+1
157
mov r25,r24                                       'copy
158
ANDI r25, &B00000011                              'bit 0 und 1 isolieren
159
sbrc r25,1
160
eor r25,r28                                       'unteres Bit umdrehen wenn oberes Bit 1
161
in r27 , portD
162
ANDI r27, &B11111100                              'output Register isolieren
163
add r27 , r25                                     'bit 0 u 1 out
164
Out Portd , R27
165
Out Sreg , R8
166
$end Asm
167
Return
#7426493
Lesenswert?

Wenn man Interesse hat, kann man das auch in einen CPLD packen, die gibt es ziemlich billig auf Ebay. Hier incl. Programmieradapter für unter 15 Euro!

https://www.ebay.de/itm/232684120955

Oder der hier, allerdings braucht man dann noch den Programmieradapter für XILINX.

https://www.ebay.de/itm/385453238900 https://www.ebay.de/itm/272374665838

Hier der XILINX Adapter, natürlich etwas teuer für die Einzelanwendung.

https://www.ebay.de/itm/272600102573

Hier die Billigversion, aber wer hat schon noch einen echten Parallelport am Computer?

https://www.ebay.de/itm/202022683374

Wenn du magst, kann ich dir so einen CPLD von XILINX programmieren, ich hab das Kabel und Know How hier. Altera kann ich nicht, hab kein Kabel dafür.

#7426494
Lesenswert?

Gerhard H. schrieb:

Hallo,

hab mal einen Arduino Nano mit Bascom/ASM programmiert.

Schau mal was dort oben steht! Längere Quelltexte als Anhang!

Der soll die 5 Stp/Dir Kanäle einlesen und Quadrature Signale ausgeben. Läuft am Simulator , kann aber erst heute abend testen.

Ohje, ASM im BASIC Compiler 8-0 Das ist alles deutlich langsamer als meine Version. Und wenn die Takte gleichzeitig kommen, wird es nochmal langsamer. Es reicht nicht, wenn es prinzipiell funktioniert, es muss auch SICHER bei maximaler Last funktionieren. Man kann vieles in Software machen, aber nicht alles.

#7426526
Lesenswert?

Gerhard H. schrieb:

hab mal einen Arduino Nano mit Bascom/ASM programmiert. Der soll die 5 Stp/Dir Kanäle einlesen und Quadrature Signale ausgeben.

Wir wissen nicht, welche Achsen zu welcher Zeit welche Ausgangssignale liefern. Vielleicht hast Du ja Glück und Deine Lösung reicht Dir aus. Mich wundert auch ein wenig, daß es zuvor allein per Software gelaufen ist. Selber würde ich die Lösung niemals in nur einen einzigen ATmega328 packen.

Gerhard H. schrieb:

Bleibt noch offen, ob Dir die teilweise nur 16 Bit breiten Zähler im F411 auch reichen. Diese per Software zu vergößern könnte wegen up/down-Richtungswechsel heikel werden.

Das hab ich bereits per Overrun/Underrun Interrupt gelöst, funktioniert einwandfrei.

Die F411 Timer arbeiten nicht alle gleich. Insbesondere werden die Interrupt-Flags eines Timers nicht immer über einen einzigen ISR-Vektor verarbeitet. Die NVIC-Priorität kann man passend einstellen, die ISR-Vektoren haben jedoch eine feste Priorität, was genau verkehrt herum sein kann. Weder kenne ich Deine Software noch möchte ich hier dramatisieren, daher nur dieser Hinweis. Wenn alles einwandfrei funktioniert, ist es gut. Und wenn es Aussetzer gibt, sind die sicherlich so selten, daß sie nur alle paar Stunden auftreten ;-)

#7426801
Lesenswert?

Das sollte doch für einen STM32 kein Problem sein. Interrupts für Überlauf und Unterlauf der Timer aktivieren. Interrupt für jedes Dir-Signal aktivieren und die Stepsignale an die Counter dran. Bei einem "dir-Interrupt" entsprechend die Richtung des Counters einstellen. Fertig. So oft ändert sich ja die Richtung nicht, so dass diese paar Interupts nicht ins Gewicht fallen.

OP #7427040
Lesenswert?

Gerald M. schrieb:

Bei einem "dir-Interrupt" entsprechend die Richtung des Counters einstellen. Fertig.

Werde ich auch mal probieren

Zino schrieb:

Wir wissen nicht, wieviele ns zwischen der Änderung von DIR und dem nächsten STEP minimal vergehen. Wir kennen nur den Abstand zwischen zwei gleichsinnigen STEP-Flanken.

Leider habe ich dazu auch keine Info , bzw. nicht die Mittel dies zu messen. Der step Impuls ist 12 ns breit. Wenn STEP und Dir gleichzeitig gesetzt werden und auf die fallende Flanke von STP getriggert wird (aktiv high) müsste das laufen.

#7427241
Lesenswert?

Gerald M. schrieb:

Das sollte doch für einen STM32 kein Problem sein. Interrupts für Überlauf und Unterlauf der Timer aktivieren. Interrupt für jedes Dir-Signal aktivieren und die Stepsignale an die Counter dran. Bei einem "dir-Interrupt" entsprechend die Richtung des Counters einstellen. Fertig. So oft ändert sich ja die Richtung nicht, so dass diese paar Interupts nicht ins Gewicht fallen.

Jetzt habe ich doch noch ins Datenblatt gesehen. Dort gibt es nur ein gemeinsames Flag UIF, was bei Über- und Unterlauf gesetzt wird. Die ISR muß daher noch nachsehen, was zu tun ist und hoffen, daß sich zwischendurch nichts verändert hat. Die Annahme, daß sich die Richtung nur eher selten ändert, ist mir zu optimistisch. Es kann ja alles so funktionieren, wie Du geschrieben hast, hängt aber doch von den (derzeit unbekannten) Eingangssignalen ab.

Timer 2 - 5 haben nur einen ISR-Vektor. Da kann man Richtungsumschaltung über einen CC-Interrupt auslösen und UIF nach Bedarf verwerten. Bei Timer 1 hat 'TIM1_UP_TIM10' höhere Priorität als 'TIM1_CC'. Hier kann es Probleme geben. Es kann sinnvoll sein, UIF durch ein CC-Flag zu ersetzen, um nur einen Vektor benutzen zu müssen. Wie oben geschrieben, gilt dies bei der Erweiterung von 16 Bit Timern auf 32 Bit - sofern notwendig.

@TO: Ich habe noch einen Vorschlag für Dich, die Zähler in einen externen ATtinyXX2 zu packen: http://mino-elektronik.de/mt12_iic/mt12_iic.htm#qcnt_tiny202 Anstelle der Eingänge PHA und PHB müßte man das Programm auf STEP/DIR anpassen. Vielleicht mache ich das noch selber.

#7427363
Lesenswert?

Zino schrieb:

Wir wissen nicht, wieviele ns zwischen der Änderung von DIR und dem nächsten STEP minimal vergehen.

Wir wissen, dass es sich um eine CNC-Fräße handelt. Die beschleunigt und bremst ab. Bei einer Richtungsumkehr wird normal einiges berechnet, so dass nicht beide Pulse gleichzeitig kommen.

Mi N. schrieb:

Die ISR muß daher noch nachsehen, was zu tun ist und hoffen, daß sich zwischendurch nichts verändert hat. Die Annahme, daß sich die Richtung nur eher selten ändert, ist mir zu optimistisch.

Das Nachsehen bei einem Überlauf von 5x 16-Bit Timern ist keine Zauberei. Selbst bei den genannten 250kHz passiert das nur wenige Male in der Sekunde. Ich habe mir den genannten Controller nicht genau angeschaut, viele bieten auch die Möglichkeit einen Timer als "Prescaler" zu nehmen. Vielleicht gibt es ja die Möglichkeit solch einen STM32 auszuwählen. Und die Richtungsumkehr kommt definitiv bei einer CNC Fräse nicht oft vor, weil das physikalisch nicht geht.

Mi N. schrieb:

Timer 2 - 5 haben nur einen ISR-Vektor.

Die Dir-Signale kommen natürlich an eigene Pins mit Interrupt und haben nichts mit den Countern zu tun, außer eben dass sie im Interrupt das Register eines Counter ändert um dle Zählrichtung umzudrehen.

Da bis 250kHz angegeben ist gehe ich außerdem von einem sehr hohen Mikrostepping aus. Da macht ein verschluckter Step nichts aus, da die Auflösung dann deutlich höher ist als die Genauigkeit der Fräse. Da sie außerdem genau so oft in die eine wie die andere Richtung fährt, gleichen sie sich aus (sofern das überhaupt vorkommt)

OP #7427470
Lesenswert?

Gerald M. schrieb:

Wie gesagt, der Überlauf selbst kommt maximal 10x pro Sekunde vor

Das ist leider nicht so. Theoretisch kann man auch im Überlaufbereich nur einige Takte hin und her pendeln, z.B. Abzeilen von sehr kleinen Flächen beim Fräsen, dan kommt der Überlauf hunderte wenn nicht gar tausende male pro Sekunde.

Gerald M. schrieb:

Da macht ein verschluckter Step nichts aus

Doch , auch ein verlorender Takt ist zuviel. Da ich die Genauen Werte in trigonometrischen Funktionen weiter verrechne muss da ALLES stimmen.

#7427487
Lesenswert?

Dann rück mal raus mit den Mikroschritten, der maximalen Beschleunigung und dem Ruck, wenn du die Achse mit 1KHz vorwärts und rückwärts fahren lässt.

Idealerweise gleich noch sagen wieviel Mikrometer ein Schritt entspricht.

Du sagst, du machst es aktuell mit Interrupts. Meine Variante ist deutlich besser (wenn es vorher geklappt hat reicht es definitiv) und lässt 98% der CPU Teit übrig für andere Aufgaben.

#7427606
Lesenswert?

Kurzes Rechenbeispiel: Schrittmotor maximale Drehzahl bevor das Drehmoment komplett abgefallen ist: 10U/s. Bei 200 Pulse pro Umdrehung sind das maximal 2000 Vollschritte pro Sekunde. Für 250kHz bräuchte man 128 Mikroschritte. Bei einer maximalen Geschwindigkeit der Fräse von 1500mm/min wäre ein Vollschritt also 25mm/s bei 2000 Vollschritten pro Sekunde bei etwa 12,5um. Ein verpasster Mikroschritt ist also irgendwo bei 100nm Fehler. Aus Erfahrung kann ich dir sagen, dass thermischer Drift, ungenaue Gewindesteigung und Spiel deutlich mehr Fehler verursachen. Ganz zu Schweigen davon, dass ein Schrittmotor solch eine Auflösung mechanisch nicht her gibt.

Von daher kann deine Fehlerbetrachtung maximal von akademischer Natur sein.

OP #7427652
Lesenswert?

Gerald M. schrieb:

Dann rück mal raus mit den Mikroschritten, der maximalen Beschleunigung und dem Ruck, wenn du die Achse mit 1KHz vorwärts und rückwärts fahren lässt.

Idealerweise gleich noch sagen wieviel Mikrometer ein Schritt entspricht.

für die derzeitigen Tests habe ich 1µm für einen Schritt eingestellt. 1000 Schritte = 1mm 250000 Schritte/s / 1000 = 250mm/s =15m/min Schub

Gerald M. schrieb:

Du sagst, du machst es aktuell mit Interrupts

Derzeitiger Stand: STEP/DIR zu A/B quadrature Wandler mittels AVR STM32: TIM2 u. TIM5 lesen quadrature direkt in 32bit counter register TIM1,TIM3 und TIM4 werden over-/underrun der 16bit counter mit interrupts in 32 bit Werte weitergegeben

Gerald M. schrieb:

Von daher kann deine Fehlerbetrachtung maximal von akademischer Natur sein.

Ich kenne die Thematik. Ich baue seit Jahrzehnten die verschiedensten Hobby-CNC Maschinen. Nun geht es aber um ganz andere Sachen. "TCPM" 5-Achs Maschinenkinematk Berechnung in Echtzeit. D.h. werden hier Takte verschluckt werden auch diese Berechnungen falsch sein. Nicht nur so wie bei einer normalen 3-achs Kinematik dass eine Achse ein paar Steps daneben steht. Daher muss das Lesen der Signale zu 1000% sicher funktionieren bevor ich mich den nächsten Themen dieses Projektes widme. Erste tests heute Nacht sehen sehr gut aus. Alle 5 Achsen mal ca. 20min auf "Vollgas" ein 5x CNC Programm laufen lassen. Zumindest 4 Achswerte konnte ich am LCD Display kontrollieren , TIM2,3,4,5 passten exakt. Stresstest Programm im over-/underrun Bereich der 3 16bit Timer werde ich ev. heute abend machen.

#7427680
Lesenswert?

Ja, das Problem, warum es keine Hardware Schnittstelle gibt, die automatisch Step und Dir Signale einliest ist, dass es ja nicht wie A/B ein Sensorsignal ist, sondern ein Steuersignal, was vom Prinzip her irgendwo bekannt sein muss. Wenn man das einlesen muss ist beim System etwas nicht richtig.

Es gibt verschiedene Varianten:

STM32 und Timer im Counter Mode, wie ich das geschrieben habe.

FPGA macht das problemlos

Umwandlung in A/B Signal. Hier gibt es bestimmt eine analoge Schaltung (A und B durch Flip Flops erzeugt (eins bei fallender das andere auf steigende Flanke). Das Dir Signal investiert ein Ausgabgssignal eines Flip Flops.

OP #7427688
Lesenswert?

Gerald M. schrieb:

Ja, das Problem, warum es keine Hardware Schnittstelle gibt, die automatisch Step und Dir Signale einliest ist, dass es ja nicht wie A/B ein Sensorsignal ist, sondern ein Steuersignal, was vom Prinzip her irgendwo bekannt sein muss. Wenn man das einlesen muss ist beim System etwas nicht richtig.

Ist aber eben bei Hobby-CNC PC-Steuerungen seit je her standard (Mach3, mach4, UCCNC, Benazan, .....)

Wandlung step/dir --> A/B sehe ich als erledigt , geht im AVR zuverlässig. over/underrun der 3 16bit counter muss ich noch weiter testen.

OP #7437765
Lesenswert?

Hallo,

vorerst einmal DANKE für die vielen Tipps die ich in diesem Thread erhalten habe.
Ich habe in letzter Zeit nun einige Varianten durch probiert, d.h. Stresstests mit verschiedenen G-Codes über mehrere Stunden Laufzeit bei max. speed. (380kHz an allen 5 Achsen)
Dabei wurde besonders darauf geachtet dass die benötigten Interrupts f. 16bit Timer- Über/Unterlauf und Richtungsumkehr alle gemeinsam angefordert wurden.
Hier meine Varianten u. Ergebnisse:
A:
5 externe AVR's mit dem Code von Falk.
stp/dir->AB quadrature -> STM32
Ergebnis: 1A; 0 Fehler an allen 5 Achsen über mehrere Stunden
B:
5 externe AVR's mit meinem Code (Int0).
stp/dir->AB quadrature -> STM32
Ergebnis: 1A; 0 Fehler an allen 5 Achsen über mehrere Stunden
C:
STEP Signale an STM32 Timer1-5
DIR Signale an Eingangpins mit Interrupts
Ergebnis: 2-5 Steps Fehler an verschiedenen Achsen über mehrere Stunden

Also stand fest , Variante A od. B wird verwendet.
Aber irgendwie ließ mich der Gedanke einfach nicht los
dass es direkt am STM32 auch laufen muss.
Also nochmal an den Tmer Registern stundenlang rumgebastelt bis ich eine Lösung hatte.
Hier die Timer Register Einstellung:

1
  RCC_APB1ENR.TIM2EN = 1              
2
  TIM2_CR1.EN = 0                    
3
  TIM2_CCMR1_Input.CC1S0 = 1         
4
  TIM2_CCMR1_Input.CC1S1 = 0        
5
  TIM2_CCMR1_Input.CC2S0 = 1        
6
  TIM2_CCMR1_Input.CC2S1 = 0        
7
  TIM2_CCER.CC1P = 1                
8
  TIM2_CCER.CC1NP= 1                
9
  TIM2_SMCR.SMS0 = 1                
10
  TIM2_SMCR.SMS1 = 0                
11
  TIM2_SMCR.SMS2 = 0               
12
  TIM2_ARR = 4294967295            
13
  TIM2_PSC = 0                     
14
  TIM2_CR1.EN = 1

Damit lässt sich ein STP/DIR Signal an den quadrature Eingängen einwandfrei lesen.
Der Timerwert muss noch durch 2 dividiert werden , aber damit kann ich leben.
Tests ,nur steigende od. fallende Flanke am STP Eingang zu verwenden,
funktionieren nicht.
Auch "TIMx_PSC = 1" funktioniert nicht da dieser Wert erst beim ersten Richtungswechsel , dh. Flankenwechsel am DIR Eingang gelesen wird.

BG Gerhard

#7450953
Lesenswert?

Falls mal jemand in der Zukunft ein ähnliches Problem hat, diesen Faden findet und warum auch immer die Lösung von Gerhard nicht verwenden kann oder will: Ich stieß beim Stöbern bei Digi-Key auf den LS7184N, der konvertiert von A/B nach STEP/DIR. Kostet deutlich mehr als ein ATtiny o.ä. und ist ein Marktplatzangebot (wohl direkt vom Hersteller), dafür muß er nicht programmiert werden.

#7464728
Lesenswert?

Ich weiß, ich bin eigentlich zu spät, aber würde nicht ein einfacher D-Flip-Flop pro Kanal reichen? Das wären dann 2,5 mal 74HC74 statt 5 AVRs.

Da der Encoder-Modus immer beide Flanken zählt, schaltet man den Flip-Flop als 1-Bit Prescaler für STEP (^Q auf D). Der 3-fach XOR ist in jedem der 5 Timer ja schon drin. Der muß alle 3 Signale (DIR, STEP und STEP/2) verbinden, und schon hat man den anderen Bit vom Gray-Code:

1
DIR  S  S/2 XOR
2
 0   0   0   0
3
 0   1   1   0
4
 0   0   1   1
5
 0   1   0   1
6
 0   0   0   0
7

8
 1   0   0   1
9
 1   1   1   1
10
 1   0   1   0
11
 1   1   0   0
12
 1   0   0   1

Mit TI1S=1 liegt der XOR-Ausgang an TI1. Jetzt muß STEP/2 noch auf CH2/TI2 liegen und mit SMS=001 nur TI2-Flanken gezählt werden.

Zur Sicherheit sollten die Signale gefiltert werden (IC1F und IC2F). Vor allem TI1, weil STEP/2 immer ganz kurz nach STEP schaltet (Verzögerung des Flip-Flops), und am XOR-Ausgang deswegen Gliches auftreten können. Zu jeder anderen Zeit dürfen DIR und TI1 feiern, was sie wollen. Daher sind diese Fälle auch nicht in der Tabelle oben drin.

Alle Angaben ohne Gewähr. Ich bin auf diesen Thread nur gerade zufällig gestoßen und habe nichts davon ausprobiert.

#7464886
Lesenswert?

Mi N. schrieb:

Die ISR muß daher noch nachsehen, was zu tun ist und hoffen, daß sich zwischendurch nichts verändert hat.

"hoffen" ist in der Software immer ein schlechtes Konzept. Das führt zu seltenen, scheinbar unerklärlichen Fehlern, die entsprechend übel zu debuggen sind. Im Fall eines Dir-Interrupts müsstest du einen Blick in die Zeitspezifikationen deiner Geber werfen. Vermutlich ist die Reaktion auf den Interrupt so langsam, dass dein Hardwarezähler noch einen Puls mit der alten, falschen Richtung zählt, bevor die Interruptroutine so weit ist, dass sie die Richtung umschalten kann. Da müsste der Zählerstand dann korrigiert werden. Zur Kontrolle ist es sicher gut, in der ISR das Dir-Signal noch einmal einzulesen und zu prüfen. Da kommt es auch drauf an, wie sauber die Signale von deinen Gebern kommen.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren