Forum: Compiler & IDEs Wie seriellen String empfangen?


von Andreas (Gast)


Lesenswert?

Hallo zusammen,

bei meinem neuen Projekt bräuchte ich etwas hilfe:

Ein AD22100 Temperatursensor misst eine Temperatur und der µC sendet die 
Daten über die Serielle Schnittstelle (eventuell später über Power line) 
an einen anderen µC. Der Empfänger µC wertet die Daten aus und schreibt 
mir die Temperatur aufs Display (keine Float ausgabe). 
"Komma-Temperatur" ist nicht erforderlich.

Temperatur ermitteln und seriell versenden ist kein Problem. Ich weiß 
nur nicht wie ich die Daten entgegen nehmen soll. Mit der getch() 
routine kann man ja nur einzelne Zeichen empfangen - ich müsste aber 
einen String empfangen damit ich die Temperatur auswerten kann.

Das www hilft mir leider nicht weiter ;)

Hätte jemand die güte mir zu helfen oder weiß jemand ein geeignetes 
Tutorial?

Schon mal danke im Voraus.

Programmiersprache ist C. Plattform AVR Studio 4. Compiler WinAVR.

Prozessor (vorerst zum probieren) Mega 32

von Helfer (Gast)


Lesenswert?


von Andreas (Gast)


Lesenswert?

Danke^^ Hab ich wohl nicht gesehen ;)

Wie wandle ich nun meine Empfangenen Daten in Dezimal um? Gibts da nen 
C-Befehl?

von Helfer (Gast)


Lesenswert?


von Helfer (Gast)


Lesenswert?


von Andreas (Gast)



Lesenswert?

Wunderbar!
Also hab jetzt mal mein Programm geschrieben und compiliert. Dabei 
treten zwei Warnungen auf.

Code ist im Anhang und Screenshot vom Buildstatus.

Könne mir jemand erklären was da nicht stimmt?

Danke

von Andreas (Gast)


Lesenswert?

Codekommentar ganz oben bitte nicht beachtet. Den hab ich von der 
seriellen Datenübertragung kopiert und den text noch nicht geändert.

von DirkB (Gast)


Lesenswert?

Die Warnungen sind doch ganz eindeutig
uart_gets erwartet bei Argument 1 einen anderen Pointer Typ.
1
void uart_gets (char* Buffer, uint8_t MaxLen)
Du hast aber
1
  
2
  int x;
3
  ...
4
  int Line [40];                        // Puffer für "Line" anlegen
5
  uart_gets( Line, sizeof (Line) / sizeof (Line[0] ));
Somit ist Line vom Typ int* und nicht char* wie erwartet.

Und Zeile 93:
1
  x = Line;
x ist ein int und Line ist ein Array. Das geht nicht.

von Karl H. (kbuchegg)


Lesenswert?

int Line [40];                        // Puffer für "Line" anlegen

  uart_gets( Line, sizeof (Line) / sizeof (Line[0] ));


Ähm.
uart_gets will ein char Array, in welches es den Text hineinlegt, den es 
empfangen hat! Text, nicht Zahl!


  x = Line;
Was versprichst du dir davon?


Dir scheint nicht klar zu sein, dass es in C Datentypen gibt, die nicht 
einfach nur so zum Spass existieren. Datentypen haben eine Berechtigung 
und einen Sinn.

Kauf dir ein C-Buch und arbeite es von Anfang an durch.

von DirkB (Gast)


Lesenswert?

Aber wenn ich mir das nochmal ansehen, denke ich du willst was anderes 
machen.

Wie werden denn die Daten gesendet (als Text oder gleich der Wert vom 
ADC)?

von Andreas (Gast)


Lesenswert?

@Karl Heinz Buchegger: Kannst du ein Buch empfehlen?

mit x = Line wollte ich den Text der in Line steht in die Variable x 
schreiben damit ich sie ASCII wandeln und an das LCD übergeben kann.


@ DirkB: Es wird der gemessene ADC Wert in Digits gesendet.

von DirkB (Gast)


Lesenswert?

Andreas schrieb:
> mit x = Line wollte ich den Text der in Line steht in die Variable x
> schreiben damit ich sie ASCII wandeln und an das LCD übergeben kann.

Wenn das sowieso ein Text ist, kannst du ihn auch gleich an das Display 
senden.
uart_gets ist zum empfangen von Text da.

Was verstehst du unter Digits?

Kennst du den Unterschied zwischen
1
char  a  =  4;
2
char  b  = '4';
3
char *c  = "4";
4
char d[] = "4";

von Karl H. (kbuchegg)


Lesenswert?

Andreas schrieb:
> @Karl Heinz Buchegger: Kannst du ein Buch empfehlen?

Den Klassiker

Kernighan & Ritchie
Programmieren in C

>
> mit x = Line wollte ich den Text der in Line steht in die Variable x
> schreiben damit ich sie ASCII wandeln und an das LCD übergeben kann.

http://www.mikrocontroller.net/articles/FAQ#Wie_funktioniert_String-Verarbeitung_in_C.3F

> @ DirkB: Es wird der gemessene ADC Wert in Digits gesendet.

Was KRIEGST du vom Sensor?
Kriegst du einen Text, in dem der Messwert enthalten ist, oder kriegst 
du den Messwert binär?

von Andreas (Gast)


Lesenswert?

Beides: Zuerst Text und dann den gemessenen Wert binär. (denk ich 
zumindest)

Gesendet wird das ganze mit der rprintf funktion

von Karl H. (kbuchegg)


Lesenswert?

Andreas schrieb:
> Beides: Zuerst Text und dann den gemessenen Wert binär. (denk ich
> zumindest)

Was heißt 'denk ich zumindest'?
Was sagt die Doku? Hast du das schon ausprobiert?
Hast du mit dem Mann gesprochen, der die Senderoutine geschrieben hat?

Wenn man nicht weiß, was man auf einer Leitung bekommt, dann hängt man 
die einfach mal an ein Terminal (zb Hyperterminal am PC oder HTerm auf 
dem PC) und sieht sich an, was da eigentlich daherkommt.

Solange man nicht weiß, wie das was auf der Leitung daherkommt konkret 
aussieht, kann man auch keine Empfangsroutine schreiben.

> Gesendet wird das ganze mit der rprintf funktion

Schön. Und?

von Andreas (Gast)


Lesenswert?

Ich hab die Schaltung noch nicht aufgebaut. Werd ich demnächst machen.

von Andreas (Gast)


Lesenswert?

Die Senor Routine hab ich selber geschrieben und die sollte auch 
funktionieren. Hat sie zumindest bis jetzt immer. Über Hyperterminal 
konnte ich alles lesen was ich vom µC an den PC gesendet habe. Ob das 
Text war oder ein Messwert. Funktionierte alles.

Wenn das sowieso ein Text ist, kannst du ihn auch gleich an das Display
senden.
uart_gets ist zum empfangen von Text da.

ja erst mal muss ich den Datensatz empfangen bevor ich ihn ans Display 
senden kann oder?

von DirkB (Gast)


Lesenswert?

Andreas schrieb:
> ja erst mal muss ich den Datensatz empfangen bevor ich ihn ans Display
> senden kann oder?

Dann brauchst du aber kein itoa mehr und du kannst Line als char 
Line[40] anlegen.
Wenn du die Zahl noch ändern willst brauchst du noch atoi().

... und auf alle Fälle ein C-Buch.
Wenn du schon Programmieren kannst (andere Sprache) auch von mir die 
Empfehlung zu Kernighan & Ritchie

Nochmal: kennst du den Unterschied?

von Andreas (Gast)


Lesenswert?

Nein den Unterschied kenn ich nicht. Erklärst dus mir?

Die grobe Programmierung klappt ganz gut. Nur meistens scheiters an so 
Feinheiten.

von DirkB (Gast)


Lesenswert?

Andreas schrieb:
> Nur meistens scheiters an so
> Feinheiten.

Das sind keine Feinheiten, das sind Grundlagen.

Nagut:
char  a  =  4;  // Die Variable a bekommt den Wert 4

char  b  = '4'; // Die Variable b bekommt den Wert für das Zeichen 4 
(bei ASCII ist das 52).

char d[] = "4";  // Das ist ein Feld mit 2 Elementen im 1. steht das 
Zeichen 4 und im 2. steht eine '\0' als Stringende. (Da 1. Element hat 
den Index 0)

char *c  = "4";  // Da ist ein Zeiger auf ein Array  wie bei d. Nur 
kannst du den Inhalt i.A nicht ändern, da es ein Stringliteral ist.

von Karl H. (kbuchegg)


Lesenswert?

Ausgangspunkt war das hier
1
char  a  =  4;
2
char  b  = '4';
3
char *c  = "4";
4
char d[] = "4";

vorausschicken sollte man, das in C ein char auch nur ein Datentyp ist, 
der eine kleine Zahl enthält. Nur wird er bei Ein/AUsgabe anders 
behandelt. Da wird die Zahl im char bereits als Zeichencode aufgefasst 
und es wird nicht versucht aus der Zahl eine Textrepräsentierung zu 
erzeugen. Ein char ist bereits seine Textrepräsentierung (vulgo ASCII 
Code)

1
char a = 4;
in a wird die Zahl 4 abgelegt

1
char b = 'b';
in b wird der ASCII Code des Zeichens 'b' abgelegt. Blick in eine ASCII 
Tabelle: 'b' hat den ASCII Code 98, also ist
   b = 'b';
völig gleichwertig zu
   b = 96;
Nur dass im ersten Fall der Compiler den ASCII Code raussucht, und im 
zweiten Fall du selber.
Übrigens ist auch
   b = 0x62;
dazu gleichwertig.
'b', 96, 0x62 ist alles dasselbe, nämlich ein Byte mit dem Bitmuster 
01010010

1
char *c  = "4";
Hier wird ein Pointer vereinbart, welcher auf einen konstanten Text 
(=String) zeigt. Wie jeder String besteht dieser Text aus einer Abfolge 
von Zeichen, die mit einem '\0' Byte enden. Das hier konstruiert also 
sowas

   c
  +-----+                   +---+---+
  |  o--------------------->|'4'| 0 |
  +-----+                   +---+---+

1
char d[] = "4";
Während die c-Lösung einen Pointer auf ein 'Array' von Zeichen (die 
nicht verändert werden dürfen) erzeugt, erzeugt das hier ein Array. d 
IST ein Array

   d
  +---+---+
  |'4'| 0 |
  +---+---+


Und nein: Das ist kein verzeihlicher Lapsus. Das sind alles Grundlagen 
ohne deren Beherrschung man in C nicht weit kommt.


http://www.mikrocontroller.net/articles/FAQ#Wie_funktioniert_String-Verarbeitung_in_C.3F

von Andreas (Gast)


Lesenswert?

Ich hab auch ned gesagt das ich die Grundlagen beherrsche. Ich mach das 
seit nem Jahr Hobbymäßig und versuch mir durch die Tutorials (welche zum 
teil nicht sehr hilfreich sind) das Wissen anzueignen. Wenn ich das 
schon so lange machen würde wie ihr dann würd ich mir den Fehler auch 
ned verzeihen...

von Karl H. (kbuchegg)


Lesenswert?

Andreas schrieb:
> Ich hab auch ned gesagt das ich die Grundlagen beherrsche. Ich mach das
> seit nem Jahr Hobbymäßig und versuch mir durch die Tutorials (welche zum
> teil nicht sehr hilfreich sind) das Wissen anzueignen.

Seit 1 Jahr?
Und in der Zeit bist du nie auf Strings gestossen oder hattest das 
Gefühl du bräuchtest ordentliche Unterlagen, die dir die Dinge von der 
Pieke auf beibringen.

OK, fürs Stammbuch:

Eine Sprache wie C kann man nicht ohne vernünftige Unterlagen erlernen. 
Dazu gibt es viel zu viele Fallen und Dinge die beachtet werden müssen!

> Wenn ich das
> schon so lange machen würde wie ihr

Weißt du, was ich tue, wenn ich mit einer Sprache arbeiten muss, die ich 
vorher noch nie programmiert habe:

Pfffffffft, ab in die nächste Buchhandlung und dort im Regal 
geschmökert, mit welchem Buch ich zurecht komme.
Danach mindestens 2 Wochen lesen und experimentieren und rumspielen und 
Übungen aus dem Buch machen.
Und erst danach geht es frühestens mit dem Projekt los.

Und ich bin jetzt seit 30 Jahren in der SW-Entwicklung.

von Andreas (Gast)


Lesenswert?

Da hast du recht aber dann beantwort mir doch mal die Frage für was 
dieses Forum dann gut ist?

Wenn ihr keine Anfänger hier haben wollt dann schreibt das auf die 
Startseite und passt.

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Karl Heinz Buchegger schrieb:
> Und ich bin jetzt seit 30 Jahren in der SW-Entwicklung.

Das ist der Unterschied zur Web2.0-Generation. Du weißt noch, was eine 
Buchhandlung ist, und Du kannst ein Buch bedienen.

von DirkB (Gast)


Lesenswert?

Andreas schrieb:
> Wenn ihr keine Anfänger hier haben wollt dann schreibt das auf die
> Startseite und passt.

Dir wurde doch geholfen. Sehr ausführlich.
Deine Probleme wurden gelöst und es gab Hinweise was du besser machen 
kannst.

von Helfer (Gast)


Lesenswert?

> Da hast du recht aber dann beantwort mir doch mal die Frage für was
> dieses Forum dann gut ist?

Die Motive sind so unterschiedlich wie die User, die das Forum besuchen.

Neben "Supporthotline" wären da noch: Abhängen, Bashen, Verkaufen, 
Kaufen, Geld verdienen, Tauschen, Zeigen, Gesehen werden, 
Selbstbestätigen, Neugier, Langweile, Polemisieren, Schwätzen, 
Diskutieren, Teachen...

> Wenn ihr keine Anfänger hier haben wollt dann schreibt das auf die
> Startseite und passt.

Anfänger sind willkommen. Man sieht es oft nicht auf den ersten Blick, 
ob jemand Anfänger ist. Und manche reagieren allergisch, wenn man ihnen 
sagt, dass sie Anfänger sind und ihnen Hinweise gibt wo die Lücken sind 
bzw. wie sie sie selbst beheben können. Die Teacher sind nur ein kleiner 
Teil der Usergemeinde und bei jeder Fragen alles von Null an zu 
erklären, übersteigt manchmal selbst deren Kraft.

von Andreas (Gast)


Lesenswert?

das Problem mit der ersten warning wurde gelöst. Und nach der "string 
copy" funktion mekkert der Compiler immer noch der gleiche Fehler.
Die String copy funktion nützt mir ja nichts da kopier ich nur den 
Inhalt eines Arrays in ein anderes Array...

Naja nix für ungut dann kauf ich mir eben n Buch

von Karl H. (kbuchegg)


Lesenswert?

Und das nächste was du lernen musst:

Wenn du eine Frage zum Code hast, dann ZEIGE deinen Code. Wenn du ihn 
(deiner Meinung nach) schon einmal gezeigt hast: macht nichts. Zeige ihn 
noch einmal. Denn in der Zwischenzeit hast du Änderungen vorgenommen.

Zb. kommt in deinem Code von oben kein strcpy vor. Also: Wovon, zum 
Teufel, sprichst du eigentlich?


Und wenn du mit "string copy" das hier meinst

  x = Line;

dann frag ich doch mal wozu denn hier eigentlich umkopieren willst?

Du kriegst von der USART einen String. Für die Ausgabe auf das LCD 
brauchst du einen String. Hmmmm  auf der einen Seite hast du einen 
String, auf der anderen Seite brauchst du einen String. Du hast einen 
String, die Ausgabefunktion braucht einen String. Du hast ....

Sagt dir das nichts?

wie wärs mit
1
...
2
3
 while(1)
4
 { 
5
  int Line [40];                        // Puffer für "Line" anlegen
6
 
7
  uart_gets( Line, sizeof (Line) / sizeof (Line[0] ));
8
9
  lcd_gotoxy(0,0);
10
  lcd_puts("Data receive:");             // Text auf LCD ausgeben
11
  lcd_gotoxy(0,1);
12
  lcd_puts( Line );                   // Bufferinhalt auf LCD ausgeben
13
 }

von Andreas (Gast)


Lesenswert?

So hab ichs ganz am anfang geschrieben. Eine Fehlerfreie Compilierung 
blieb aus.

warning: passing argument 1 of 'lcd_puts' from incompartible pointer 
type

von Karl H. (kbuchegg)


Lesenswert?

Andreas schrieb:
> So hab ichs ganz am anfang geschrieben. Eine Fehlerfreie Compilierung
> blieb aus.
>
> warning: passing argument 1 of 'lcd_puts' from incompartible pointer
> type

OK. Mein Fehler. Ich hab von oben einfach runterkopiert

Line muss natürlich ein char Array sein. Davon faseln wir ja 
schliesslich schon seit ein paar Postings, dass nicht jedes Array ein 
Array für Strings ist.

von Andreas (Gast)


Lesenswert?

Jetzt hat ers fehlerfrei compiliert.
Wobei ich das ganz am Anfang (vor meinem Post) auch so hatte und da 
gings dann wieder nicht.

Werd die Schaltung dann bald mal testen wenn sich Zeit findet. Ich geb 
dann Rückmeldung obs funktioniert.
Danke schon mal :)

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.