ubuntuusers.de

Integer und String über eine serielle Schnittstelle ausgeben

Status: Ungelöst | Ubuntu-Version: Kein Ubuntu
Antworten |

fllopi

Anmeldungsdatum:
31. August 2015

Beiträge: 26

Hallo,

ich hatte schon länger danach gesucht aber noch nichts passendes zu meinem Problem gefunden....

Ich möchte ganz einfach einige Zahlen als integer über meine serielle Schnittstelle ausgeben, das geht nicht mit echo so weit ich es in Erfahrung bringen konnte sondern nur mit printf %d aber ich bin mir nicht sicher. Zusätzlich muss ich eine Zahl als Zeichen ausgeben was nach meinen Recherchen mit echo gehen müsste?!

Als bsp.:

1
2
3
4
varA=12345
printf %d $varA >> /dev/ttyS0  #12345 wird als Integer an meine serielle Schnittstelle gesendet

echo "5" >> /dev/ttyS0  #5 wird als Zeichen an meine serielle Schnittstelle gesendet

Stimmt das so oder liege ich daneben?

LG fllopi

Bearbeitet von rklm:

Syntaxhighlighting + Codeblock

rklm Team-Icon

Projektleitung

Anmeldungsdatum:
16. Oktober 2011

Beiträge: 13204

Es gibt keinen Unterschied: die Zahlen werden immer als Zeichen ausgegeben.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
$ echo 5 | od -tx1c
0000000  35  0a
          5  \n
0000002
$ echo "5" | od -tx1c
0000000  35  0a
          5  \n
0000002
$ v=5
$ echo "$v" | od -tx1c
0000000  35  0a
          5  \n
0000002

Wie Du siehst, kommt immer das gleiche heraus. Es ist etwas anderes, wenn Du Zahlen binär auf die Schnittstelle schicken musst. Aber davon war nicht die Rede.

fllopi

(Themenstarter)

Anmeldungsdatum:
31. August 2015

Beiträge: 26

Ja bei echo schon aber doch nicht wenn ich es mit printf an sie schicke oder liege ich da falsch?

user_unknown

Avatar von user_unknown

Anmeldungsdatum:
10. August 2005

Beiträge: 17620

Wohnort: Berlin

Die serielle Schnittstelle kennt keine Dateitypen. Du kannst ihr keinen übergeben. Du kannst nur Bytes übergeben.

1
2
3
4
echo -en "\x5" | od -tx1c 
0000000  05
        005
0000001

mit -en unterdrückst Du am Ende das Newline und mit -e aktivierst Du extended Features. Eines der extended Features ist es, Hexadezimalcodes einzugeben, bei 5 eine einfache Sache, da es \x5 ist, Maskierung ist nötig, also "\x5", "\x05" geht aber auch, falls Du ansonsten Schwierigkeiten mit größeren Werten bekämst.

fllopi

(Themenstarter)

Anmeldungsdatum:
31. August 2015

Beiträge: 26

Muss man also die werte so konfigurieren, oder reicht dann nicht auch ein "normales" echo?

echo "5" >> /dev/ttyS0

Marc_BlackJack_Rintsch Team-Icon

Ehemalige
Avatar von Marc_BlackJack_Rintsch

Anmeldungsdatum:
16. Juni 2006

Beiträge: 4686

Wohnort: Berlin

@fllopi: Wofür soll das reichen? Das sendet etwas anderes, nämlich die Bytefolge 35 0a (zwei Bytewerte in Hexadezimalnotation angegeben), während das von user_unknown nur ein Byte mit dem Wert 5 sendet.

fllopi

(Themenstarter)

Anmeldungsdatum:
31. August 2015

Beiträge: 26

Naja ich muss an ein Gerät einige bestimmte Werte über die serielle Schnittstelle senden. Dabei muss ich einmal das Zeichen 5 senden und mehrere male einzelne Zahlen, diese aber nicht als Zeichen sondern als Zahl. Zumindest hatte ich das so aus dem Vorgänger Programm, welches jedoch in C geschrieben war, abgelesen. Dort wurde mit dem Befehl ComWrtByte gearbeitet http://zone.ni.com/reference/en-XX/help/370051V-01/cvi/libref/cvicomwrtbyte/.

Marc_BlackJack_Rintsch Team-Icon

Ehemalige
Avatar von Marc_BlackJack_Rintsch

Anmeldungsdatum:
16. Juni 2006

Beiträge: 4686

Wohnort: Berlin

@fllopi: Warum ist das neue Programm nicht auch in C? Oder irgendwas anderes, denn nahezu alles dürfte für so etwas besser geeignet sein als ein Bash-Skript.

rklm Team-Icon

Projektleitung

Anmeldungsdatum:
16. Oktober 2011

Beiträge: 13204

fllopi schrieb:

Ja bei echo schon aber doch nicht wenn ich es mit printf an sie schicke oder liege ich da falsch?

Das kannst Du einfach ausprobieren:

1
2
3
4
$ printf '%d\n' 5 | od -tx1c
0000000  35  0a
          5  \n
0000002

Der ganze Witz von printf (in der Shell und erst recht in C) ist, die Argumente formatiert als Zeichenketten auszugeben.

fllopi schrieb:

Naja ich muss an ein Gerät einige bestimmte Werte über die serielle Schnittstelle senden. Dabei muss ich einmal das Zeichen 5 senden und mehrere male einzelne Zahlen, diese aber nicht als Zeichen sondern als Zahl.

Hast Du denn keine Protokollbeschreibung? So etwas ist eigentlich unerlässlich, um das richtig zu machen.

Zumindest hatte ich das so aus dem Vorgänger Programm, welches jedoch in C geschrieben war, abgelesen. Dort wurde mit dem Befehl ComWrtByte gearbeitet http://zone.ni.com/reference/en-XX/help/370051V-01/cvi/libref/cvicomwrtbyte/.

Das ist anscheinend nur eine Funktion, die ein Byte verschicken kann. Entscheidend ist aber, was die Gegenseite versteht.

Marc_BlackJack_Rintsch Team-Icon

Ehemalige
Avatar von Marc_BlackJack_Rintsch

Anmeldungsdatum:
16. Juni 2006

Beiträge: 4686

Wohnort: Berlin

In der Bash könnte eine Funktion die so ähnlich wie die gezeigte ComWrtByte() funktioniert, so aussehen:

1
2
3
4
5
WriteByte() {
    local device=$1
    local byte_value=$2
    echo -e "\x$(printf '%02x' "$byte_value")" > "$device"
}

Schön ist anders. ☺

fllopi

(Themenstarter)

Anmeldungsdatum:
31. August 2015

Beiträge: 26

OK ich versuche es jetzt erstmal mit dem Vorschlag von user_unknown: dann müsste ich für die ausgabe der 5 schreiben,

1
echo -en "\x5" >> /dev/ttyS0

und für z.B. eine 170

1
echo -en "\xAA" >> /dev/ttyS0

Liege ich da richtig oder falsch?^^

rklm Team-Icon

Projektleitung

Anmeldungsdatum:
16. Oktober 2011

Beiträge: 13204

fllopi schrieb:

Liege ich da richtig oder falsch?^^

Ohne zu wissen, was die Gegenseite erwartet, kann man das schlecht sagen. Wenn z.B. alle Zahlen als 32Bit-Zahlen übermittelt werden müssen, dann reicht das nicht. Dann muss man vier Bytes schicken und außerdem wissen, ob Big- oder Little-Endian übermittelt werden muss.

fllopi

(Themenstarter)

Anmeldungsdatum:
31. August 2015

Beiträge: 26

Hmm ok danke, da werde ich nochmal nach fragen müssen.

Noch eine Frage zu dem was Marc_BlackJack_Rintsch geschrieben hat, wofür steht die 02 bei

1
...printf '%02x'...

?

user_unknown

Avatar von user_unknown

Anmeldungsdatum:
10. August 2005

Beiträge: 17620

Wohnort: Berlin

Länge 2 Zeichen, vorne mit 0en füllen. Laut Doku:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
Parameters
Input
Name	Type	Description
portNumber	int	A number that indicates the COM port on which to operate.

This number maps to the COM port specified by deviceName in the call to OpenCom or OpenComConfig. The portNumber 1, for example, may not necessarily map to COM1.

(Linux) The portNumber 1, for example, may not necessarily map to /dev/ttyS0.

Valid Range: 1—1,000
byte	int	The value of the byte to write to the selected port. Only the low-order byte is significant.

erwartet die Funktion nur ein Int, von dem sie nur das untere Byte auswertet.

Ob Big- oder Little-Enzian - tja, weiterrecherchieren oder auf gut Glück.

fllopi

(Themenstarter)

Anmeldungsdatum:
31. August 2015

Beiträge: 26

Aber ist in deinem Code bsp.

1
2
3
4
5
WriteByte() {
    local device=$1
    local byte_value=$2
    echo -e "\x$(printf '%02x' "$byte_value")" > "$device"
}

das

1
echo -e "\x$"

nicht zu viel? Da die zahl mit Hilfe des printf Befehls schon in eine Hexadezimalzahl umgewandelt wurde. Denn wenn ich das Ganze mit z.B.83 versuche ein S als Ausgabe erhalte, welches nicht hexadezimal ist.

Antworten |