Forum: Mikrocontroller und Digitale Elektronik Umwandlung ASCII Charactr zu decimal in STM


von Martin (Gast)


Lesenswert?

Hallo zusammen,

Ich möchte Daten von Python über die serielle Schnittstelle an STM32 μc 
senden. Das Problem ist, dass ich nur Zeichen von Python an STM senden 
kann. Zum Beispiel wird 21 in Python in stm 0x32 und 0x31 empfangen. und 
ich will es 22 in deciaml haben.



import serial # import time #

X = serial.Serial('com3',115200) time.sleep(0.5)

X.write('21') #

von Thomsa A. (Gast)


Lesenswert?

Wenn du ASCII IN DEZ. Umrechnen möchtest, brauchst du von den 
Einerstellen einfach nur -48 abziehen.

von Rolf M. (rmagnus)


Lesenswert?

Martin schrieb:
> Zum Beispiel wird 21 in Python in stm 0x32 und 0x31 empfangen. und
> ich will es 22 in deciaml haben.

Was meinst du mit "in decimal"? Hexadezimal und dezimal sind 
Eigenschaften einer Zeichenkodierung von Zahlen. 0x32 und 0x31 wären die 
ASCII-Zeichen für die dezimale Textkodierung der Zahl 21.
Und wieso soll eigentlich 22 statt 21 rauskommen?

von Martin (Gast)


Lesenswert?

Thomsa A. schrieb:
> brauchst du von den
> Einerstellen einfach nur -48 abziehen

Danke für deine Antwort. '1'ist in hex 0x31 und in dez 49 >> 49-48 =1 
und das gleiche für '2'. Nun meine Frage ist wie kriege ich das hin, die 
Nummer in 2 stellen zu kriegen also 21 in dec

von Stefan F. (Gast)


Lesenswert?

Das mit dem Subtrahieren von 48 halte ich hier für eine Sackgasse. Das 
klappt nur mit einstelligen Zahlen.

Ascii to Integer atoi()
Integer to Ascii itoa()

Lies Dir mal die Beschreibung dieser beiden Funktionen durch.

von Martin (Gast)


Lesenswert?

Rolf M. schrieb:
> ASCII-Zeichen für die dezimale Textkodierung der Zahl 21.
> Und wieso soll eigentlich 22 statt 21 rauskommen?

sorry das soll 21 sein. Ich möchte die 0x31 und 0x32 zu 21 in dez 
umrechnen.

von W.S. (Gast)


Lesenswert?

Martin schrieb:
> Ich möchte Daten von Python über die serielle Schnittstelle an STM32 μc
> senden. Das Problem ist, dass ich nur Zeichen von Python an STM senden
> kann.

Nein, das ist wirklich kein Problem, sondern ich sehe das als deutlich 
besser, als wenn jemand auf die Idee kommt, rein binäres Zeugs über eine 
Serielle schicken zu wollen.

Das Problem besteht darin, daß du nicht im Geringsten nachgedacht hast 
über irgend ein sinnvolles Protokoll oder wenigstens über eine 
Eingangs-Konvertierung.

Ist es denn so schlimm, mal gedanklich sowas zu formulieren:
1
bool negativ;
2
long Nummer;
3
4
void ZahlErwarten(void)
5
{ Nummer = 0;
6
  negativ = false; }
7
8
// liefert true, wenn Nummer fertig ist
9
bool ZeichenVomUART_verarbeiten (char Zeichen)
10
{ if((Zeichen=='-') && (Nummer==0)) negativ = true;
11
12
  if ((Zeichen>='0') && (Zeichen<='9'))
13
  { Nummer = Nummer*10 + (Zeichen-'0');
14
    return false;
15
  }
16
  if (negativ) Nummer = -Nummer;
17
  return true;
18
}

W.S.

von Martin (Gast)


Lesenswert?

Stefanus F. schrieb:
> Ascii to Integer atoi()

danke das hilft mir schon. Aber wenn ich '-21' empfangen möchte, was 
mache ichdann?

von W.S. (Gast)


Lesenswert?

Martin schrieb:
> danke das hilft mir schon. Aber wenn ich '-21' empfangen möchte, was
> mache ichdann?

Ab hier sollte dieser Thread eigentlich kostenpflichtig werden!

W.S.

von Martin (Gast)


Lesenswert?

W.S. schrieb:
> Ab hier sollte dieser Thread eigentlich kostenpflichtig werden!

ok Danke trotzdem

von Stefan F. (Gast)


Lesenswert?

Martin schrieb:
>> atoi()
> hilft mir schon. Aber wenn ich '-21' empfangen möchte, was
> mache ich dann?

Dann sendest du '-21'. Steht irgendwo in der Doku von atoi(), dass es 
keine negativen Zahlen unterstützt?

von STK500-Besitzer (Gast)


Lesenswert?

Stefanus F. schrieb:
> Dann sendest du '-21'. Steht irgendwo in der Doku von atoi(), dass es
> keine negativen Zahlen unterstützt?

Das Ding ist dokumentiert? ^^

von Martin (Gast)


Angehängte Dateien:

Lesenswert?

Stefanus F. schrieb:
> dass es
> keine negativen Zahlen unterstützt?

eigentlich nicht.Ich kann aber leider die empfangenen Daten per UART 
nicht in einem String haben. Z.B. '2'=0x32 und '2'=0x32 werden nicht 
'22' sondern 0x64=d (siehe Bild)


uint8_t Rx_data[10];
char X [4];
char Y[2];


X[0]=Rx_data[0];
X[1]=Rx_data[1];
Y[0]=X[0]+X[1];

von OMG (Gast)


Lesenswert?

Martin schrieb:
> X[0]=Rx_data[0];
> X[1]=Rx_data[1];
> Y[0]=X[0]+X[1];

OMG!

von Martin (Gast)


Lesenswert?

was denn ? ^^

von OMG (Gast)


Lesenswert?

Martin schrieb:
> was denn ? ^^

Welches Operationsergebnis versprichst du dir denn wenn du
zwei Variablen vom Datentyp Character addierst?

Lerne erst mal Grundlagen in C.

von Martin (Gast)


Lesenswert?

OMG schrieb:
> Welches Operationsergebnis versprichst du dir denn wenn du
> zwei Variablen vom Datentyp Character addierst?

man ich will die nicht addieren, sondern nebeneinander sortieren '2', 
'3' und '6' in '236'

von OMG (Gast)


Lesenswert?

Martin schrieb:
> man ich will die nicht addieren,

Genau das tust du aber hier.

Martin schrieb:
> Y[0]=X[0]+X[1];

Also warum addierst du wenn du nicht addieren willst?

von STK500-Besitzer (Gast)


Lesenswert?

Martin schrieb:
> was denn ? ^^

Du machst einen Schriit zu wenig.
Die 0x32 und 0x31 repräsnsentieren die Postion der Zahlen "2" und "1" in 
der ASCII-Tabelle 
(https://de.wikipedia.org/wiki/American_Standard_Code_for_Information_Interchange)

Da könnten auch "X" und "h" drinstehen. Man hat es aber so festgelegt.
Das praktische an der Geschichte ist, dass sowohl Ziffern als auch 
Buchstaben  in aufsteigender Reihenfolge in dieser Tabelle stehen, so 
dass sie nur einen Offset haben, dann aber die gleiche "Zählweise" wie 
man sie aus dem täglichen Leben gewohnt ist.

"0": 0x30
"1": 0x31
"2": 0x32
"3": 0x33
"4": 0x34
"5": 0x35
"6": 0x36
"7": 0x37
"8": 0x38
"9": 0x39

Um jetzt auf Dezimalwerte zu kommen, musst du nur von jedem Zeichen den 
Offset abziehen: '6'-0x30 = 0x06.
Das musst du nur mit jedem Zahlenzeichen machen, das du empfängst.

von Martin (Gast)


Lesenswert?

OMG schrieb:
> Also warum addierst du wenn du nicht addieren willst?

weil es so nicht geklappt hat.

X[0]=Rx_data[0];
X[1]=Rx_data[1];
char Y[9]="X[0]+X[1]";

von Martin (Gast)


Lesenswert?

STK500-Besitzer schrieb:
> Um jetzt auf Dezimalwerte zu kommen, musst du nur von jedem Zeichen den
> Offset abziehen: '6'-0x30 = 0x06.
> Das musst du nur mit jedem Zahlenzeichen machen, das du empfängst.

nun geht es nicht darum, es geht nun um die char in eine String zu 
sortieen.

LG

von STK500-Besitzer (Gast)


Lesenswert?

Martin schrieb:
> nun geht es nicht darum, es geht nun um die char in eine String zu
> sortieen.

Dazu kopiert man sie einfach in ein Feld.

Martin schrieb:
> X[0]=Rx_data[0];
> X[1]=Rx_data[1];
> char Y[9]="X[0]+X[1]";

Das ist totaler Blödsinn.
Guck dir einfach mal die C-Grundlagen zur String-Manipulation an.

von Markus F. (mfro)


Lesenswert?

Martin schrieb:
> as Problem ist, dass ich nur Zeichen von Python an STM senden
> kann.

Dann solltest Du das üben. Natürlich kann man einen String von A nach B 
schicken und ihn entsprechend hin- und herwandeln, wenn man eigentlich 
eine Binärzahl übertragen will (das ist meist sogar eine gute Idee), man 
kann (eine 8-Bit fähige Schnittstelle vorausgesetzt) aber auch einfach 
eine Binäre Zahl übertragen:
1
f.write(bytes([21]))

Das funktioniert so nur in Python 3+ und auch nur, wenn f im Binärmodus 
geöffnet wurde (bei niedrigerer Python-Version geht's auch, aber eben 
anders).

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Markus F. schrieb:
> man kann (eine 8-Bit fähige Schnittstelle vorausgesetzt) aber auch
> einfach eine Binäre Zahl übertragen:

Das kann man zwar, aber dann besteht keinerlei Chance mehr, sich 
irgendwie zu synchronisieren, d.h. bei der Übertragung mehrerer 
unterschiedlicher Werte herauszufinden, welcher gemeint ist.

Da ist die Klartextübertragung deutlich im Vorteil, einerseits können 
damit auch Werte übertragen werden, die außerhalb des mit einem Byte 
darstellbaren Wertebereichs von 0-255 liegen, und andererseits können 
auch zusätzliche Steuerinformationen gesendet werden (welcher Wert ist 
gemeint, Gerät zurücksetzen, Gerät dazu auffordern, irgendetwas zu tun, 
etc. pp)

von Zeno (Gast)


Lesenswert?

Martin schrieb:
> uint8_t Rx_data[10];
> char X [4];
> char Y[2];
>
> X[0]=Rx_data[0];
> X[1]=Rx_data[1];
> Y[0]=X[0]+X[1];

Man was ist den da so schwer. Du hast einen Puffer X der 9 Zeichen 
aufnehmen kann und das ist in Deinem Falle sogar schon mit #0 
initialisiert (bis auf die ersten 2 Positionen - sort steht ja Deine 
Zahl). Damit hast Du Deinen C-String. Du übergibst atoi nur eine 
Referenz auf Deinen Puffer und gut ist.

Du kannst auch über die Elemente des Puffers iterieren und jeden Wert 
umwandeln, so wie es hier mehrfach gezeigt wurde, und die einzelnen 
Stellen mit 10 Potenzen gewichtet aufsummieren. Wie das geht hat Dir 
W.S. gezeigt. Du mußt nur wissen wo die Einer-, Zehner- usw. Stelle in 
Deinem Puffer steht.

von Markus F. (mfro)


Lesenswert?

Rufus Τ. F. schrieb:
> Markus F. schrieb:
>> man kann (eine 8-Bit fähige Schnittstelle vorausgesetzt) aber auch
>> einfach eine Binäre Zahl übertragen:
>
> Das kann man zwar, aber dann besteht keinerlei Chance mehr, sich
> irgendwie zu synchronisieren, d.h. bei der Übertragung mehrerer
> unterschiedlicher Werte herauszufinden, welcher gemeint ist.
>
> Da ist die Klartextübertragung deutlich im Vorteil, einerseits können
> damit auch Werte übertragen werden, die außerhalb des mit einem Byte
> darstellbaren Wertebereichs von 0-255 liegen, und andererseits können
> auch zusätzliche Steuerinformationen gesendet werden (welcher Wert ist
> gemeint, Gerät zurücksetzen, Gerät dazu auffordern, irgendetwas zu tun,
> etc. pp)


Die Binärdatenübertragung kann all das auch, wenn man sich ein 
geeignetes Protokoll ausdenkt. Und man beschränkt den Nutzdaten-Bereich 
nicht ohne Not auf den Bruchteil der übertragbaren Information. Wenn's 
darum geht, (z.B. für's Debugging) einfach mitlesen zu können, hat ASCII 
natürlich seine Vorteile.

Martin schrieb:
> Das Problem ist, dass ich nur Zeichen von Python an STM senden
> kann.

Und das Problem kann man beseitigen.

von Stefan F. (Gast)


Lesenswert?

Ich habe das Gefühl, dass hier über einen Quelltext diskutiert wird, den 
niemand gesehen hat, außer Martin. Aber Martin fehlen noch 
Grundlagenkenntnisse.

Martin, die Grundlagen der Programmiersprache lernst du am Besten aus 
einem Buch und übst sie auf einem PC (nicht Mikrocontroller).

Wir können Dir vielleicht weiter helfen, wenn du deinen Quelltext 
zeigst.

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Markus F. schrieb:
> Die Binärdatenübertragung kann all das auch, wenn man sich ein
> geeignetes Protokoll ausdenkt.

Wenn. Hast Du den Eindruck, daß das der nächste Schritt ist, den der 
Threadstarter gehen sollte?

von OMG (Gast)


Lesenswert?

Zeno schrieb:
> Man was ist den da so schwer.

Wenn man kein C gelernt hat ist alles schwer. Was du da schreibst
geht voll an den Fähigkeiten und Verständnis des TO vorbei.

So wie bei einigen anderen Märchenerzähler hier auch.

Am ehesten würde ich noch Stefanus hier zustimmen.

von Joe F. (easylife)


Lesenswert?

Hallo Martin,

als erstes würde ich dir empfehlen, die Zahlen mit einem Linefeed 
(Zeilenumbruch) abgeschlossen zu übertragen.
Das beseitigt das Problem, dass dein Sender und der Empfänger ihre 
Synchronisation verlieren können.

Auf Senderseite:
1
X.write('21\n')
2
X.write('-2100\n')
3
(...)

Auf Empfängerseite ist die einfachste Methode (wie bereits genannt) auf 
die Funktion atoi() zurückzugreifen.
Die gibts auch in Python (string.atoi)

Um atoi deine Zahl konvertieren zu lassen, liest du auf Empfängerseite 
einfach die komplette Zeile (bis zum Linefeed) in einen Buffer (hier 19 
Zeichen + String delimiter).
Atoi kümmert sich um den Rest (Zahl mit variabler Länger von ASCII 
String in Integer umwandeln, auch mit Vorzeichen).
1
char buf[20];
2
FILE *fp_uart;
3
int  value;
4
5
(...)
6
7
fgets(buf, 19, fp_uart);
8
value = atoi(buf);

von Martin (Gast)


Lesenswert?

Zeno schrieb:
> Man was ist den da so schwer. Du hast einen Puffer X der 9 Zeichen
> aufnehmen kann und das ist in Deinem Falle sogar schon mit #0

danke. wenn man manchmal unter Druck ist, dann kann man nicht mehr 
denken.

LG

von zitter_ned_aso (Gast)


Lesenswert?

Martin schrieb:
> Ich möchte Daten von Python

Und warum wird jetzt in C programmiert?
1
num1=5
2
num2=42
3
num3=12345
4
5
str1=str(num1)
6
str2=str(num2)
7
str3=str(num3)
8
9
10
#einzelne Ziffern ausgeben
11
for i in str3:
12
    print("ascii: ", ord(i),"\tdec: ", i)

Ausgabe:
1
ascii:  49   dec:  1
2
ascii:  50   dec:  2
3
ascii:  51   dec:  3
4
ascii:  52   dec:  4
5
ascii:  53   dec:  5

von Zeno (Gast)


Lesenswert?

OMG schrieb:
> Wenn man kein C gelernt hat ist alles schwer. Was du da schreibst
> geht voll an den Fähigkeiten und Verständnis des TO vorbei.

Ich habe C auch nicht wirklich gelernt und ich bin definitiv nicht 100% 
fit in C. Ich habe mich aber auf den Hosenboden gesetzt, mir ein Buch 
genommen und die Basics gelernt. Ob ich alles verstanden habe ist eine 
andere Sache.
Aber gerade in diesem Thread sind genug Vorschläge gekommen die man 
ausprobieren kann, auch wenn man kein C Guru ist. Aber wenn man selbst 
das nicht tut dann ist eben doch Hopfen und Malz verloren.
Also so wie es W.S. beschrieben hat kann man es durchaus verstehen, wenn 
man will. Ich habe aber der Eindruck der TO hat selbst das noch nicht 
mal ansatzweise probiert.

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
Noch kein Account? Hier anmelden.