Forum: Mikrocontroller und Digitale Elektronik Serielle Schnittstelle auslesen


von derFragende (Gast)


Lesenswert?

Hallo zusammen!
Ich bin will gerade auf meinem PC eine serielle Schnittstelle einlesen 
und in ein File abspeichern.
Ich hab meinen C-Code auch schon mehrere Male überprüft. Fine aber nicht 
meinen Fehler. Ist ganz komisch. Mein Arduino schickt dauerhaft den Text 
"test123" und ich kann auch über die Konsole die Werte lesen (nicht 
gleichzeitig natürlich mit meinem Programm)
Aber mein Textfile bleibt leer.

Hat jemand eine Ahnung was ich falsch mache?
1
#include <stdio.h>
2
3
int main(void)
4
{
5
  char buffer[256];
6
7
  FILE *pWriteToFile;
8
  FILE * pFile;
9
  pFile=fopen ("/dev/ttyACM0", "r");
10
  pWriteToFile=fopen ("zybo.txt", "a");
11
12
  if(pWriteToFile==NULL)
13
  {
14
    perror ("Error opening zybo.txt file.");
15
  }
16
17
  if (pFile==NULL) perror ("Error opening /dev/tty file");
18
  else
19
  {
20
    while(1)
21
    {
22
23
      while(!feof(pFile)) {
24
  if(fgets(buffer, sizeof(buffer), pFile) != NULL) {
25
    fprintf(pWriteToFile, "%s", buffer);
26
  }
27
      }
28
    }
29
    return 0;
30
  }
31
}

von Jim M. (turboj)


Lesenswert?

Die C-Lib puffert, und leert den Puffer nur bei "\n", was in Deinem Fall 
nicht vorkommt. Die Puffer können recht groß sein - dann dauert es lange 
bis Daten im File auf der Disk ankommen.

Kann man umgehen mit
1
fflush(pWriteToFile);

von derFragende (Gast)


Lesenswert?

Ich habe jetzt denn fflush nach dem fprint eingefügt.
aber ich bekomme immer noch keine Daten....

von derFragende (Gast)


Lesenswert?

Vielleicht als kleine Ergänzung, ich vermute, dass die fgets-Funktion 
den Fehler hat. Weil wenn ich dort eine printf reinstecke, die nicht 
ausgegeben wird. Wenn ich diese vor das gets() setze, schon.
Aber mehrere Beispiele die ich gesehen habe, machen es genauso....

von Georg G. (df2au)


Lesenswert?

Vorschlag: Ein fclose() am Ende kann Wunder bewirken.

Und meine Definition von fgets() sagt, dass ein String eingelesen wird. 
Kennzeichen eines String ist das '\n' am Ende. Wenn das nicht kommt, 
wartet fgets() bis zum Sankt Nimmerleins Tag und sammelt dabei fröhlich 
Zeichen, rückt sie aber nicht heraus.

: Bearbeitet durch User
von derFragende (Gast)


Lesenswert?

Das fclose() habe ich ergänzt. Aber macht natürlich auch nichts.

Nach diesem Beispiel hier, mache ich es egl richtig.
https://www.tutorialspoint.com/c_standard_library/c_function_fgets.htm

von Georg G. (df2au)


Lesenswert?

Sende nicht "test123" sondern "test123\n".
(oder warte, bis der buffer überläuft, alternativ mach den buffer 
kleiner, 16 Bytes oder so)

: Bearbeitet durch User
von derFragende (Gast)


Lesenswert?

das letzte Zeichen, das ich übrigens vom Arduino sende ist ein \n.
Bringt bei fgets() trotzdem nichts.

Kann es ein Problem der Baudrate sein?

von Dirk B. (dirkb2)


Lesenswert?

Georg G. schrieb:
> wennn das nicht kommt,
> wartet fgets() bis zum Sankt Nimmerleins Tag und sammelt dabei fröhlich
> Zeichen, rückt sie aber nicht heraus.

Nö.
Wenn der Buffer voll ist, (die Parameter von fgets), dann kehrt fgets 
zürück.
An dem fehlenden \n im buffer kann man dann erkennen, das die Zeile 
nicht vollständig gelesen wurde.

Versuch mal Zeichenweise. Statt der while (1)
1
int c;
2
while ((c = fgetc(pFile)) != EOF)  
3
  fputc ( c , pFile );

von Georg G. (df2au)


Lesenswert?

derFragende schrieb:
> Kann es ein Problem der Baudrate sein?

Du hast geschrieben, dass du es mit einem Terminalprogramm richtig lesen 
kannst. Also stimmt die Baudrate. Es wäre aber dennoch guter Stil, am 
Anfang deines Programms die Baudrate explizit zu setzen.

Und noch ein Hinweis: Du gehst beim fprint() davon aus, dass im Buffer 
ein String ist, Nullterminiert, das ist aber nicht zwangsläufig so. Das 
Schreibergebniss kann also etwas seltsam werden.

Im Beitrag von 13:42 muss es natürlich "Zeile" und nicht "String" 
heissen.

: Bearbeitet durch User
von Volker B. (Firma: L-E-A) (vobs)


Lesenswert?

derFragende schrieb:
> (...) Mein Arduino schickt dauerhaft den Text
> "test123" und ich kann auch über die Konsole die Werte lesen (nicht
> gleichzeitig natürlich mit meinem Programm)
> Aber mein Textfile bleibt leer.

>   pFile=fopen ("/dev/ttyACM0", "r");

Wo setzt Du die Baudrate?

Grüßle
Volker

von Dirk B. (dirkb2)


Lesenswert?

Georg G. schrieb:
> Und noch ein Hinweis: Du gehst beim fprint() davon aus, dass im Buffer
> ein String ist, Nullterminiert, das ist aber nicht zwangsläufig so.

fgets sorgt dafür, das der String Nullterminiert ist.
Im Fehlerfall wird fprintf nicht aufgerufen.

von devzero (Gast)


Lesenswert?

Du verlaesst Dich darauf, dass das Device stets mit den richtigen 
Settings initialisiert ist.. wtf? termios.h inkludieren und Device 
konfigurieren.

von derFragende (Gast)


Lesenswert?

@Dirk B.
hat hervorragend geklappt! Merci vielmals!

Vielen Dank auch an den Rest fürs Gedankenmachen!

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.