Forum: PC-Programmierung Zuviele Enter


Announcement: there is an English version of this forum on EmbDev.net. Posts you create there will be displayed on Mikrocontroller.net and EmbDev.net.
von Päät (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Moin an alle,

ich will eine UART Schnittstelle auf meinem PC auslesen und in einem 
File speichern
1
#include <stdio.h>
2
#include <fcntl.h>   /* File Control Definitions           */
3
#include <termios.h> /* POSIX Terminal Control Definitions */
4
#include <unistd.h>  /* UNIX Standard Definitions      */ 
5
#include <errno.h>   /* ERROR Number Definitions           */
6
7
void main(void) {
8
   ssize_t nrd;
9
   int fd;
10
   int fd1;
11
   char buffer[256];
12
13
   fd = open("/dev/ttyUSB1", O_RDONLY);
14
   fd1 = open("text.txt", O_CREAT | O_WRONLY); /*S_IRUSR | S_IWUSR*/
15
   while (nrd = read(fd,buffer,256)) {
16
      write(fd1,buffer,nrd);
17
   }
18
   
19
   close(fd);
20
   close(fd1);
21
}

Mein uC überträgt nach jeder Information ein "\n", soweit ist die 
Anzeige, wenn ich Minicom als Konsole benutze richtig. Mit meinem Code 
wird jetzt aber in der .txt-Datei zwei "\n" eingefügt. Nehm ich das "\n" 
aus dem Programmcode meines uC raus, habe ich keine Enter mehr drin.

Weiß jemand abhilfe?

Vielen Dank für alle konstruktiven und nicht konstruktiven Beiträge

Patrick

von wendelsberg (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Päät schrieb:
> Mit meinem Code
> wird jetzt aber in der .txt-Datei zwei "\n" eingefügt. Nehm ich das "\n"
> aus dem Programmcode meines uC raus, habe ich keine Enter mehr drin.
>
> Weiß jemand abhilfe?

Naheliegender Gedanke: Korrigiere das uC-Programm.

wendelsberg

von Päät (Gast)


Bewertung
0 lesenswert
nicht lesenswert
wendelsberg schrieb:
> Naheliegender Gedanke: Korrigiere das uC-Programm.

Nunja, ich verwende in meinem uC-Programm ein \n.
-wenn ich das nun weglasse, habe ich in meinem txt-File kein \n mehr 
drin.
-die Konsole zeigt es richtig an, bedeutet, in dem Programmcode muss 
irgendwo (vermutlich bei der read Stelle) ein weiteres \n eingefügt 
werden.

Patrick

von Luther B. (luther-blissett)


Bewertung
1 lesenswert
nicht lesenswert
/dev/ttyUSB0 ist ja nicht einfach die serielle Schnittstelle, sondern 
die serielle Schnittstelle als TTY - d.h. du hast möglicherweise 
Transformationen in input und output. Ich würde daher zuerst mal darauf 
tippen, daß daß der µC in Wirklichkeit '\r\n' am Zeilenende sendet und 
daß für /dev/ttyUSB das 'OCRNL' Flag aktiv ist (das übersetzt \r nach 
\n, was unter meiner Annahme zur Duplizierung führen würde). Du kannst 
ja mal nachgucken, was

$ stty -a -F /dev/ttyS0

ausgibt und ob da "ocrnl" steht (ohne Minus vorne dran).

In jedem Fall solltest du noch mal 
https://en.wikibooks.org/wiki/Serial_Programming/termios durchlesen, wie 
du diese Transformationen ein oder ausschalten kannst.

: Bearbeitet durch User
von wendelsberg (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Päät schrieb:
> bedeutet, in dem Programmcode muss
> irgendwo (vermutlich bei der read Stelle) ein weiteres \n eingefügt

Also schreibe Dir eine Dump-Ausgabe zwischen read und write.

wendelsberg

von Kopfschüttel (Gast)


Bewertung
-2 lesenswert
nicht lesenswert
Re: Zuviele Enter
Männliche Enten heissen Erpel, nicht Enter, auch im Plural.






zum tieferen Sinn dieses Postings:
Denkt doch einfach mal nach bevor ihr so unsinnige Betreffs schreibt. 
Siehe auch Netiquette und Forum-Fragenformulierung

von Dirk B. (dirkb2)


Bewertung
0 lesenswert
nicht lesenswert
Sind es wirklich zwei \n oder ist es \r\n ?

von Frank M. (ukw) (Moderator) Benutzerseite


Bewertung
0 lesenswert
nicht lesenswert
Luther B. schrieb:
> würde daher zuerst mal darauf tippen, daß daß der µC in Wirklichkeit
> '\r\n' am Zeilenende sendet und daß für /dev/ttyUSB das 'OCRNL' Flag
> aktiv ist (das übersetzt \r nach \n, was unter meiner Annahme zur
> Duplizierung führen würde).

Du meinst ICRNL, nicht OCRNL, denn schließlich nimmt der PC die Zeichen 
als Eingabe entgegen. Ausgegeben wird ja offenbar auf /dev/ttyUSB 
nichts.

Erklärung: Wenn der µC ein \r\n schickt, wird wegen ICRNL das erste 
Carriage-Return in \n verwandelt. Der PC sieht dann: \n\n.

@TO: Ja, Du musst /dev/ttyUSB in den Raw-Mode versetzen, sonst werden 
diverse Zeichen vom TTY-Driver gemapped. Google mal nach "tty raw mode" 
bzw. nach "man termios".

Gib mal ein der Shell ein:
1
stty -a </dev/ttyUSB

und poste hier den Output.

Folgende Input flags sollten mindestens gelöscht werden:

c_lflag: ISIG, ICANON, ECHO
c_iflag: ICRNL

Desweiteren solltest Du noch VMIN auf einen vernüftigen Wert setzen, 
z.B. 1. VTIME sollte auf 0, damit der Input blockiert, wenn keine 
Zeichen empfangen werden.

Danach wirst Du \r\n als Zeilentrenner erhalten, also weiterhin 2 
Zeichen und nicht eines. Wenn Du damit leben kannst, ist das okay. 
Schließlich hast Du dann eine Datei, wie sie auch Windows oder DOS 
speichern würden, da sie immer \r\n als Zeilentrenner in einer 
Text-Datei verwenden. UNIX/Linux benutzt nur \n, kann aber mit 
Windows-kompatiblen Dateien durchaus umgehen.

Wenn Du nur \n empfangen willst, musst Du das auf dem µC anpassen, indem 
Du das Senden von \r unterbindest, also nur das '\n' sendest. Oder Du 
änderst Deine simple read-write-Schleife derart ab, dass Du das \r auf 
dem PC herausfilterst:
1
while (nrd = read(fd,buffer,1))
2
{
3
    if (nrd > 0 && buffer[0] != '\r')
4
    {
5
        write(fd1,buffer,nrd);
6
    }
7
}

Wenn Dich hier stört, dass die Zeichen zeichenweise einzeln auf die 
Datei geschrieben werden, hier der Tipp: Nutze für Datei-I/O möglichst 
die stdio-Lib, also fopen/fputc statt open/write. stdio ist im Zweifel 
immer effizienter, als Du es mit open/write sein kannst, da es an das 
System angepasste Buffer-Strategien nutzt. Du kannst mit stdio immer 
guten Gewissens die Zeichen einzeln auf die Datei schreiben. Die 
stdio-Lib mapped das automatisch in Block-IO (z.B. in 1K-Blöcke). Falls 
Dich die größeren Blöcke jedoch wieder stören: "man fflush"

Es gibt also jede Menge Möglichkeiten.

: Bearbeitet durch Moderator
von Luther B. (luther-blissett)


Bewertung
0 lesenswert
nicht lesenswert
Frank M. schrieb:
> Du meinst ICRNL, nicht OCRNL, denn schließlich nimmt der PC die Zeichen
> als Eingabe entgegen. Ausgegeben wird ja offenbar auf /dev/ttyUSB
> nichts.

Ja, sorry, Richtungen verwechselt. ;)

von Rolf M. (rmagnus)


Bewertung
1 lesenswert
nicht lesenswert
Päät schrieb:
> #include <termios.h> /* POSIX Terminal Control Definitions */

Du bindest den termios-Header ein, benutzt aber nicht die Funktionen 
daraus. Siehe z.B:

https://en.wikibooks.org/wiki/Serial_Programming/termios

Päät schrieb:
> while (nrd = read(fd,buffer,256)) {
>       write(fd1,buffer,nrd);
>    }

Das führt bei einem Fehler zu einer Endlosschleife.

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]
  • [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.