"Schreibende" Kommandos an die Control Unit senden

  • Hi Leute,


    Ich bastele ja an SmartRace, wie inzwischen wohl einige wissen. Jetzt ist meine aktuelle Herausforderung, "schreibende" Kommandos an die CU zu senden. Lesend greife ich ja bereits zu, um z.B. die Versionsnummer der Firmware oder die letzte Zieldurchfahrt bzw. den Status abzufragen. Jetzt will ich aber Parameter setzen wie Bremswirkung, Tankinhalt, etc.


    Ich weiß, dass es möglich ist und Schlaubi macht es in seiner App beispielsweise auch. Er hat mir aber schon mitgeteilt, dass er leider nicht bereit ist, mir zu helfen, da er uns als Konkurrenten sieht - finde ich schade, muss ich aber respektieren. Ich würde jedoch gerne die Software zum Nutzen derer, die sie schon gekauft haben, weiter verbessern und deshalb neue Funktionen einbauen.


    Deshalb meine Frage: Hat jemand irgendwelche Ansatzpunkte? Wie lautet die Syntax der Befehle? In welcher Reihenfolge muss was gesendet werden? Etc. etc. etc. - ich bin für jeden Hinweis dankbar. Die Seite vom Slotbären habe ich natürlich schon ausführlich studiert, aber bisher bei all meinen Experimenten keinen Erfolg. Das einzige, was ich zustande gebracht habe, war, dass die CU mein Senden eines "J" mit einem zweimaligen kurzen Blinken jeder Diode bestätigt hat (ähnlich wie wenn man etwas direkt über die CU eingestellt hat und es dann speichert).


    Also - schießt los! Alles hilft :)


    Liebe Grüße,
    Marc

  • Google Werbung
  • Hi Marc,
    bei slotbaer steht im Grunde alles, was du brauchst. Mitunter ist nicht jeder Schritt bis ins kleinste Detail ausgeführt (gewollt oder nicht), doch es ist auf alle Fälle ausreichend, um die ersten Gehversuche zu machen.
    Du nutzt doch Cockpit-XP... Dann horch doch einfach mal an der seriellen Schnittstelle. Hast du ein Programmierwort erkannt, dann schaue es dir ruhig Bit für Bit an und mit slotbaers Hilfe wirst du es sicherlich schnell selbst umsetzen können.


    Wenn du ein >"J< sendest, sollte zuerst ein >J< zurückkommen, dann sendest du deinen Programmierbefehl und wenn >$< geantwortet, ist alles ok.


    Cheers,
    René

  • Hi René,


    Danke für's Feedback. Ja, wie gesagt: Bei Slotbär kenne ich einige Sachen inzwischen auswendig und ohne die Seite wäre ich nicht mal ansatzweise soweit gekommen, wie ich schon bin. Ich habe auch schon echt viel experimentiert. Wie der Aufbau der Befehle ist, habe ich einigermaßen verstanden, allerdings fehlt mir noch die Brücke vom Binärcode zu dem, was dann tatsächlich an die CU übertragen wird (HEX-Codes?). Da stecke ich fest. Ganz zu schweigen von der Frage, ob die Kommunikation über AppConnect mit einer Prüfsumme efolgen muss oder nicht - bei den Lesebefehlen sendet die CU jedenfalls keine Prüfsumme mit, obwohl Slotbärs Doku das so sagt. Da sind viele unklare Dinge drin, die ich noch nicht wirklich entschlüsseln konnte...


    LG,
    Marc

  • Binär, Hex, Dezimal oder ASCII sind ja nur verschiedene Darstellungsformen eines Bytes. Das ändert ja nichts am Byte selbst.
    Wenn du es hinbekommen hast, die >"?< Antworten zu interpretieren, dann ist der Rest auch nicht mehr so weit.
    Ich habe zwar kein AppConnect sondern nur einen älteren BT-Chip, aber ich denke, die Prüfsumme müsste auch da gesendet werden. Mit der AppConnect kann man die CU updaten, vielleicht ist hier etwas in der Syntax geändert worden. Ich kann's nicht sagen.


    Nehmen wir mal Slotbaers Beispiel:
    ID = 5, Befehl = 6, Wert = 4, Wiederholung = 1


    macht...


    ASCII: 6:415$
    DEZ: 54 58 52 49 53 36
    HEX: 36 3A 34 31 35 24
    BIN: 00110110 00111010 00110100 00110001 00110101 00100100


    Die Hex Darstellung finde ich am einfachsten zu verstehen, gerade hinsichtlich oberes und unteres Nibble. ;)
    Du musst jetzt natürlich eine Funktion finden, die dir das Byte-Array erzeugt. Das hat Slotbaer ganz gut beschrieben.
    Hast du das, dann kannst du deine Kommunikation strukturieren.



    Du sendest also: "J
    wartest auf: J
    sendest: 6:415$ (oder eben was du setzen/ändern willst)
    wartest auf: $


    That's it.


    Cheers,
    René

  • Hi René,


    Danke für Deine Hilfe. Meine Lücke ist an der Stelle, die Du (und der Slotbär) einfach als selbstverständlich anseht, weshalb ich glaube, dass ich einfach was total offensichtliches übersehe oder (noch) nicht kapiere. Du schreibst Befehl 6, Fahrzeug 5, Wert 4, Wiederholung 1 gibt:


    ASCII: 6:415$
    DEZ: 54 58 52 49 53 36
    HEX: 36 3A 34 31 35 24
    BIN: 00110110 00111010 00110100 00110001 00110101 00100100




    Gemäß der bei Slotbär beschriebenen Syntax wäre 6:415$ Befehl/Fahrzeug/Wert/Wiederholung/Prüfsumme (BAWNP).



    Die Umwandlung von ASCII in DEZ in HEX in BIN ist mir klar, aber meine Frage ist, wie ich ÜBERHAUPT darauf komme, dass 6/5/4/1 eben einfach 6:415$ als ASCII-Zeichen (oder in welcher Byte-Repräsentation auch immer) entspricht? Da stehe ich gnadenlos auf dem sprichwörtlichen Schlauch und habe mir schon diverseste Haare ausgerissen...



    Slotbär schreibt, dass BA zusammen ein Byte ergeben, wobei die unteren 5 Bit dem Befehl und die oberen 3 Bit der FahrzeugID entsprechen. Wenn ich das mit meinem kleinen Hirn umsetze, kommt da raus:



    Befehl 6 in BIN (LSB): 01100000
    FahrzeugID 5 in BIN (LSB): 10100000
    Kombiniert: 01100101 = HEX 65


    Aber mit dieser Logik kann ich mir beim besten Willen nicht die Beispiele von Dir oder dem Slotbär zusammenreimen. HILFEEEE :(



    LG,
    Marc

  • Zitat von Slotbaer:
    (A)
    B und A bileden ein Byte im üblichen Carrera Format dessen untere 5 Bit dem befehl und dessen höchsten 3 Bit der Fahrzeugadresse entsprechen.


    (B)
    Handelt es sich um einen binären Bytewert, so wird er durch zwei aufeinander folgendeZeichen dargestellt. Es werden nur jeweils die unteren 4 Bit jeden Zeichens verwendet. Innerhalb eines Bytes werden zuerst die niederwertigen 4 Bits übertragen und dann die höherwertigen Bits.


    Kümmern wir uns erst um (A).
    Befehl 6 wäre (BBBBBxxx) BIN 01100000 (LSB)
    ID 5 wäre (DDDxxxxx) BIN 10100000
    Das hast du ja schon richtig kombiniert zu (BBBBBDDD) 01100101. In Hex wäre das dann aber nicht HEX 65, sondern HEX 6A (LSB eben).


    Kommen wir zu (B).
    Ein ganzes Byte wird nicht mit einem Mal übertragen, sondern zuerst in unteres und oberes Nibble geteilt. Also HEX 6 und HEX A.
    Das sieht nicht so unähnlich zu den letztlich übertragenen Werten im Hex-Format aus. Ich habe sie im Beispiel im MSB-Format geschrieben, bin eben damit groß geworden. =)


    Ich gebe dir mal noch eine kleine Aufgabe, wenn du magst.
    Fahrzeug mit ID 3 soll blinken (Frühstart):
    Befehl 4
    ID 3
    Wert 8
    Wie sähe dann der entsprechende Sendebefehl aus?


    Cheers,
    René

  • ebay Werbung
  • Danke für Deine Geduld... mein lieber Mann. Meine alten Zellen müssen hier ja nochmal richtig ran ;)


    Wenn ich es halbwegs kapiert habe, müsste das hier einigermaßen passen:



    Befehl 4


    BIN: 00000100
    LSB: 00100000
    Nur untere 5 Bits: 00100


    ------------


    Fahrzeug 3


    BIN: 00000011
    LSB: 11000000
    Nur untere 3 Bits: 110


    ------------


    Befehl/Fahrzeug kombiniert


    BIN: 00100110
    LSB: 01100100
    Nibble 1 LSB: 0110
    Nibble 1 HEX: 6
    Nibble 2 LSB: 0010
    Nibble 2 HEX: 4


    ------------


    Wert


    BIN: 00001000
    LSB: 00010000
    Nur unteres Nibble: 0001
    HEX: 1


    ------------


    Nach Adam Riese


    J6411P$ (wobei "P" noch zu klären wäre, falls es benötigt wird).


    Bitte bitte sag mir dass das richtig ist :D

  • Hi Marc,
    na da müssen wir noch mal üben. =D


    Deine Antwort (ASCII):
    6411P$
    Richtig (ASCII):
    46813$


    Befehl 4, ID 3 wäre kombiniert (B = höchstes Bit für Befehl, D = höchstes Bit für ID)
    bbbbBddD (LSB)
    00100110
    bzw.
    DddBbbbb (MSB, übliche Darstellung)
    01100100


    Du hast da nun LSB und MSB Darstellung etwas durcheinander gebracht, kommst am Ende zumindest hier fast wieder richtig raus. Ich würde zur Notation stets MSB empfehlen, da es letztlich intuitiver ist. Du schreibst ja zB auch deine Kontostand mit der größten Stelle links, sei die nun negativ oder positiv. =P


    Nehmen wir also
    01100100 (MSB)
    Macht für oberes und unteres Nibble
    01100100


    Hex 64


    Gut, haben wir also die Nibbles. Nun schauen wir uns nochmals Zitat (B) von Slotbaer an.
    ...
    Will ich also ein ganzes Byte übertragen (wie hier), so muss ich es in der Mitte teilen (haben wir gemacht) und dann erst die untere Hälfte und dann die obere Hälfte übertragen. Nun ist es eben so, dass für eine Übertragung dennoch 8 Bits gefüllt werden müssen.
    Übertragung Teil 1: xxxx0100 (Hex X4)
    Übertragung Teil 2: xxxx0110 (Hex X6)


    Was sind nun aber diese 4 Bits xxxx?
    Da kommen wir gleich drauf zurück.


    Schauen wir mal den Wert an (hier hast du von LSB in HEX einen Fehler gemacht, da du deine Wert in LSB-Darstellung als MSB interpretiert hast):
    00001000 (MSB)
    Hier brauchen wir eh nur das untere Nibble (Wert gibt's nur zw. 0 und 15 ), also
    Übertragung Teil 3: xxxx1000 (Hex X8)


    Die Wiederholung sollte eine sein:
    00000001 (MSB)
    Auch hier brauchen wir nur das untere Nibble (gibt's wohl nur zw. 1 und 15, habe ich aber noch nicht ausprobiert), also
    Übertragung Teil 4: xxxx0001 (Hex X1)


    Die Prüfsumme wäre ohne Übertrag
    xxxx0011 (Hex X3)


    So, da sind wir fast durch.
    Unsere Übertragung wäre dann (mit >$< am Ende)
    HEX: X4 X6 X8 X1 X3 24
    ADCII: 46813$


    Was ist nun mit dem X bzw xxxx? Das kannst du herausfinden, wenn du die ASCII-Zeile selbst in HEX aufschreibst, dann wirst du sehen, dass das die Xe überall die gleichen sind.


    Neue Aufgabe für dich.
    Die Bremse (Befehl 1) für ID 1 auf Wert 13 setzen (2 Wiederholungen, sonst nimmt es das Fahrzeug nicht an).


    Ich hoffen, ich konnte dir hier etwas weiter helfen, bin auf deine neue Antwort gespannt.


    Cheers,
    René

  • Servus René,


    Ich find's krass, dass Du so viel Zeit aufwendest, um mir armem Schlucker den ganzen Kram vorzukauen. Ich überlege mal, wie ich mich revanchieren kann. Vielen Dank jedenfalls!


    Also, ich versuchs mal:


    Befehl 1: 00000001
    ID 1: 00000001
    Zusammen: 00100001 (MSB)
    Oberes Nibble: xxxx0010 = Hex x2
    Unteres Nibble: xxxx0001 = Hex x1


    Wert 13 (nur unteres Nibble): xxxx1101 = Hex xD
    Wiederholung 2 (nur unteres Nibble): xxxx0010 = Hex x2


    Prüfsumme: 0010 (2) + 0001 (1) + 1101 (13) + 0010 (2) = 18 = nur letzte Stelle verwenden = 8
    Mit 30 verodern (0011 0000):


    00001000
    00110000
    -----------
    00111000 = Hex 38


    Übertragung Hex: x2 x1 xD x2 38 24
    Übertragung ASCII: J21=28$


    Und? Uuuuuuund? Jetzt bin ich meinerseits gespannt... 8o

    Unsicher bin ich mir beim Thema "Überträge ignorieren". Wo gäbe es denn bei der Prüfsumme Überträge, die man ignorieren könnte?


    LG,
    Marc


    Edith: Gab noch einen Fehler bei der Prüfsumme :(

  • Hi Marc,
    das sieht doch schon ganz gut aus. =D


    Deine Antwort (ASCII):
    21=28$
    Richtig (ASCII):
    12=22$




    Bei der Übertragung von ID und Befehl hast du lediglich die Reihenfolge der Nibbles vertauscht. Erst das untere und dann das obere senden. Alles andere hast du hier richtig gemacht, super!
    Wert und Wiederholung stimmen auch.



    Kommen wir zur Prüfsumme. Hier meine ich mit "Übertrag ignorieren", dass man am Ende nur die unteren 4 Bits braucht. Das war zugegeben nicht ganz glücklich formuliert.
    Deine Prüfsumme 18 ist schonmal richtig.
    Binär ergibt das 00010010.
    Gebraucht werden nur die unteren 4 Bits, also xxxx0010.
    Hier hast du einfach die Zehnerstelle gestrichen und mit einer 8 weitergerechnet. Das ist aber nicht ganz dasselbe. ;)



    Das Verodern mit HEX 30 hast du bei der Prüfsumme wieder richtig gemacht. Hinzu kommt, dass es auch mit allen anderen Bytes passieren muss (bis auf das letze Byte >$< = HEX 24).
    Sonst kommt man ja nicht von
    Übertragung Hex: x1 x2 xD x2 32 24
    auf
    Übertragung ASCII: 12=22$


    wenn die verbleibenden "x"-e nicht auch auf 3 gesetzt werden.


    Eins noch zur Erinnerung:
    Du sendest: "J
    wartest auf: J
    sendest dann: 12=22$ (in diesem Fall)
    wartest auf: $




    So, ich denke mit dem nächsten Beispiel hast du's.



    Die Fahrstufe (oder Maximalgeschwindigkeit oder Speed, ich nenn's halt Fahrstufe) von ID 4 soll auf 7 gesetzt werden. Das macht zB CockpitXP so, um den realen Tankmodus zu emulieren.
    Befehl = 0
    ID = 4
    Wert = 7
    Wiederholung = 2 (muss ebenfalls 2x gesendet werden, damit das Fahrzeug den neuen Wert annimmt)



    LG,
    René



    PS: Keine Ursache für das bisschen Zeit. Ich hätte dir auch einfach eine Codeschnippsel senden können. Ich denke aber, es ist nachhaltiger für dich - und jemanden, der das vllt. auch mal baucht - wenn man selbst drauf kommt. Auch wenn's länger dauert. Ich helfe ja von Schritt zu Schritt nur ein wenig nach. Du bist ja auch eifrig dabei und von daher mache ich das gerne. Mach dir ein schönes Wochenende. =D

    Einmal editiert, zuletzt von unrene ()

  • Ahhh... jetzt hab ichs (glaube ich) endgültig gerafft. Also:


    Befehl 0: 00000000
    ID 4: 00000100
    Zusammen: 10000000 (MSB)
    Unteres Nibble: xxxx0000 = Hex x0


    Oberes Nibble: xxxx1000 = Hex x8
    Wert 7 (nur unteres Nibble): xxxx0111 = Hex x7
    Wiederholung 2 (nur unteres Nibble): xxxx0010 = Hex x2
    Prüfsumme: 0000 (0) + 1000 (8) + 0111 (7) + 0010 (2) = 17 = 00010001 = nur unteres Nibble verwenden = xxxx0001 = Hex x1


    = x0 x8 x7 x2 x1 24


    Alle Bytes (bis auf >$</24) mit 30 verodern (0011 0000):



    = 00110000 00111000 00110111 00110010 00110001 00100100


    = 30 38 37 32 31 24
    = J08721$


    Oh mann, mir fällt grade auf wie spät es ist... meine Frau schimpft schon... ich hoffe jedenfalls, ich habe mit meinem müden Hirn jetzt nicht doch noch was durcheinandergebracht :(

  • ebay Werbung
  • Super René, vielen lieben Dank. Sorry, dass ich mich jetzt erst melde. Zwischenzeitlich habe ich den ganzen Kram direkt in eine Funktion gegossen. Das ganze schreit ja auch geradezu nach Unittests... mal sehen, ob ich mich dazu aufraffen kann... :D

  • Kurzes Update: Ich habe jetzt rausgefunden, dass man der CU bei der Kommunikation über AppConnect wohl die Kommandos nicht separat sendet/senden muss. Ich habe erfolg, wenn ich das Kommando direkt so sende:


    J<Befehl><Prüfsumme> (ohne "$")


    Als Bestätigung auf den ganzen Befehl kommt dann ein "J" zurück.


    Es haben sich jetzt aber dadurch noch ein paar Fragen ergeben, die Du, René, vielleicht auch beantworten kannst (oder andere, die hier still und heimlich mitlesen ;-)):


    (1) Gibt es "zusammenfassende" Befehle, also sowas wie "Setze Tankgröße für ALLE Regler auf <Wert>"? Falls nicht, sendet man also den entsprechenden Befehl für alle Regler nacheinander?


    (2) Ich habe noch keinen Befehl entdeckt, der mir die aktuellen Einstellungen für die jeweiligen Parameter (z.B. aktuelle Tankgröße für <Regler>) ausgibt. Gibt es sowas? Falls nicht, wäre es ja so, dass die App nichts davon mitbekommen kann, wenn an der CU manuell etwas eingestellt wird (also nicht über die App). Hoffe, man versteht, was ich meine.


    LG,
    Marc

  • Um mir meine Fragen direkt mal selbst zu beantworten: Es klappt, wenn man alle Befehle nacheinander sendet. Passt! Tankgröße abfragen geht wohl nicht, muss aber auch nicht unbedingt.


    Aber ich habe noch mehr Fragen: Ich habe es bisher nicht hinbekommen, der CU den Startbefehl zu senden 6, 0, 9 oder =1 (klappt beides nicht). Hat jemand eine Idee, was ich tun muss (und in welcher Reihenfolge), damit die CU ein Rennen startet?`


    LG

  • ebay Werbung
  • Servus HuGo,


    Aber die originale App von Carrera kann es - das macht mich eifersüchtig :D


    LG

  • Hallo zusammen,


    habt ihr inzwischen rausgefunden, wie der Befehl für den Start eines Rennen ist?
    Ich wäre auch an dem Befehl interessiert ;)


    Wird dafür das Update über AppConnect benötigt?


    Danke schon.


    Viele Grüße,
    Fabian

Jetzt mitmachen!

Sie haben noch kein Benutzerkonto auf unserer Seite? Registrieren Sie sich kostenlos und nehmen Sie an unserer Community teil!