Umwandlung ASCII Charactr zu decimal in STM

Gast #5847365
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') #
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
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
Gast
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
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
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
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'
Gast
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.
Gast
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
Gast
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.
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
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
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.
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
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
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.
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
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
Gast
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
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

Eine eigene Frage? Dieser Thread ist über 7 Jahre alt. Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.