Hex - Zahlen / Binärzahlen mit dem Arduino empfangen via Serial Port

Hallo, habe eine Frage, möchte über eine elbstgeschriebene GUI- Steuerparameter an dem Arduino via SerialPort senden. Da diese aber meistens in Hex / Binär sind, wollte ich fragen, ob das geht, dass man die Werte z.b. wenn ich in der GUI 0x58 eingebe, der Arduino auch wirklich diesen Wert als Hex /Binär empfangen kann. Und wenn ja, wie geht das?

Microcontroller und CPU arbeiten prinzipiell binär. Die dezimal, oktal oder hexadezimal Darstellung ist ein Ausgabeformat damit wir menschen die Zahlen verstehen.
Darum: es gibt Dein befürchtetes Problem nicht.
Grüße Uwe

Ich tippe du suchst etwas in dieser Richtung:

Serial.println(0xFF, HEX);

Steuerparamteter werden meisten allerdings in Hexadezimaler Notation angegeben, um sich die vielen Bits zu sparen, da 0xFF = 255 = 0b11111111

Addi

Na ja, das Problem ist, in der GUI gibst eventuell Text ein,
was du zum Arduino überträgst, kann dieser Text sein ( muss aber nicht )
Serial.read() liest die Zeichen, die du sendest.

Du kannst den Text “0x58” ( 4 Buchstaben )
oder ein ‘X’ senden ( oder ein byte mit dem Wert 0x58, was das gleiche ist )

Im zweiten Fall reicht
byte input = Serial.read(); // liefert input = 0x58
aber du hast die Arbeit in der GUI, den eingetippten Text in die gewünschte Zahl zu wandeln.

Im ersten Fall musst du mehere Serial.read() aufrufen,eine EndeKennung anfügen und hinterher den Text “0x58” in deine Zahl wandeln. ( Kann der Arduino auch )

Und wenn ja, wie geht das?

Da gibt es zig Möglichkeiten …

Addi, ich fürchte, milito will es anders rum …

D.h. ich brauche die umwandlung in Hex nicht direkt in der GUI machen? Ich habe mich natürlich für die Variante entschieden, dass ich zb in der GUI den Hexwert eingebe oder in Dez. so nun möchte ich , dass es der Arduino es auch als Hex oder Dez empfängt. Wie mache ich das? Ich will diese Daten (Parameter) zuerst in eine csv datei auf derSd speichern, und nach bedarf soll der Arduino diese Parameter auslesen und damit das I2c-Device ansteuern. Jetzt die frage, lohnt es sich die schon vorher umzuwandeln( also in der GUI), weil wenn ich diese in eine csv datei speichere sind es ja dann wieder strings. Oder gibt es die möglichkeit diese Werte schon umgewandelt in eine HEx/Bindatei zu speichern bzw. sollte ich diese dann beim auslesen von der csv.datei umwandeln? Sorry

Oder wäre es einfacher diese auf dem EEPROM zu schreiben? nur wüsste nicht wie

Von welchen Zahlenwerten reden wir eigentlich? Zahlen zwischen 0 und 255? zwischen 0 und 65000 zwischen -32000 und +32000? Grüße Uwe

Hi Uwe,

wir reden von PArametern, die ich gerne über meine GUI in Hexadezimal eingeben möchte und meinem Arduino sende , zum zwischenspeichern in eine csv.datei und nach abruf diese, der Arduino ausliest und zum Steuern des i2c-devices verwendet.

Also sie müssen im Bereichvon 0-255 (0x00 - 0xff) sein.

csv Dateien sind auf jeden Fall Textdateien, in denen also keine binär 0 vorkommen kann und manche Zeichen ( " ; , ) Sonderfunktionen haben.
Seriell ist eine Text-Übertragung auch vorzuziehen, wenn es nicht auf höchste Geschwindigkeit ankommt, da das Testen (z.B. Simulation der GUI durch SerialMonitor ) dann einfacher ist.

Ob in dem String nun DezimalZahlen 0 … 255, Hex-Zahlen 00 … FF, oder komplizierteres ( 0, 0x0, 0x00 … 0xf … 0xAf, beliebige Leerzeichen , … ) erlaubt ist, ist Geschmackssache.

Da du überhaupt fragst, würde ich dir empfehlen, erstmal strikte Regeln zu setzen
z.B:

  • jede Zahl zweistellig aus [0 … 9, A…F] zusammengesetzt
  • keine Leerzeichen
  • ‘,’ als Trennzeichen
  • feste Anzahl von Werten

… und das dekodieren selber auszuknobeln. Das haben zwar schon Tausende vor dir gemacht, und du findest sicher mehr verschiedene Lösungen als hilfreich ist, aber µC programmieren ist eben eigentlich solche Fummel-Arbeit und also sehr lehrreich.

Die eigentliche Umwandlung ist sehr simpel :
Die Ziffern ‘0’ bis ‘9’ liegen hintereinander, also liefert

if (Serial.available() >=2) {
byte asc = Serial.read();
byte bin = asc - '0';

eine Zahl zwischen 0 und 9, wenn in asc ein solcher Buchstabe ( ‘0’ … ‘9’ ) ist.

Genauso liegt ‘A’ bis ‘F’ hintereinander, aber leider nicht direkt nach der ‘9’.

Also gibt

if (bin > 9) bin = asc - 'A' + 10;

eine Zahl zwischen 10 und 15 ( 0x0A … 0x0F), wenn asc nicht ‘0’ … ‘9’ sondern ‘A’ … ‘F’ war.

bin1 * 16 + bin2 … und fertig ist deine Zahl 0 … 255.

Edit: Jetzt noch klarer beschrieben :wink:

HI michael_x,

danke für deine Hilfe, bin immerhin etwas vorwärts gekommen:D. Als erstes , warum hast du das mit dem Serial.available()>=2 und nicht >0? -> vllt. weil du 2Byte erwartest? normalerweise müsste doch ein byte reichen oder?

So dann das wäre die Variante, wenn ich das von der GUI aus schon dekodiere und das über Serialport dem Arduino sende, stimmst?

Und die nächste Frage ist, lohnt es sich das schon von der GUI aus zu dekodieren(Umwandeln), denn wenn ich es in eine csv.Datei speichere war ja die Umwandlung umsonst. oder Gibt es vllt. eine andere Dateiart zum speichern, die ich verwenden kann?

normalerweise müsste doch ein byte reichen oder? So dann das wäre die Variante, wenn ich das von der GUI aus schon dekodiere und das über Serialport dem Arduino sende, stimmst?

Nein, das war schon alles, wenn der PC Parameter als Text sendet. Wenn der PC für einen Parameter im Bereich 0 .. 0xFF nur ein Byte sendet, ist es auf der Arduino Seite noch viel einfacher:

if (Serial.available()) {
  byte bin = Serial.read(); // fertig
}

Serial.available()>=2 wenn eine zu lesende Zahl immer aus 2 Buchstaben besteht, braucht man auch vorher nicht anzufangen... Ein zusätzliches ',' Trennzeichen dient eigentlich nur dazu, das gesendete für Menschen einfacher lesbar zu machen.

Gibt es vllt. eine andere Dateiart zum speichern, die ich verwenden kann?

Du kannst jedes Byte in eine Datei schreiben und wieder auslesen, auch binäre Nullen.

Ob eine Datei .csv oder .txt oder sonstwie heisst, ist dem Arduino vollkommen egal ( Der Name sollte max. 8+3 Buchstaben lang sein ).

Dass solch eine Binär-Datei dann am PC mit notepad schwer lesbar ist, ist eine andere Sache.

Eeprom zum Speichern von ein paar Parameter-Bytes ist übrigens einfacher: Du brauchst keine SD-card, der eeprom Speicher ist sowieso vorhanden, keine aufwendige Library ... .

HI ok, aber wenn ich jedes Byte oder binäre 0 in die Datei schreibe (nehmen wir an in csv oder txt) ist es ja kein byte bzw. binäre 0 , sondern ein String oder täusche täusche ich mich? d.h. dann müsste ich sie auslesen und umwandeln in hex oder byte, oder täusche ich mich? Gibt es keine möglichkeit, sie direkt als solches, also als Byte oder Hex auf die SD zu schreiben?

Zu dem eeprom, ist es also einfacher, hättest du da beispiele wie man sowas mit dem eeprom machen kann? (Also empfangene Parameter über Serialport dort reinschreiben und nach bedarf auslesen und diese sowohl an die GUI und zum ansteuern des Devices zu verwenden) ich wollte es versuchen, doch das erschien mir komplizierter. Das Problem ist, ich sende von meiner GUI 3 Werte bzw.Parameter zum Arduino die jeweils 8bit gross sind. Nun wüsste ich nicht, wie ich alle 3 aufeinmal in dem EEPROM reinschreibe.

Hallo, habe mich entschieden, die SD.Karte zu verwenden und die Werte in die CSV.Datei zu speichern. Nun möchte sie nach bedarf auslesen , in einem Buffer schreiben und mit der strtok() splitten und die werte in 3 verschiedenen Variablen speichern, damit ich sie jeweils immer separat versenden kann.

habe doch einige fragen:

1) Wie mache ich das den inhalt zeilenweise auszulesen und in den Buffer einzuladen und diesen dann zu splitten und in drei verschiedene Variablen zu packen?

2) jede zeile entspricht immer 3 parametern, d.h. 3 parameter werden immer auf einmal gesendet. Nun die csv.datei besteht nicht nur aus einer zeile mit 1 befehlsatz , sondern aus mehreren zeilen. Wie mache ich dass, dass ich mir immer den beliebigen Befehlssatz raussuche und diesen splitte und sende?

Wenn du eine bestimmte Zeilennummer suchst: Beim Lesen die '\n' zeichen zählen ? Eine komplette Zeile lesen: Bis zum nächsten '\n' (oder Dateiende) lesen ? Wenn du eine bestimmte Zeile suchst, musst du halt jede gelesene Zeile auswerten und bei Bedarf die nächste lesen ?

Zum Splitten hast du strtok ja schon gefunden, atoi / atol , um eine Zahl draus zu machen, sollte auch zu finden sein.

Hi michael_x danke nochmals, habe auch etwas anderes gefunden und zwar mit parseInt() müsste es auch gehen, schau: http://arduino.cc/en/Tutorial/ReadASCIIString. Werde es versuchen :D