Serial Verbindung auslesen keine Werte

Schnelle objektorientierte, kompilierende Programmiersprache.
Antworten
darkwin
Beiträge: 26
Registriert: So Aug 08, 2021 4:37 pm

Serial Verbindung auslesen keine Werte

Beitrag von darkwin » So Aug 08, 2021 5:31 pm

Hallo, eins vorweg ich habe wenig c Erfahrung möchte aber daran arbeiten.
Meine Erfahrung mit c habe ich bisher nur mit Arduino und ESP Chips gemacht.
Da man viel Code im Netz findet muss hier meist nur wenig am Code angepasst werden damit die kleinen Chips das machen was man will.

Die letzten Tage habe ich einiges über c gelesen und ausprobiert.
Nun würde ich gern ein Programm schreiben damit ich über eine Webseite meine Poolsteuerung steuern kann.
Die Steuerung lässt sich über eine Tastatur die einen kleinen Bildschirm hat steuern.
Die Kommunikation zwischen Steuerung und Tastatur läuft über rs422.
Ich habe mir deshalb einen RS422/485 USB Adapter gekauft und an einem Linux Rechner angeschlossen.

Setze ich auf der Bash folgenden Befehl ab:

Code: Alles auswählen

cat /dev/ttyUSB0
hier ein Ausschnitt:
fXSM�XMSkfXSM�XMSkfXSM�XMSkfXSM�XMSkfXSM�PeXMSkfXSM�PeXMSkfXSM�PeXMSkfXSM�PeXMSkfXSM�PeXMSkfXSM�PeXMSkfXSM�PeXMSkfXSM�PeXMSkfXSM�PeXMSk
Sehe ich die Kommunikation die zwischen Steuerung und Tastatur stattfindet.
Mit einem Serial Terminal sehe ich die Daten ebenfalls.

Da ich keine Ahnung habe wie ich die Serielle Schnittstelle auslese habe ich im Netz einige fertige Beispiele gefunden die ein paar Zeichen von der tty Schnittstelle lesen sollen und danach auf dem Terminal ausgeben.
Leider bekomme ich nicht das angezeigt das ich im Serial Terminal angezeigt bekomme.

Wenn ich das Programm Compiliere wird mir angezeigt das über 60 Zeichen gelesen wurden. Aber in read_buf scheint mit nichts gefüllt zu sein.

Wie kann es sein das in read_buf 62 Zeichen gefüllt sind aber printf nichts davon ausgibt?

Code: Alles auswählen

Read 62 bytes. Received message: 

Code: Alles auswählen

// C library headers
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
// Linux headers
#include <fcntl.h> // Contains file controls like O_RDWR
#include <errno.h> // Error integer and strerror() function
#include <termios.h> // Contains POSIX terminal control definitions
#include <unistd.h> // write(), read(), close()

int main() {
  // Open the serial port. Change device path as needed (currently set to an standard FTDI USB-UART cable type device)
  int serial_port = open("/dev/ttyUSB0", O_RDWR);

  // Create new termios struc, we call it 'tty' for convention
  struct termios tty;

  // Read in existing settings, and handle any error
  if(tcgetattr(serial_port, &tty) != 0) {
      printf("Error %i from tcgetattr: %s\n", errno, strerror(errno));
      return 1;
  }

  tty.c_cflag &= ~PARENB; // Clear parity bit, disabling parity (most common)
  tty.c_cflag &= ~CSTOPB; // Clear stop field, only one stop bit used in communication (most common)
  tty.c_cflag &= ~CSIZE; // Clear all bits that set the data size 
  tty.c_cflag |= CS8; // 8 bits per byte (most common)
  //tty.c_cflag &= ~CRTSCTS; // Disable RTS/CTS hardware flow control (most common)
  tty.c_cflag |= CREAD | CLOCAL; // Turn on READ & ignore ctrl lines (CLOCAL = 1)

  tty.c_lflag &= ~ICANON;
  tty.c_lflag &= ~ECHO; // Disable echo
  tty.c_lflag &= ~ECHOE; // Disable erasure
  tty.c_lflag &= ~ECHONL; // Disable new-line echo
  tty.c_lflag &= ~ISIG; // Disable interpretation of INTR, QUIT and SUSP
  tty.c_iflag &= ~(IXON | IXOFF | IXANY); // Turn off s/w flow ctrl
  tty.c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP|INLCR|IGNCR|ICRNL); // Disable any special handling of received bytes

  tty.c_oflag &= ~OPOST; // Prevent special interpretation of output bytes (e.g. newline chars)
  tty.c_oflag &= ~ONLCR; // Prevent conversion of newline to carriage return/line feed
  // tty.c_oflag &= ~OXTABS; // Prevent conversion of tabs to spaces (NOT PRESENT ON LINUX)
  // tty.c_oflag &= ~ONOEOT; // Prevent removal of C-d chars (0x004) in output (NOT PRESENT ON LINUX)

  tty.c_cc[VTIME] = 1;    // Wait for up to 1s (10 deciseconds), returning as soon as any data is received.
  tty.c_cc[VMIN] = 50;

  // Set in/out baud rate to be 9600
  cfsetispeed(&tty, B115200);
  cfsetospeed(&tty, B115200);

  // Save tty settings, also checking for error
  if (tcsetattr(serial_port, TCSANOW, &tty) != 0) {
      printf("Error %i from tcsetattr: %s\n", errno, strerror(errno));
      return 1;
  }
  //printf("Schreibe auf Serialport\n");
  // Write to serial port
  //unsigned char msg[] = { 'H', 'e', 'l', 'l', 'o', '\r' };
  //write(serial_port, "Hello, world!", sizeof(msg));

  // Allocate memory for read buffer, set size according to your needs
  char read_buf [64];

  // Normally you wouldn't do this memset() call, but since we will just receive
  // ASCII data for this example, we'll set everything to 0 so we can
  // call printf() easily.
  memset(&read_buf, '\0', sizeof(read_buf));

  // Read bytes. The behaviour of read() (e.g. does it block?,
  // how long does it block for?) depends on the configuration
  // settings above, specifically VMIN and VTIME
  int num_bytes = read(serial_port, &read_buf, sizeof(read_buf));

  // n is the number of bytes read. n may be 0 if no bytes were received, and can also be -1 to signal an error.
  if (num_bytes < 0) {
      printf("Error reading: %s", strerror(errno));
      return 1;
  }

  // Here we assume we received ASCII data, but you might be sending raw bytes (in that case, don't try and
  // print it to the screen like this!)
  read_buf[num_bytes] = '\0';
  printf("Read %i bytes. Received message: %s", num_bytes, read_buf);
  printf("\n");
  close(serial_port);
  
  return 0;  // success
}

Benutzeravatar
cloidnerux
Moderator
Beiträge: 3123
Registriert: Fr Sep 26, 2008 4:37 pm
Wohnort: Ram (Gibts wirklich)

Re: Serial Verbindung auslesen keine Werte

Beitrag von cloidnerux » So Aug 08, 2021 5:41 pm

Hi und Willkommen im Forum,

Das Problem ist höchst wahrscheinlich das eines deiner ersten Zeichen eine Null ist.
printf ist sehr primitiv. Wenn du einen Text(String) ausgeben willst, gibst du der Funktion den Pointer und printf wird so lange Bytes lesen und Versuchen auszugeben, bis es eine 0 findet, denn die 0 ist als Terminierungszeichen definiert.
Deswegen wird auch das letzte Bytes deines Empfangspuffers auf 0 gesetzt

Code: Alles auswählen

 read_buf[num_bytes] = '\0'
Damit printf nicht versucht deinen kompletten Speicher auszugeben.

Sinnvollerweise solltest du jedes Bytes als Zahl ausgeben, dann siehst du genau was kommt.
Redundanz macht wiederholen unnötig.
quod erat expectandum

darkwin
Beiträge: 26
Registriert: So Aug 08, 2021 4:37 pm

Re: Serial Verbindung auslesen keine Werte

Beitrag von darkwin » So Aug 08, 2021 7:15 pm

Hallo, Danke das war es.
Ich habe den read_buf als Hex ausgeben lassen und die Werte sind die gleichen die ich auch im Serial Monitor bekomme.

Das erste Zeichen ist nicht unbedingt eine 0 sondern die kommt im Stream immer mal wieder

Code: Alles auswählen

66 58 53 4D 0 3 1A 0 50 1 65 58 4D 53 0 3 6B 0 0 1 66 58 53 4D 0 3 1A 0 0 1 15 58 4D 53 0 3 6B 0 0 1 66 58 53 4D 0 3 1A 0 0 1 15 58 4D 53 0 3 6B 0 0 1 66 0

Josef Wismeth
Beiträge: 5
Registriert: So Sep 05, 2021 5:08 pm
Wohnort: Oberpfalz

Re: Serial Verbindung auslesen keine Werte

Beitrag von Josef Wismeth » Mo Sep 13, 2021 1:18 pm

Hallo Darkwin!
Ich versuchte im Dateianhang hier eine alte PDF-Datei zu Posten, die ich früher mal geschrieben habe.Serielle Schnittstellen
Hat hier nicht geklappt. Schade drum.

nufan
Wiki-Moderator
Beiträge: 2557
Registriert: Sa Jul 05, 2008 3:21 pm

Re: Serial Verbindung auslesen keine Werte

Beitrag von nufan » Mo Sep 13, 2021 2:01 pm

Josef Wismeth hat geschrieben:
Mo Sep 13, 2021 1:18 pm
Ich versuchte im Dateianhang hier eine alte PDF-Datei zu Posten, die ich früher mal geschrieben habe.Serielle Schnittstellen
Hat hier nicht geklappt. Schade drum.
Wenn ich deine Nachricht richtig verstehe, bist du hier auf ein Problem mit der Foren-Software gestoßen. Ich würde dich bitten dafür einen eigenen Thread aufzumachen (am besten hier: https://www.proggen.org/forum/viewforum.php?f=24). Falls du eine Fehlermeldung erhalten hast, würde uns diese auf jeden Fall bei der Behebung des Problems helfen.

Alternativ bist du natürlich herzlich eingeladen, dein Wissen auch in unserem Wiki zu teilen :)

Antworten