Umwandlung ASCII Charactr zu decimal in STM

Gast #5847365
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') #
#5847383
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?
Gast #5847459
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.
Gast #5847472
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.
Gast #5847825
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];
Angehängte Dateien:
Gast #5847854
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.
#5847880
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).
Persönliche Seite #5847884
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)
Gast #5847889
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.
#5847899
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.
Gast #5847904
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.
Gast #5847914
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.
#5847916
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);
Gast #5847940
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
Gast #5848108
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.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren