Programmierung der Schrittmotorsteuerung „SM1“
(PT_PIESA, Teilprojekt A2)
Zusammengekürzt auf Relevanz für OWIS-Schiebetisch
Steuerung
- Serielle Schnittstelle: 38400-8-n-1, globales TimeOut bei 200 ms, kein oder Hardware-Handshake
- Anschlussbelegung: Siehe „sm.wmf“
- Zum Anschluss an einen PC genügt ein 3-adriges, 9-poliges Verlängerungskabel.
- Binärkommandos, erspart
printf()
/scanf()
in Firmware
Schnittstellen-Kommandos
- Die Fernbedienung erfolgt mit den folgenden Steuerzeichen.
- Alle Mehr-Byte-Binärzahlen sind Little-Endian (LSB zuerst) und vzb. Integerzahlen.
- Alle Strukturen sind auf 8-Byte-Grenzen ausgerichtet, ausgenommen der Kopf der Mehrbyte-Kommandos.
- Die Motorsteuerung sendet niemals von sich aus Daten.
- Hier nicht genannte Steuerkodes sind reserviert und tabu.
Einzelbyte-Kommandos
PC OUT | PC IN | Funktion
|
---|
0 | - | wird ignoriert, kann zur Synchronisation nach Kommunikationsverlust gesendet werden
|
'#' ♣ | '#' | Echo-Prüfung (kurzer Anwesenheitstest der Motorsteuerung)
|
'%' | 4 Byte | Mikrocontroller-Auslastung abfragen und Min/Max rücksetzen, Load::
1 Byte Minimum-Load (hier ca. 20 = 0%, aber 0 = 0% kann man getrost annehmen) Min
1 Byte Maximum-Load (0xFF = 100%) Max
2 Byte gleitender Load-Mittelwert (0xFF00 = 100%) Avg
|
'$' ♣ | '$' | Warten bis alle Achsen stehen oder bis EEPROM-Schreibvorgang beendet
Hierzu ggf. TimeOut der seriellen Schnittstelle temporär erhöhen.
Andere Kommandos beenden diesen Wartemodus vorzeitig ohne '$'-Antwort.
Sollte kein Warten erforderlich sein (kein Motor in Bewegung und kein EEPROM-Schreibvorgang), erfolgt die '$'-Antwort unmittelbar.
|
'?' ♣ | "SM1" | zur Unterscheidung und Anwesenheitstest für die Anwendungssoftware
|
'D' | 8 Byte | Motorstruktur abfragen (schnell) (hier: für OWIS-Motor), Motor::
- 1 Byte Zustand phase
HUNTBit 0 | Zielfahrt-Modus | Diese Bits bestimmen die firmware-interne State-Machine
| REFFBit 1 | Referenzfahrt-Modus
| BRAKEBit 2 | Bremsung aktiv
| SLOWBit 3 | Langsame Referenzschaltersuche (3. Pass)
| FULLBit 4 | Motor bestromt | Diese Bits reflektieren den Zustand der Motor-Endstufen
| PHABit 7-5 | Phasenlage | | | | | | |
- 1 Byte vzb. Beschleunigung (max. ±64), in Mikroschritt/125²µs² * 2^ea (zz. ea=-9) accel
- 2 Byte vzb. Geschwindigkeit (max. ±512) in Mikroschritt/125µs speed
- 4 Byte vzb. Mikroschritt-Position Ist
256 Mikroschritte sind 1 Halbschritt
|
'c' ♣ | - | Stopp für alle Achsen (für alle Motoren)
|
'f' ♣ | - | Nullpunkt setzen
- Setzt Position zu Null.
- Setzt Referenzierung (REF-Bit).
- Bei vorher vorhandener Referenzierung werden auch die Software-Endschalter
Anfang und Ende im RAM verschoben.
|
't' ♣ | - | Referenzierung aufheben (löscht REF-Bit)
|
♣ Kann man sinnvoll in HyperTerminal oder anderem Terminalprogramm verwenden
Mehrbyte-Kommandos (RAM, flüchtig)
Mehrbyte-Kommandos haben im Kommandobyte Bit 7 gesetzt.
Danach folgt die Nutzdaten-Länge in Bytes, danach die Nutzdaten.
PC OUT | PC IN | Funktion
|
---|
0x83 länge Daten | - | Sollposition setzen und Zielfahrt/Referenzfahrt ausführen Command::
länge = 1..16 (typisch 1 oder 8)
- 1 Byte Kommando cmd
Mögliche (sinnvoll erscheinende) Kombinationen
- 1 = Zielfahrt absolut
- 5 = Zielfahrt relativ
- 2 = Referenzfahrt in Normalrichtung (wie im EEPROM festgelegt: zum Motor hin)
- 6 = Referenzfahrt in Gegenrichtung (vom Motor weg)
Falls AZ gelöscht, steht nach Abschluss der Referenzfahrt in Soll
die Referenzabweichung in Mikroschritt.
Falls AZ gesetzt, wird anschließend zur Nullposition gefahren.
Wirksame Bits in cmd:
HUNTBit 0 | Zielfahrt starten
| REFFBit 1 | Referenzfahrt starten
| RIGHTBit 2 | Schaltersuche umschalten / REL relative Positionsangabe für Zielfahrt
| SLOWBit 3 | Schleichfahrt (sonst automatisch erst schnell, dann langsam) | | | | |
- 1 Byte vzl. Maximalbeschleunigung MaxAccel, 0 = Maximum aus EEPROM, CNAN = vorhergehender Wert
- 2 Byte vzl. Maximalgeschwindigkeit MaxSpeed, in Mikroschritt/125µs, 0 = Maximum aus EEPROM, INAN = vorhergehender Wert
- 4 Byte Zielposition Soll, in Mikroschritt◊, oder explizite Referenzfahrtrichtung (negativ ist normal!), LNAN = vorhergehender Wert
+∞ fährt bis zum positiven Limit
–∞ fährt bis zum negativen Limit
- 4 Byte Lage des linksseitigen Software-Endschalters Anfang, in Mikroschritt◊, LNAN = vorhergehender Wert
- 4 Byte Lage des rechtsseitigen Software-Endschalters Ende, in Mikroschritt◊, LNAN = vorhergehender Wert
|
0x8B länge Daten | - | Limits oder Flags setzen
länge = 1..24
- Erstes Byte flags (wird automatisch im EEPROM gespeichert):
LEFTBit 0 | Motor dreht andersherum (bspw. sinnvoll wenn eine Phase vertauscht wurde)
| REFBit 1 | Motor referenziert, Software-Endschalter wirksam
| RIGHTBit 2 | Schaltersuche nach rechts (zum Ende hin)
| MANUBit 3 | Niemals Referenzfahrt; Kommando setzt Referenzposition an aktueller Stelle
| HOLDBit 4 | Motoren dauerhaft bestromt (mit verringertem Haltestrom)
| ROTABit 5 | umlaufender Antrieb ohne Software-Endschalter, Software-Endschalter geben Periode vor (von Anfang bis Ende-1)
| DEMOBit 6 | Demo-Modus (ungenutzt!)
| AZBit 7 | Nach Referenzfahrt zur Null eilen
Wenn nicht gesetzt, steht nach der Referenzfahrt in Soll die Abweichung von der letzten Referenzfahrt. | | | | | | | | |
- weiter wie oben, Folgebytes werden nicht im EEPROM gespeichert
|
0x93 2 offset länge | <länge> | Motor-Struktur abfragen (komplett) (Strukturlänge 32 Bytes, Quelltext: class Motor)
offset = 0..31
offset+länge ≤ 32
Damit können alle variablen Infos abgefragt werden.
Die Daten liegen hintereinander:
- wie bei Kommando 'D' (8 Bytes)
- wie bei Kommando 0x8B (16 Bytes)
- danach 8 Bytes, die weniger interessant und zumeist funktionslos sind
- 2 Byte Pilgerschritt (0) Pilger
- 1 Byte Ruck (0) Jolt
- 1 Byte Endschalter-Zuordnung endsw
- Bit 0 = Endschalter motornah vorhanden (1)
- Bit 1 = Endschalter motorfern vorhanden (1)
- Bit 2 = Referenzschalter vorhanden (0)
- Bit 3 = Endschalter motornah/motorfern vertauscht (0)
- Bit 4 = Endschalter mit invertiertem Signal (0)
- 2 Byte weitere Flags (0) fl2 fl3
- 1 Byte PowerDownCounter (0) pdc
- 1 Byte Einzelbeschleunigungskommando (0) OneAccel
Mittels offset und länge kann ein beliebiger Ausschnitt der 32-Byte-Motordaten gelesen werden,
um den Datenverkehr auf der RS232-Schnittstelle zu minimieren.
|
◊ Die niederwertigen 8 Bits werden von der Firmware auf Null gesetzt.
Die angegebenen Konstanten sind wie folgt festgelegt (NaN = Not-a-Number, keine Zahl):
- CNAN = 0x80 (char-NaN)
- INAN = 0x8000 (Integer-NaN)
- LNAN = 0x8000000 (LongInt-NaN)
- +∞ = 0x7FFFFFF
- –∞ = 0x8000001
Mehrbyte-Kommandos (EEPROM, persistent)
Diese Mehrbyte-Kommandos dienen zum Zugriff insbesondere auf den EEPROM,
der die persistenten Einstellungsdaten speichert.
Damit kann PC-Steuersoftware in gewissen Grenzen plug-and-play-fähig
gemacht werden, da diese steuerungsspezifische Daten wie Spindelsteigung
aus dem EEPROM entnehmen kann.
PC OUT | PC IN | Funktion
|
---|
0xA0 4 adrL adrH 0x81 ♠ länge | länge Nutzdaten |
EEPROM lesen
adrH:adrL = Adresse (high:low)
|
0xA1 länge adrL adrH 0x81 ♠ Nutzdaten | - |
EEPROM schreiben
länge = 4..255
adrH:adrL = Adresse (high:low)
länge-3 Bytes Nutzdaten
|
♠ Dies entspricht der Linkerskript-Vorgabe des AVR-GCC.
EEPROM-Inhalt
Der EEPROM enthält Konfigurationsinformation in der folgenden Form:
8 Byte Header ab EEPROM-Adresse 0:
|
Adresse | Name | Länge | Inhalt | Beschreibung
|
---|
0 | fv2 | 8000 | Berechnungsschritte pro Sekunde für v (8 kHz)
| 2 | ea1 | -9 | Exponent zur Basis 2 für a (64 kHz² als Basis)
| 3 | xs1 | 8 | Irrelevante Bits für Positionsangabe (hier: Halbschritt)
| 4 | le1 | ≈20 | Ausgabewert für Load = 0 % (siehe Kommando '%')
| 5 | lf1 | 255 | Ausgabewert für Load = 100 % (siehe Kommando '%')
| 6 | bd1 | 0x19 | Baudrate gemäß Baudrate.htm
| 7 | nm1 | 0x46 | 6 Motor-Achsen (Low-Nibble) à 48 Byte,
4 (High-Nibble) — für koordinierte Steuerung
| | | | | | | |
Die Angaben fv und ea sind zur Einheitenumrechnung bei Geschwindigkeit und Beschleunigung erforderlich, siehe LabVIEW-Beispiel!
Die Angabe xs dient zum Ausblenden von Bits beim Auslesen und Anzeigen des Istwertes.
Die Angabe nm ist zur Berechnung von EEPROM-Offsets heranzuziehen!
Es folgen:
6 × 48 Byte Motordaten ab EEPROM-Adresse 8 (Quelltext: struct EeMotor):
|
Offset | Name | Länge | Inhalt | Beschreibung
|
---|
0 | Ist4 | 0 | Position zurzeit (wird häufiger geschrieben)
| 4 | flags1 | 0 | Nichtflüchtige Bits
0 = LEFTPhasenumkehr der Motorbestromung
| 1 = REFPosition referenziert
| 2 = RIGHTDefault-Referenzschaltersuche zur Motorferne
| 3 = MANUNiemals Referenzfahrt, sondern Null-Setzung
| 4 = HOLDDauer-Bestromung des Motors
| 5 = ROTAUmlaufender Antrieb ohne Endlagen
| 6 = PILG¿Pilgern, sonst Spielausgleich
| 7 = AZZielfahrt nach Null nach Referenzfahrt | | | | | | | | |
| 5 | MaxAccel1 | 64 | Maximale Beschleunigung
| 6 | MaxSpeed2 | 128 | Maximal erlaubte Verfahrgeschwindigkeit
| 8 | RefPos4 | 0 | Position des Referenzschalters ‡
| 12 | Anfang4 | –∞ | Software-Endschalter links †
| 16 | Ende4 | +∞ | Software-Endschalter rechts †
| 20 | Pilger2 | 0 | Pilgerschritte oder Spiel, vzb., max. ±127 Halbschritte
| 22 | Jolt1 | 0 | (Maximaler) Ruck, 0 = ohne Ruckbegrenzung
| 23 | endsw1 | 3 | Endschalter-Zuweisung, Bits:
0 = Endschalter motornah vorhanden
| 1 = Endschalter motorfern vorhanden
| 2 = Referenzschalter vorhanden (gleiche Leitung wie „motornah“)
| 3 = Endschalter-Leitungen motornah/motorfern vertauscht
| 4 = Endschalter mit invertiertem Signal (Schließer) |
| 24 | fl21 | 0 | weitere Flags (vorgesehene Verbote)
4 = DEMO¿ungenutzt
| 5 = F2AR¿Automatisch Referenzfahrt beim Einschalten
| 6 = F2RR¿Keine Bewegung ohne Referennz
| 7 = F2RV¿Referenzverlust beim Einschalten | | | | |
| 25 | fl31 | 0 | unbestimmt
| 26 | Current1 | ≈50 | Strom durch Motorwicklung, in 20 mA (einstellbar ab SM3, sonst nur Anzeigegröße)
| 27 | Curve1 | 0 | Kurvenform der Sinusinterpolation (mikroschrittfähiges SM3+)
| 28 | PerUnit4 | 400L<<8 | Mikroschritt pro Einheit — nur für PC-Software (C: float, PASCAL: single)
| 32 | Unit8 | "mm" | Einheitenbezeichner in UTF-8 — nur für PC-Software
(nullterminiert oder nicht terminiert)
| 40 | FreeForApp8 | 0 | Handle o.ä. für Anwendungsprogramm
| | | | | | | | | | | | | | | | | |
- † darf ±∞ sein, wenn Hardware-Endschalter vorhanden, sonst nicht.
- NaN ist nicht erlaubt.
- ‡ darf sich auch außerhalb von Anfang und Ende befinden.
- NaN oder ±∞ ist nicht erlaubt.
- ¿ Nicht implementiert
Eine wichtige Angabe ist PerUnit,
welche zur Umrechnung der Mikroschritte in physikalische Einheiten heranzuziehen ist,
sowie Unit zur Anzeige der passenden Einheit.
Somit ist Position/Unit = Position/µSchritt / PerUnit
, somit zum Anzeigen der
- Istposition:
printf("%.*f %s", nkx, Ist/PerUnit, Unit)
- Geschwindigkeit:
printf("%.*f %s/s", nkv, speed/PerUnit*fv, Unit)
- Beschleunigung:
printf("%.*f %s/s²", nka, accel/PerUnit*fa, Unit)
mit double fa = ldexp(fv*fv,ea)
(steuerungsspezifische Konstante, hier 244.140625
).
Die Ausgabezeichenkette ist UTF-8-kodiert
und muss ggf. für das Betriebssystem umgewandelt werden.
Für Windows typischerweise mittels MultiByteToWideChar()
.
Tipp: Die Anzahl der anzuzeigenden Nachkommastellen errechnen sich zu:
- Hilfsvariable
double u = fabs(PerUnit)
- für Positionsangaben:
nkx = (int)ceil(log10(ldexp(u,-xs)))
- für die Geschwindigkeit (pro Sekunde):
nkv = (int)ceil(log10(u/fv))
- für die Beschleunigung (/s²):
nka = (int)ceil(log10(ldexp(u/(fv*fv),ea)))
Anmerkung: Für den OWIS-Schiebetisch liegt die passende Struktur ab EEPROM-Adresse 152 (0x98) = 8 + 3 * 48.
Es folgen:
6 × ?? Bytes Motor-Achsbezeichnung (nullterminierte UTF-8-Strings)
(an vierter Position "OWIS-Lineartisch\0")
|
In LabVIEW exisitert für die Binär-Interpretation des seriellen Datenstroms
eine passende Komponente: Daten serialisieren / deserialisieren.