printf()
/scanf()
in Firmware
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::
| ||||||||||||||||||||
'c' ♣ | - | Stopp für alle Achsen (für alle Motoren) | ||||||||||||||||||||
'f' ♣ | - | Nullpunkt setzen
| ||||||||||||||||||||
't' ♣ | - | Referenzierung aufheben (löscht REF-Bit) |
♣ Kann man sinnvoll in HyperTerminal oder anderem Terminalprogramm verwenden
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)
| ||||||||||||||||||||||||
0x8B länge Daten | - | Limits oder Flags setzen
länge = 1..24
| ||||||||||||||||||||||||
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:
|
◊ Die niederwertigen 8 Bits werden von der Firmware auf Null gesetzt.
Die angegebenen Konstanten sind wie folgt festgelegt (NaN = Not-a-Number, keine Zahl):
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.
8 Byte Header ab EEPROM-Adresse 0: | ||||
Adresse | Name | Länge | Inhalt | Beschreibung |
---|---|---|---|---|
0 | fv | 2 | 8000 | Berechnungsschritte pro Sekunde für v (8 kHz) |
2 | ea | 1 | -9 | Exponent zur Basis 2 für a (64 kHz² als Basis) |
3 | xs | 1 | 8 | Irrelevante Bits für Positionsangabe (hier: Halbschritt) |
4 | le | 1 | ≈20 | Ausgabewert für Load = 0 % (siehe Kommando '%') |
5 | lf | 1 | 255 | Ausgabewert für Load = 100 % (siehe Kommando '%') |
6 | bd | 1 | 0x19 | Baudrate gemäß Baudrate.htm |
7 | nm | 1 | 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 | Ist | 4 | 0 | Position zurzeit (wird häufiger geschrieben) | ||||||||||||||||
4 | flags | 1 | 0 | Nichtflüchtige Bits
| ||||||||||||||||
5 | MaxAccel | 1 | 64 | Maximale Beschleunigung | ||||||||||||||||
6 | MaxSpeed | 2 | 128 | Maximal erlaubte Verfahrgeschwindigkeit | ||||||||||||||||
8 | RefPos | 4 | 0 | Position des Referenzschalters ‡ | ||||||||||||||||
12 | Anfang | 4 | –∞ | Software-Endschalter links † | ||||||||||||||||
16 | Ende | 4 | +∞ | Software-Endschalter rechts † | ||||||||||||||||
20 | Pilger | 2 | 0 | Pilgerschritte oder Spiel, vzb., max. ±127 Halbschritte | ||||||||||||||||
22 | Jolt | 1 | 0 | (Maximaler) Ruck, 0 = ohne Ruckbegrenzung | ||||||||||||||||
23 | endsw | 1 | 3 | Endschalter-Zuweisung, Bits:
| ||||||||||||||||
24 | fl2 | 1 | 0 | weitere Flags (vorgesehene Verbote)
| ||||||||||||||||
25 | fl3 | 1 | 0 | unbestimmt | ||||||||||||||||
26 | Current | 1 | ≈50 | Strom durch Motorwicklung, in 20 mA (einstellbar ab SM3, sonst nur Anzeigegröße) | ||||||||||||||||
27 | Curve | 1 | 0 | Kurvenform der Sinusinterpolation (mikroschrittfähiges SM3+) | ||||||||||||||||
28 | PerUnit | 4 | 400L<<8 | Mikroschritt pro Einheit — nur für PC-Software (C: float, PASCAL: single) | ||||||||||||||||
32 | Unit | 8 | "mm" | Einheitenbezeichner in UTF-8 — nur für PC-Software (nullterminiert oder nicht terminiert) | ||||||||||||||||
40 | FreeForApp | 8 | 0 | Handle o.ä. für Anwendungsprogramm |
Position/Unit = Position/µSchritt / PerUnit
, somit zum Anzeigen derprintf("%.*f %s", nkx, Ist/PerUnit, Unit)
printf("%.*f %s/s", nkv, speed/PerUnit*fv, Unit)
printf("%.*f %s/s²", nka, accel/PerUnit*fa, Unit)
double fa = ldexp(fv*fv,ea)
(steuerungsspezifische Konstante, hier 244.140625
).
MultiByteToWideChar()
.
Tipp: Die Anzahl der anzuzeigenden Nachkommastellen errechnen sich zu:
double u = fabs(PerUnit)
nkx = (int)ceil(log10(ldexp(u,-xs)))
nkv = (int)ceil(log10(u/fv))
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.