Hallo, bevor ich mit meinen bescheidenen Software-Kenntnissen versuche irgendwas zusammen zu wurschteln frage ich lieber einmal nach wie es die "Profis" machen würden. Und zwar möchte ich mit dem PC über USART auf meine Schaltung zugreifen können (das funktioniert auch prinzipiell schon) und gewisse Variablen lesen und schreiben können. Folgende Operationen möchte ich dazu durchführen können: LADE 16Bit Variable X SCHREIBE 16Bit Variable X LADE 64Byte Array X SCHREIBE 64Byte Array X Mein Problem ist nun wie ich den Befehlssatz am schlausten codieren soll. Ich kann ja schlecht 64Byte als ASCII-Zeichen empfangen/versenden... aber wenn ich die Werte einfach binär verschicke kann ich Anfang und Ende eines Befehls nicht erkennen(?). Ich wollte die ganzen Befehle µC-Seitig erstmal per RX-Interrupt in einen Ringbuffer speichern und dann im Hauptprogramm auswerten. Ist das überhaupt Sinnvoll? Wie würdet ihr das lösen? Vielen Dank! Gruß, Roman
Roman F. schrieb: > Ich kann ja schlecht 64Byte als ASCII-Zeichen > empfangen/versenden... und warum nicht?
Peter II schrieb: > Roman F. schrieb: >> Ich kann ja schlecht 64Byte als ASCII-Zeichen >> empfangen/versenden... > > und warum nicht? Wenn ich mich nicht irre müsste ich ja dann 192Bytes senden... ich dachte mir das würde die ganze Sache nur "verkomplizieren", da ich die ganzen Werte dann jeweils noch von ASCII in die wirklichen Werte umwandeln müsste.
Roman F. schrieb: > Wenn ich mich nicht irre müsste ich ja dann 192Bytes senden... ich > dachte mir das würde die ganze Sache nur "verkomplizieren", da ich die > ganzen Werte dann jeweils noch von ASCII in die wirklichen Werte > umwandeln müsste. aber dafür ist das "Protokoll" einfacher. Wenn du genug ram und zeit dafür hast dann mach es als ASCII. Binary ist zwar effizienter aber auch schwer umzusetzen.
Roman F. schrieb: > Wenn ich mich nicht irre müsste ich ja dann 192Bytes senden Du irrst. Aus einem Binärbyte werden 2 ASCII-Zeichen. Roman F. schrieb: > ich > dachte mir das würde die ganze Sache nur "verkomplizieren", da ich die > ganzen Werte dann jeweils noch von ASCII in die wirklichen Werte > umwandeln müsste. Wahnsinnig kompliziert.
1 | unsigned char AsciiToByte(char nH, char nL) |
2 | {
|
3 | if(nH > 0x40) nH += 9; |
4 | if(nL > 0x40) nL += 9; |
5 | return (nH << 4) + (nL & 0x0F); |
6 | }
|
mfg.
Wenn du 64Byte übertragen willst, musst du 64 Byte übertragen! Wie du auf 194Byte kommst weiß ich nicht... Du kannst in deiner Empfangsroutine (im uC) abhängig von dem empfangenem Byte deine Variablen verschicken. Dein PC Programm muss dann nur die empfangenen Bytes in Abhängigkeit von der versendeten Nachricht interpretieren.
ah ok. Verstehe das mit den 192Byte... Das ist aber nicht sehr effizient. Lieber direkt binär übertragen und deinen (schnellen) Pc die "Arbeit" übernehemen lassen.
Thomas Eckmann schrieb: > Du irrst. Aus einem Binärbyte werden 2 ASCII-Zeichen. Thomas Eckmann schrieb: > unsigned char AsciiToByte(char nH, char nL) > { > if(nH > 0x40) nH += 9; > if(nL > 0x40) nL += 9; > return (nH << 4) + (nL & 0x0F); > } Das ist natürlich tricky! Da wäre ich niemals drauf gekommen... Effizienter erscheint es mir aber trotzdem die Werte direkt in Binärform zu übertragen. Was haltet ihr von der Möglichkeit zuerst eine Art Header zu verschicken der z.B. lautet: "SAVE_ARRAY NAME;"<<Byte1<<Byte2<<...<<Byte64 Beziehungsweise im umgedrehten Fall: "LOAD_ARRAY NAME;" der Controller antwortet dann z.B. mit: Byte1<<Byte2<<...<<Byte64 Das Array ist immer 64Byte groß, man könnte also mit dem µC den String bis zum Semikolin auswerten und wüsste, dass danach die 64 Datenbyte kommen die abgespeichert werden sollen. Ich bin mir nur unsicher ob das so überhaupt praktikabel und betriebssicher ist oder ob da irgendwelche fiesen Übertragungsfehler passieren könnten? Danke und Gruß, Roman
Hi, das kannst du so machen, für den Fall von einem Übertragungsfehler kannst du ja zusätzlich alle 64 Datenbytes zusammen zählen (als uint8_t) und das Ergebnis als 65. Byte hinterher schicken, dann kannst du im uC prüfen ob da was nicht stimmt. Der uC könnte auch seine errechnete Prüfsumme zurück schicken, damit du auch auf PC-Seite weist ob es geklappt hat oder nicht. Zusätlich solltest du dir auch um einen Timeout gedanken machen, nach dem der uC die bis dahin empfangenen Zeichen verwirft, falls kein Semikolon eingetroffen ist. Und du musst natürlich den Buffer groß genug machen, den stell dir z.B. vor der "Header" wird nicht erkannt (z.B. durch Übertragenungsfehler), anschließend werden die 64 Bytes gespeichert, und erst dann kommt der nächste "Header"... Gruß Marcus
So richtig verstehe ich dein Problem nicht, mag an der Uhrzeit liegen. Ich an Deiner Stelle würde mir ein einfaches Binärprotokoll definieren: Byte 0: Kommando, in Deinem Fall z.B 0x1 für schreiben 16bit, 0x2 schreiben 64 Byte, 0x10 lesen 16bit und 0x11 für lesen 64 Byte ... Nur im Schreibfall über trägst Du nach dem Kommando weitere Daten, im Lesefall war test Du halt direkt auf die Antwort. Die Sache mit dem Erkennen des Befehls läuft dann über die state machine, die Dein Protokoll auswertet - es beginnt also immer mit dem Befehlsbyte, was danach passiert hängt vom Befehl ab. Wirklich "erkennen" müsstest Du den Befehl nur in solchen Protokollen, in denen variable Feldgrössen übertragen werden, was aber in dem von Dir geschilderten Fall nicht vorkommt. [FYI: Wenn Du variable Feldgrössen über tragen - z.B. nicht alle 64 Bytes senden oder lesen willst, ergänzt Du halt das Kommando um die Feldgrösse: auf 0x2 0x20 lässt Du dann nur 32 Bytes folgen - wiederum sorgt die Implementierung der state machine für die korrekte Abarbeitung.]
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.