OmegaSim Wiki – die Idee dazu stammt von Gnen54. Hier stehen die offenen Artikel von Nutzer Luuke42 unter der Lizenz CC BY-SA 4.0.
Hexadezimalsystem
Stand dieses Artikels: OmegaSim 1.2.9 vom 26.10.2026 · Firmware des Autos: nicht bekannt (OmegaSim liest die Firmware-Version nicht aus)
Dieser Text wurde mithilfe von KI erstellt (Claude) und ist nicht in jedem Punkt von Menschen geprüft. Fehler bitte direkt verbessern oder auf der Diskussionsseite melden, siehe Mitmachen. Die öffentliche Fassung auf luuke42.github.io/omegasim kann älter sein als der hier beschriebene Stand.
Das Hexadezimalsystem (kurz Hex, von griechisch hexa „sechs“ und lateinisch decem „zehn“) ist ein Zahlensystem mit der Basis 16. Es verwendet die Ziffern 0 bis 9 und die Buchstaben A bis F für die Werte zehn bis fünfzehn. Programmierer benutzen es, weil eine Hex-Ziffer genau vier Bit darstellt und ein Byte deshalb immer mit genau zwei Hex-Ziffern geschrieben werden kann. In OmegaSim begegnet es überall dort, wo die App mit dem Carrera HYBRID spricht: Die Streckenteile melden sich mit Codes wie 0x01 oder 0x0A, jeder Fahrbefehl beginnt mit dem Byte 0xAF, und die Neutralstellung des Gases ist 0xDF. Dieser Artikel erklärt das System von Grund auf und zeigt an Beispielen aus dem Quellcode, wie OmegaSim damit rechnet.
Auf einen Blick
| Merkmal | Wert |
|---|---|
| Basis | 16 (dezimal: 10, binär: 2) |
| Ziffern | 0 1 2 3 4 5 6 7 8 9 A B C D E F |
| Schreibweisen | 0x0A (C, JavaScript, Java, Python), 0Ah (Assembler), #0A (Farben in HTML/CSS)
|
| Ziffern je Byte | genau 2 (00 bis FF, dezimal 0 bis 255)
|
| Wichtige Werte in OmegaSim | 0xAF Befehlskopf · 0xDF Gas neutral · 0x01 Start/Ziel · 0x02 Gerade · 0x0A Engstelle bzw. Start/Ziel auf Papier · 0x00 abseits · 0xFF noch nichts gelesen
|
| Übungsmöglichkeit in der App | Entwickler → Zahlensysteme (Binär- und Hex-Trainer, Status WIP, seit 0.7) |
| Beteiligte Quelldateien | src/20-protocol.js, src/10-ble-explorer.js, src/05-app-bruecke.js, src/60-track.js, src/90-ghosts.js, src/92b-num-trainer.js, OmegaBlePlugin.java
|
Grundlagen
Was ein Stellenwertsystem ist
Im Alltag schreiben wir Zahlen im Dezimalsystem: Jede Stelle ist zehnmal so viel wert wie die Stelle rechts von ihr. Die Zahl 223 bedeutet
223 = 2 × 100 + 2 × 10 + 3 × 1
= 2 × 10² + 2 × 10¹ + 3 × 10⁰
Die Zahl 10 heißt hier Basis. Man kann jede andere ganze Zahl ab 2 als Basis nehmen. Dann braucht man genau so viele verschiedene Ziffern, wie die Basis groß ist: im Dezimalsystem zehn (0–9), im Binärsystem (Basis 2) zwei (0 und 1), im Hexadezimalsystem (Basis 16) sechzehn. Weil es nur zehn arabische Ziffern gibt, nimmt man für die Werte zehn bis fünfzehn die Buchstaben A bis F.
Allgemein gilt für eine Ziffernfolge zn … z1 z0 zur Basis b:
Wert = z_n × b^n + … + z_1 × b^1 + z_0 × b^0
zi– die Ziffer an Stellei(von rechts, beginnend bei 0)b– die Basis (10, 2 oder 16)b^i– der Stellenwert, also „Basis hoch Stellennummer“
Bit, Nibble, Byte
- Ein Bit ist die kleinste Informationseinheit: 0 oder 1, aus oder an. Es ist eine Ziffer des Binärsystems.
- Ein Nibble (auch Halbbyte) sind 4 Bit. Mit 4 Bit lassen sich 24 = 16 verschiedene Werte darstellen, also genau die Werte einer Hex-Ziffer.
- Ein Byte sind 8 Bit, also zwei Nibble. Es kann 28 = 256 Werte annehmen, dezimal 0 bis 255, hexadezimal
00bisFF.
Die Bits eines Bytes werden von rechts nach links von 0 bis 7 nummeriert. Bit 0 ist das niederwertigste (Wert 1), Bit 7 das höchstwertige (Wert 128). Wenn in OmegaSim von „Byte 14, Bit 5“ die Rede ist, ist das Bit mit dem Wert 25 = 32 = 0x20 im fünfzehnten Byte gemeint (gezählt wird ab Byte 0).
Die Tabelle 0 bis 15
Diese Tabelle ist der Schlüssel zu allem Weiteren. Wer sie kann, kann jedes Byte im Kopf umrechnen.
| Dezimal | Binär (4 Bit) | Hex | Merkhilfe |
|---|---|---|---|
| 0 | 0000 | 0 | |
| 1 | 0001 | 1 | Bit 0 |
| 2 | 0010 | 2 | Bit 1 |
| 3 | 0011 | 3 | 2 + 1 |
| 4 | 0100 | 4 | Bit 2 |
| 5 | 0101 | 5 | 4 + 1 |
| 6 | 0110 | 6 | 4 + 2 |
| 7 | 0111 | 7 | 4 + 2 + 1 |
| 8 | 1000 | 8 | Bit 3 |
| 9 | 1001 | 9 | 8 + 1 |
| 10 | 1010 | A | 8 + 2 |
| 11 | 1011 | B | 8 + 2 + 1 |
| 12 | 1100 | C | 8 + 4 |
| 13 | 1101 | D | 8 + 4 + 1 |
| 14 | 1110 | E | 8 + 4 + 2 |
| 15 | 1111 | F | alle vier Bits |
Schreibweisen
Weil „10“ im Dezimalsystem zehn, im Hexadezimalsystem aber sechzehn bedeutet, muss man kennzeichnen, welches System gemeint ist:
0x0A– das Präfix0xstammt aus der Programmiersprache C und gilt auch in JavaScript, Java und Python. OmegaSim benutzt im Code ausschließlich diese Form (meist mit Kleinbuchstaben, etwa0xdf; Groß- und Kleinschreibung bedeuten dasselbe).0Ah– das nachgestelltehist in Assembler und in manchen Datenblättern üblich. Beginnt die Zahl mit einem Buchstaben, setzt man eine 0 davor (0DFh), damit sie nicht mit einem Namen verwechselt wird.#000000– in HTML und CSS werden Farben als drei Bytes (Rot, Grün, Blau) in Hex geschrieben. Die Dateimanifest.webmanifestvon OmegaSim legt so die Hintergrundfarbe Schwarz fest.0b00001010– das Präfix0bkennzeichnet Binärzahlen.- Ohne Präfix in Fließtext steht häufig „0A hex“ oder ein tiefgestelltes
0A16.
Damit gilt: 0x0A = 10 dezimal = 00001010 binär.
Warum Programmierer Hex benutzen
Der Computer rechnet binär. Binärzahlen sind aber lang und für Menschen fehleranfällig: 11011111 ist schwer zu lesen, und eine vertauschte Stelle fällt kaum auf. Dezimal (223) ist kurz, verbirgt aber die einzelnen Bits: Ob in 223 das Bit 5 gesetzt ist, sieht man der Zahl nicht an. Hex verbindet beide Vorteile:
- Kurz: Ein Byte sind immer genau zwei Zeichen. Ein 20-Byte-Befehl an das Auto passt in 40 Zeichen.
- Bitgenau: Jede Hex-Ziffer steht für genau ein Nibble.
0xDFzerfällt ohne Rechnen inD=1101undF=1111, also1101 1111. - Ausrichtung: Bitmasken wie
0x80(nur Bit 7),0x20(nur Bit 5) oder0x0F(die unteren vier Bit) sind auf einen Blick erkennbar.
Deshalb schreiben Protokollmitschnitte, Datenblätter, Speicheradressen, Farbwerte, Prüfsummen und Gerätekennungen fast immer Hex. Auch die Bluetooth-Kennungen (UUIDs) sind 128-Bit-Zahlen in Hex, und die Prüfsummen in app-update.json (SHA-256, 256 Bit) bestehen aus je 64 Hex-Ziffern, weil 256 / 4 = 64.
Bedienung
OmegaSim enthält einen kleinen Übungsbereich für Zahlensysteme (Status WIP):
- Optionen → System → Entwicklertools zeigen einschalten (oder
?devan die Adresse hängen). - Im Hauptmenü die Kachel Entwickler öffnen und dort Zahlensysteme wählen.
- Der Binär-Trainer zeigt eine vierstellige Binärzahl (0000 bis 1111, dezimal 0 bis 15), der Hex-Trainer eine vierstellige Hexzahl (0000 bis FFFF, dezimal 0 bis 65 535).
- Die Dezimalzahl in das Feld eintragen und Prüfen drücken (oder Eingabetaste).
- Die App meldet „Richtig!“ oder nennt den richtigen Wert und zählt mit („… von … richtig“).
- Mit Neue Zahl geht es weiter; eine zweite Antwort auf dieselbe Zahl wird nicht gezählt.
Die Zufallszahl entsteht als Math.floor(Math.random() × basis4) und wird mit toString(basis) in Großbuchstaben und auf vier Stellen mit führenden Nullen angezeigt.[1]
Wer Bytes am echten Auto sehen will, findet sie unter Entwickler → Code-Sonde (was der Sensor gerade liest) und im Protokoll der BLE-Werkbank, das jeden geschriebenen Befehl als Hex-Folge ausgibt.
Funktionsweise
Umrechnung dezimal → hexadezimal
Verfahren: fortgesetzt durch 16 teilen und die Reste von unten nach oben lesen.
223 : 16 = 13 Rest 15 → F (niedrigste Stelle) 13 : 16 = 0 Rest 13 → D Ergebnis von unten nach oben gelesen: DF → 223 = 0xDF
Zweites Beispiel, der Befehlskopf:
175 : 16 = 10 Rest 15 → F 10 : 16 = 0 Rest 10 → A Ergebnis: 0xAF
Umrechnung hexadezimal → dezimal
Jede Ziffer mit ihrem Stellenwert (160 = 1, 161 = 16, 162 = 256, 163 = 4096) malnehmen und addieren:
0xDF = 13 × 16 + 15 × 1 = 208 + 15 = 223
0xAF = 10 × 16 + 15 = 160 + 15 = 175
0x0A = 0 × 16 + 10 = 10
0x5E = 5 × 16 + 14 = 80 + 14 = 94
0x3F2A = 3 × 4096 + 15 × 256 + 2 × 16 + 10
= 12288 + 3840 + 32 + 10 = 16170
Die letzte Zeile ist die Beispielzahl, die auf der Kachel des Hex-Trainers abgebildet ist.
Umrechnung binär ↔ hexadezimal
Hier muss man nicht rechnen, nur gruppieren: Die Binärzahl von rechts in Vierergruppen teilen und jede Gruppe mit der Tabelle oben ersetzen.
1101 1111 → D F → 0xDF 1010 1111 → A F → 0xAF 0010 0000 → 2 0 → 0x20 (nur Bit 5) 1000 0010 → 8 2 → 0x82 (Bit 7 und Bit 1)
Umgekehrt wird jede Hex-Ziffer durch ihre vier Bits ersetzt.
Umrechnung binär → dezimal
Die Stellenwerte eines Bytes sind 128, 64, 32, 16, 8, 4, 2, 1. Man addiert die Werte der gesetzten Bits:
Bit: 7 6 5 4 3 2 1 0 Wert: 128 64 32 16 8 4 2 1 0xDF: 1 1 0 1 1 1 1 1 → 128+64+16+8+4+2+1 = 223 0x0A: 0 0 0 0 1 0 1 0 → 8+2 = 10
Bitmasken: einzelne Bits setzen, löschen, prüfen
Ein Byte kann mehrere unabhängige Schalter enthalten. Byte 14 des Fahrbefehls ist so ein Feld: Bit 0 schaltet das Bremslicht, Bit 1 den Scheinwerfer, Bit 5 die Leseart „Auf der Bahn“, Bit 7 die Leseart „Ausdruck“ (siehe Strecke). Im Code stehen dafür Konstanten:[2]
| Konstante | Hex | Binär | Bedeutung |
|---|---|---|---|
LIGHT_BRAKE |
0x01 |
0000 0001 | Bremslicht (Bit 0) |
LIGHT_HEAD |
0x02 |
0000 0010 | Scheinwerfer (Bit 1) |
TRACK_BIT_RAIL |
0x20 |
0010 0000 | Leseart „Auf der Bahn“ (Bit 5) |
TRACK_BIT_PRINT |
0x80 |
1000 0000 | Leseart „Ausdruck“ (Bit 7) |
Mit drei bitweisen Operatoren lässt sich jedes Bit einzeln bearbeiten:
| Operation | Operator | Wirkung | Beispiel |
|---|---|---|---|
| Setzen | a | m (ODER) |
jedes Bit, das in m 1 ist, wird 1 |
0x20 | 0x02 = 0x22 (Bahn + Scheinwerfer)
|
| Löschen | a & ~m (UND mit Umkehrung) |
jedes Bit, das in m 1 ist, wird 0 |
0x22 & ~0x02 = 0x20
|
| Prüfen | (a & m) !== 0 |
ist das Bit gesetzt? | (0x0C & 0x08) !== 0 ergibt wahr
|
Rechnung zum Löschen Bit für Bit:
~0x02 = 1111 1101 (0xFD, nach & 0xff) 0x22 = 0010 0010 0x22 & 0xFD = 0010 0000 = 0x20
Genau so maskiert OmegaSim defekte Lampen: Bei einem Schaden an der Front wird im Paket lb &= ~LIGHT_HEAD & 0xff gerechnet, abgesehen von kurzen Zuckungen eines simulierten Wackelkontakts.[3] Das Prüfen ist im Meldekanal üblich: (bytes[15] & 0x08) !== 0 fragt Bit 3 von Byte 15 ab, mit dem das Auto die Start/Ziel-Linie meldet.[4]
Überlauf und „& 0xFF“
Ein Byte kann nur 0 bis 255 aufnehmen. Rechnet man darüber hinaus, läuft es über: Nach 255 (0xFF) kommt wieder 0 (0x00), wie bei einem Kilometerzähler mit drei Stellen nach 999. Mathematisch ist das Rechnen modulo 256.
JavaScript kennt keine Bytes, sondern rechnet mit Kommazahlen; bei bitweisen Operatoren wandelt es in 32-Bit-Ganzzahlen. Der Ausdruck x & 0xFF behält nur die untersten 8 Bit und wirkt deshalb wie „modulo 256“, und zwar auch für negative Zahlen. In OmegaSim steht er an vielen Stellen.
Der Gaswert: 0xDF plus Ausschlag
Byte 6 des Fahrbefehls trägt das Gas nicht als 0 bis 255, sondern als Abstand von der Neutralstellung 0xDF (223):[5]
const throttleDelta = Math.max(MIN_THROTTLE_DELTA,
Math.min(127, Math.round(throttleFloat * 127)));
const throttleByte = (0xdf + throttleDelta) & 0xff;
throttleFloat– Gaswunsch von −1 (voll rückwärts) bis +1 (Vollgas)throttleDelta– derselbe Wunsch in Stufen, begrenzt auf −64 bis +127 (MIN_THROTTLE_DELTA = -64)throttleByte– das gesendete Byte
Bei Vollgas ist 0xDF + 127 = 223 + 127 = 350. Das passt nicht in ein Byte; 350 & 0xFF = 350 − 256 = 94 = 0x5E. Das Gas-Byte „läuft“ also beim Gasgeben über 0xFF hinaus und beginnt wieder bei 0x00. Eine Protokollbeschreibung von seVen nennt dazu die Bereiche 0xE0–0xFF und weiter 0x00–0x6F für vorwärts sowie 0x80–0xDE für rückwärts. Das erklärt eine alte Beobachtung: Der volle Rückwärtswert 0xDF − 127 = 0x60 liegt im Vorwärtsbereich, und genau dieser Wert ließ das Auto im Versuch vorwärts fahren. OmegaSim begrenzt Rückwärts deshalb auf −64 (0x9F); ob −95 (0x80) sicher ist, ist am Auto noch nicht gesichert.[6]
Der Kachelzähler: (neu − alt) & 0xFF
In jeder Meldung des Autos steht in Byte 11 ein Kachelzähler, der bei jedem neu befahrenen Streckenteil um eins steigt. Als Byte läuft er nach 255 auf 0 über. Wer wissen will, wie viele Teile zwischen zwei Meldungen lagen, rechnet deshalb nicht einfach neu − alt, sondern
schritte = (neu − alt) & 0xFF
alt– Zählerstand der früheren Meldung (0 bis 255)neu– Zählerstand der späteren Meldung (0 bis 255)schritte– Zahl der Teile dazwischen (0 bis 255)
So steht es etwa in der Ortung der NPCs (dort zusätzlich auf 1 bis 3 begrenzt) und in der Zählung des Anlaufs vor der ersten Runde.[7] Das Beispiel steht unten unter Beispiele.
Vorzeichen und Zweierkomplement
Ein Byte kann auch negative Zahlen tragen. Die übliche Regel heißt Zweierkomplement: Die Werte 0x00–0x7F bedeuten 0 bis 127, die Werte 0x80–0xFF bedeuten −128 bis −1. Umrechnung:
vorzeichenbehaftet = b ≥ 128 ? b − 256 : b
So steht es wörtlich in OmegaSim (function s8signed(b) { return b >= 128 ? b - 256 : b; }).[8] Umgekehrt wird aus einer negativen Zahl mit & 0xFF das passende Byte: −40 & 0xFF = 216 = 0xD8, und 216 − 256 = −40 führt zurück.
Die Lenkung in Byte 7 ist so ein vorzeichenbehaftetes Byte: steerByte = steerDelta & 0xff mit steerDelta von −127 bis +127. Positiv lenkt nach rechts, negativ nach links. Hier zeigt sich, warum die App den Ausschlag streng auf ±127 begrenzt: Ein Wunsch von 1,2 ergäbe 152, als Byte 0x98, und das liest das Auto als 152 − 256 = −104, also als kräftigen Einschlag in die andere Richtung.[9]
Auch Meldewerte des Autos werden so gelesen: Die Bytes 1 und 3 der Meldung (Bewegungssignale, die OmegaSim unter anderem für die Crash-Erkennung nutzt) werden mit s8signed() in −128 bis 127 umgerechnet.
Prüfsummen
Eine Prüfsumme ist eine kleine Zahl, die aus allen Bytes einer Nachricht berechnet und mitgeschickt wird. Der Empfänger rechnet dieselbe Zahl nach. Stimmen beide nicht überein, wurde die Nachricht unterwegs verfälscht (oder falsch gebaut) und wird verworfen.
Die einfachste Form ist die Summe aller Bytes modulo 256 oder ein XOR über alle Bytes. Solche Verfahren übersehen aber manche Fehler, zum Beispiel zwei vertauschte Bytes. Besser ist eine CRC (zyklische Redundanzprüfung): Die Nachricht wird als lange Binärzahl aufgefasst und durch ein festes Polynom geteilt; der Rest der Division ist die Prüfsumme. Die Division läuft ohne Überträge, Subtraktion ist dabei XOR.
Der Fahrbefehl an das Carrera HYBRID endet mit einer CRC-8 über die Bytes 0 bis 18, mit Polynom 0x31 und Startwert 0xFF:[10]
function crc8(bytes) {
let crc = 0xff;
for (const b of bytes) {
crc ^= b;
for (let i = 0; i < 8; i++) {
crc = (crc & 0x80) ? ((crc << 1) ^ 0x31) & 0xff : (crc << 1) & 0xff;
}
}
return crc;
}
crc– das laufende Register, ein Bytecrc ^= b– das nächste Nachrichtenbyte wird mit XOR eingemischtcrc & 0x80– ist das oberste Bit gesetzt?crc << 1– alle Bits eine Stelle nach links schieben (mal 2),& 0xffwirft das herausgeschobene Bit weg^ 0x31– wenn oben eine 1 herausfiel, das Polynom abziehen (XOR).0x31=0011 0001steht für x8 + x5 + x4 + 1; das x8 ist das herausgeschobene Bit und wird nicht mitgeschrieben.
Dass diese Deutung stimmt, ist belegt: Für drei aufgezeichnete Leerlaufpakete der Original-App mit Byte 14 = 0x80, 0x82 und 0x83 liefert crc8() genau die mitgeschnittenen Prüfsummen 0xA4, 0x33 und 0xE0.[11] Der Selbsttest „Protokoll: CRC-8“ prüft bei jedem Lauf den Fall 0x33.[12] Die Beschreibung von seVen nennt ein XOR über die Bytes 0 bis 18; das reproduziert die Mitschnitte nicht.
Weil das Auto Pakete mit falscher Prüfsumme vermutlich verwirft, rechnet OmegaSim die CRC immer zuletzt, nachdem alle Sonderbytes (Leitplanken-Modus, Versuchsvarianten der Byte-Werkbank) eingesetzt sind.
Hex als Text auf dem Weg zum Bluetooth
In der Android-App reisen die Befehle zwischen Webseite und Java-Code nicht als Bytes, sondern als Hex-Text, zum Beispiel "af0000000000df008000600001002004000000ef" (40 Zeichen für 20 Byte). Die Seite wandelt mit zuHex() jedes Byte in zwei Zeichen, das Plugin OmegaBle wandelt sie mit hexZuBytes() zurück:[13]
int hi = Character.digit(hex.charAt(i * 2), 16);
int lo = Character.digit(hex.charAt(i * 2 + 1), 16);
out[i] = (byte) ((hi << 4) | lo);
Für "df" ist hi = 13, lo = 15; 13 << 4 schiebt um vier Bit (mal 16) auf 208, | 15 setzt die unteren vier Bit, Ergebnis 223. Für den Rückweg (Meldungen des Autos) nutzt die Seite eine Nachschlagetabelle statt parseInt, weil rund 22 Meldungen je Sekunde und Auto durchlaufen.
Beispiele
Ein ganzer Fahrbefehl in Hex
Das Leerlaufpaket in der Leseart „Auf der Bahn“, ohne Licht, Gas und Lenkung neutral:
Byte: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 Hex: AF 00 00 00 00 00 DF 00 80 00 60 00 01 00 20 04 00 00 00 EF
AF(175) – BefehlskopfDF(223) – Gas neutral00– Lenkung gerade (Byte 7, Kopie in Byte 9)20(32, Bit 5) – Leseart „Auf der Bahn“EF– CRC-8 über die Bytes 0 bis 18
Schaltet man den Scheinwerfer ein, wird Byte 14 zu 0x20 | 0x02 = 0x22, und die Prüfsumme ändert sich von 0xEF auf 0x78. Ein einziges geändertes Bit ändert die ganze Prüfsumme; genau das soll eine CRC leisten. (Beide Prüfsummen sind mit der Funktion crc8() nachgerechnet.)
Die ersten Schritte der CRC von Hand
Startwert 0xFF, erstes Byte 0xAF:
| Schritt | Register vorher | oberstes Bit | Rechnung | Register nachher |
|---|---|---|---|---|
| Einmischen | FF |
– | FF XOR AF |
50 = 0101 0000
|
| 1 | 0101 0000 | 0 | nur schieben | 1010 0000 (A0)
|
| 2 | 1010 0000 | 1 | schieben, XOR 31 |
0111 0001 (71)
|
| 3 | 0111 0001 | 0 | nur schieben | 1110 0010 (E2)
|
| 4 | 1110 0010 | 1 | schieben, XOR 31 |
1111 0101 (F5)
|
| 5 | 1111 0101 | 1 | schieben, XOR 31 |
1101 1011 (DB)
|
| 6 | 1101 1011 | 1 | schieben, XOR 31 |
1000 0111 (87)
|
| 7 | 1000 0111 | 1 | schieben, XOR 31 |
0011 1111 (3F)
|
| 8 | 0011 1111 | 0 | nur schieben | 0111 1110 (7E)
|
Danach wird das nächste Byte (0x00) eingemischt, und so weiter bis Byte 18.
Gas in Stufen
| Wunsch | Ausschlag (Stufen) | Rechnung | Byte 6 |
|---|---|---|---|
| neutral | 0 | 223 + 0 | 0xDF
|
| ein Hauch Gas | +1 | 223 + 1 = 224 | 0xE0
|
| etwa ein Viertel | +32 | 223 + 32 = 255 | 0xFF
|
| halb | +64 | 287 − 256 = 31 | 0x1F
|
| Vollgas | +127 | 350 − 256 = 94 | 0x5E
|
| halb rückwärts (Grenze in OmegaSim) | −64 | 223 − 64 = 159 | 0x9F
|
| voll rückwärts (nicht gesendet) | −127 | 223 − 127 = 96 | 0x60, liegt im Vorwärtsbereich
|
Zurück rechnet die Prüfbank so: d = (b6 − 0xDF) & 0xFF, und ist d > 127, dann d − 256. Für 0x9F: (159 − 223) & 0xFF = −64 & 0xFF = 192, und 192 − 256 = −64.[14]
Kachelzähler über den Überlauf
Das Auto meldet zuletzt den Zählerstand 254 (0xFE), die nächste empfangene Meldung zeigt 2 (0x02), weil unter Funklast einige Meldungen verloren gingen.
neu − alt = 2 − 254 = −252 −252 & 0xFF = 4
Probe: 254 → 255 → 0 → 1 → 2 sind vier Schritte. Ohne & 0xFF käme −252 heraus, und eine Rundenzählung würde rückwärts laufen. Die Ortung der NPCs nimmt den Wert anschließend höchstens als 3, weil mehr Sprünge auf einmal eher eine Störung als echte Fahrt sind.
Streckencodes
Die Codes, die der Sensor in Byte 12 meldet, sind kleine Zahlen; Hex wird hier nur aus Gewohnheit geschrieben:
| Hex | Dezimal | Binär | Bedeutung (Leseart „Auf der Bahn“) |
|---|---|---|---|
0x00 |
0 | 0000 0000 | abseits der Bahn |
0x01 |
1 | 0000 0001 | Start/Ziel |
0x02 |
2 | 0000 0010 | Gerade |
0x03 / 0x04 |
3 / 4 | 0000 0011 / 0000 0100 | Kurve links / rechts |
0x05 / 0x06 |
5 / 6 | 0000 0101 / 0000 0110 | Haarnadel links / rechts |
0x0A |
10 | 0000 1010 | Engstelle (nur nach seVen) |
0xFF |
255 | 1111 1111 | noch nie ein Muster gelesen |
In der Leseart „Ausdruck“ bedeutet 0x0A dagegen Start/Ziel auf dem Original-Druckblatt. Deshalb zählt OmegaSim auf der Bahn nur 0x01 als Ziellinie, sonst würde jede Engstelle eine zusätzliche Runde zählen.[15] Einzelheiten stehen im Artikel Strecke.
Versionsnummer der APK
Der Bau der Android-App macht aus der Version 1.2.9 die ganzzahlige Versionsnummer 1 × 100000 + 2 × 1000 + 9 = 102009.[16] Das ist ein Stellenwertsystem mit gemischten Stellenwerten, aber kein Hex: Android verlangt eine wachsende ganze Zahl, und dezimale Blöcke bleiben für Menschen lesbar.
Grenzen und bekannte Probleme
- Der Hex-Trainer ist als WIP gekennzeichnet. Er übt nur die Richtung „fremdes System → dezimal“ und nur vierstellige Zahlen; Binärzahlen gehen damit nur bis 15.
- Wie viele Bits der Gaswert wirklich auflöst und wo genau die Grenze zwischen Vorwärts und Rückwärts liegt, ist nicht am Auto gemessen; die Grenze −64 ist eine sichere, beobachtete Stelle, −95 nur ein Vorschlag aus der seVen-Beschreibung.
- Ob das Auto Pakete mit falscher CRC verwirft oder anders behandelt, ist naheliegend, aber nicht eigens geprüft.
- Ein Kachelzähler-Sprung von mehr als 255 Teilen zwischen zwei Meldungen ist mit
& 0xFFnicht erkennbar; bei einer Meldung etwa alle 45 ms kommt das praktisch nicht vor.
Versionsgeschichte
| Version | Änderung |
|---|---|
| 0.7 | Neu in den Entwicklertools: Binär- und Hex-Trainer |
| August 2026 | Byte 14 als Licht- und Lesearten-Feld entschlüsselt; CRC-8 anhand von drei Mitschnitten bestätigt |
| 0.6.14 | Codetabellen je Leseart; 0x0A zählt auf der Bahn nicht mehr als Ziellinie
|
Einzelnachweise
- ↑
src/92b-num-trainer.js,numTrainerNeueZahl() - ↑
src/20-protocol.js, KonstantenLIGHT_HEAD,LIGHT_BRAKE,TRACK_BIT_RAIL,TRACK_BIT_PRINT - ↑
src/20-protocol.js,buildCommandPacket() - ↑
src/70-race.js,handleDashboardBytes(), KonstanteZIEL_SPERRE_BIT = 0x08 - ↑
src/20-protocol.js,buildCommandPacket() - ↑
CARRERA_HYBRID.md, Abschnitt „Die Rückwärtsgrenze“;src/10-ble-explorer.js, Kommentar zuMIN_THROTTLE_DELTA - ↑
src/90-ghosts.js(Ortung, „Byte 11 läuft über, also & 0xff“);src/70-race.js((dashLastTileCounter - raceAnlaufZaehler) & 0xff) - ↑
src/70-race.js,s8signed() - ↑
CARRERA_HYBRID.md, Abschnitt „Die Lenkgrenze“ - ↑
src/10-ble-explorer.js,crc8() - ↑
src/20-protocol.js, Kommentar „Byte 14: the light field“ - ↑
src/95-selftest.js, Test „Protokoll: CRC-8“ - ↑
src/05-app-bruecke.js,zuHex(),ausHex();OmegaBlePlugin.java,hexZuBytes() - ↑
src/93-testbench.js, HilfsfunktiongasVon - ↑
src/60-track.js,isStartCode() - ↑
.github/workflows/android.yml, Schritt „Version bestimmen“
Siehe auch
Quellen im Code
src/20-protocol.js–buildCommandPacket(), KonstantenLIGHT_HEAD,LIGHT_BRAKE,TRACK_BIT_RAIL,TRACK_BIT_PRINTsrc/10-ble-explorer.js–crc8(),MIN_THROTTLE_DELTAsrc/05-app-bruecke.js–zuHex(),ausHex(),uuid()src/60-track.js–isStartCode(),TILE_OFFTRACKsrc/70-race.js–s8signed(),handleDashboardBytes(),ZIEL_SPERRE_BITsrc/90-ghosts.js– Kachelzähler in der NPC-Ortungsrc/92b-num-trainer.js– Binär- und Hex-Trainersrc/95-selftest.js– Test „Protokoll: CRC-8“android-app/…/OmegaBlePlugin.java–hexZuBytes()CARRERA_HYBRID.md– Rückwärtsgrenze, Lenkgrenze, Abgleich mit seVen
Weblinks
- Browserfassung, Android-App und Quellcode: Links auf der Hauptseite