mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik längerer Text per UART/falscher ansatz?


Autor: Christian Schreiber (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

ich versuche gerade eine Lüftersteuerung zu schreiben, die per Telnet 
den aktuellen Zustand(Temperatur/Lüfterdrehzahl) ausgibt und 
Einstellungen für die Regelung entgegennimmt.

Zur Ausgabe der Daten möchte ich per UART einfach Zeilenweise den Text 
senden. Da ich auch Zahlenwerte aus Variablen mitsenden möchte, habe ich 
mich für sprintf() entschieden.
Die Ausgabe läuft so ab:
char text[80];
//uart_putc(12);//FormFeed. Clearen des Terminals
sprintf(text,"\n\rWakue-Steuerung Version 0.91\n\r\n\r");
uart_putstring(text);
sprintf(text,"Temperaturen:\n\r");
uart_putstring(text);

Das Uart ist Interruptbasierend und ich hab die Funktionen von 
Roboternetz 
(http://www.roboternetz.de/wissen/index.php/UART_mi...). 
Dahinter steht ein FIFO Buffer, in den die zu sendene Zeichenkette 
geschoben wird und dann nach und nach gesendet wird.

Ich habe nur kommischerweise sehr Merkwürdiges Verhalten. Einige Teile 
werden problemlos ausgegeben, aber manchmal kommt nur Müll. Es ist auch 
teilweise so, dass der erste Teil wunderbar am Terminal ankommt und 2 
Zeilen später ist die Formatierung hin(teilweise mit Zeichen, die nicht 
da sein sollten)
Ich kann dabei aber kein Muster erkennen.

Z.B. erzeugt
sprintf(text,"Drehzahlregelung\n\r");
uart_putstring(text);
sprintf(text,"Bottom: 30C = 50p \n\rUpper: 60C = 100p\n\r");
im moment gerade
"Botto00p00Wakue-Steuerung Version 0.91) pDrae"
und andere Zeilen produzieren keinen output.

Bin ich vielleicht auf dem flaschen Weg? Gibts eine andere, einfachere 
Lösung? Oder sollte ich das Uart nicht Interruptgesteuert machen?

Danke schonmal für jeden Tipp, denn mir gehen langsam die Ideen aus.
Christian

Autor: Hansi Lein (fabian87)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
baudrate richtig?
hast du krasse störsender neben deiner leitung?

Autor: Christian Schreiber (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Bautrate ist richtig

Störsender.... hmm meinen Rechner, sonnst nichts

Christian

Autor: Chief Brady (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich habe die UART-Routinen nur überflogen, aber kann es sein, dass der 
FIFO zu klein ist? Soll heissen, kann es sein, dass du schneller Texte 
in den Buffer schreibst als gesendet werden können?

Ich würde zum Testen mal vor jedem 'uart_putstring(text)' eine 
Warteschleife einbauen.

Autor: Christian Schreiber (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
sehr guter Tipp ...

ich hab mal die Bufferlänge hochgesetzt und sieheda: die Fehler 
verschwinden. Nur muss ich jetzt meine uart routine umändern, denn ich 
kann ja nicht die Bufferlänge auf 300 bis 400 byte setzen.
Damit blockiere ich doch dann den ganzen Ram,oder sehe ich das falsch?

vielen Dank
Christian

Autor: Chief Brady (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich schätze mal, dein 'uart_putstring()' ist die 'uart_puts()' aus den 
UART-Routinen. In dieser wird 'uart_putc' verwendet, um die einzelnen 
Zeichen des Strings in den FIFO zu schreiben. 'uart_putc' gibt einen 
wert zurück, der angibt, ob das Zeichen in den FIFO geschrieben wurde 
oder ob der Puffer voll ist (steht so im Text). Dieser Wert wird aber 
nicht ausgewertet. Das funktioniert so nur mit kurzen Texten.

Wenn du genügend RAM hast, würde ich den Puffer schrittweise 
vergrössern, bis es passt. 300 Byte weden wohl nicht gebraucht, denke 
ich. Ich tippe mal so auf 60 Byte.

Alternativ kannst du natürlich den Return-Wert von 'uart_putc' auswerten 
und immer warten, bis der FIFO wieder frei ist.
CB

Autor: Christian Schreiber (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ja, meine uart_putstrin() ist die uart_puts() ich fand, dass muss man 
zur besseren Kennzeichnung umbennenen.

Ich hab mich durch die Funktionen gekwühlt und hab das ganze anders 
gelöst.
ich hab die uart_putc() um folgendes erweitert

fifo_t *fn = &outfifo;
while(fn->count >= fn->size){;};

also die Abbruchbedingung aus dem Fifo verwendet.
so wartet er nun, wenn der Buffer voll ist. Ich denke, so ist es am 
einfachsten, da ich mir keine Gedanken über die Auswertung machen muss.

Ich würd es ja auch im RN angeben, doch irgendwie hab ich keine Lust 
mich da jetzt erst groß anzumelden.

Aber dir erstmal vielen Dank
hast mein Wochenende gerettet :)
Christian

Autor: Chief Brady (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> hast mein Wochenende gerettet :)
bitte bitte...


Ich hätte dass vielleicht so gemacht:

Die Zeile

  int ret = fifo_put (&outfifo, c);

in 'uart_putc' ersetzt durch

  int ret;
  do
  {
    ret = fifo_put (&outfifo, c);
  }
  while (ret=0);

Sollte doch auch gehen, oder? Aber wenn deine Lösung funktioniert...

BC

Autor: Christian Schreiber (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
also zu aller erst, ich will nicht besserwisserisch sein, nur zum 
Verständniss, aber ich glaube nicht,
denn es wird immer zuerst einmal versucht das Zeichen in den Buffer zu 
schieben. Schlägt das fehl, ist das Zeichen verlohren.
Es geht gut, bis einmal -1 zurückgeliefert wird.
dann bricht die Schleife ab, und das Zeichen wird verworfen, oder?
Also verhindert die Schleife zwar effektiv den Überlauf des Puffers, 
doch die Ausgabe wird dennoch verfälscht.

Oder liege ich da gerade daneben?
Christian

Autor: Chief Brady (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Es wird versucht, ein Zeichen in den FIFO zu schreiben

 ret = fifo_put (&outfifo, c);

Wenn ret 0 ist, war der FIFO voll und es wird weiter versucht, bis ret 
nicht mehr 0 ist

  while (ret=0);

ret wird 1, wenn das Zeichen im FIFO ist. Warum sollte das Zeichen 
verloren gehen? Ich denke nicht, das die Routine fifo_put das Zeichen 
('c') ändert (weiss ich allerdings nicht, da ich fifo.h nicht kenne)

CB

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ein Returnwert beim Senden ist Blödsinn, wer soll den denn auswerten ?

Eine Sende-FIFO muß einfach immer solange warten, bis wieder Platz im 
Puffer ist. Nur so geht nichts verloren.


Eine andere Möglichkeit wäre noch eine Funktion, die die aktuelle freie 
Pufferlänge zurückgibt.
Dann kann man mit der Ausgabe solange warten, bis auch genügend Platz 
ist und die Zwischenzeit anderweitig nutzen.
Trotzdem sollte die Sendefunktion warten, falls man sich mal mit der 
benötigten Paketlänge verschätzt hat.


Lieber die Daten etwas später senden, als total falsch.


Peter

Autor: Chief Brady (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Eine Sende-FIFO muß einfach immer solange warten, bis wieder Platz im
> Puffer ist. Nur so geht nichts verloren.

Ja, aber genau dieses warten ist anscheinend nicht implementiert, was 
ich mit meinem Vorschlag nachholen wollte. Oder übersehe ich da 
irgendetwas?

Autor: Christian Schreiber (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Nabend

ich glaub ich lag falsch.
Ich bin davon ausgegangen, dass -1 zurückgeleifert wird, wenn die 
Funktion nicht erfolgreich war, deshalb hats keinen Sinn für mich 
gemacht.

Hast also Recht.
Habs aber so implementiert, wie oben und es läuft soweit.

Wünsch euch noch ne gute Nacht und danke :)
Christian

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.