Linux RS232



  • Hallo liebes Forum,

    diese Woche hat ein Roboter hier spontan eine digitale Anzeige bekommen, die 4 Zeichen ausgeben kann. Angeschlossen wird diese über RS232.

    Komm-Protokoll ist ganz einfach:
    Senden: 0-4 ASCII Zeichen + ein CR
    Empfangen: ACK = 0x06 NAK = 0x15

    Wenn ich die Anzeige an mein Notebook anschließe, kann ich einen String übertragen und empfange anschließend 0x06. Alles super.

    Am IPC verhält sich das gleiche Programm anders. Ich kann den String senden, die Anzeige verhält sich wie erwartet, aber die read-Methode blockiert ewig und empfängt weder ACK noch NAK.

    Woran könnte das liegen?

    (Das Programm ist etwas C-Code, das ich mir mit Hilfe von Google zusammen gefummelt habe)

    Viele Grüße,
    anjohn



  • Hier ist ein funktionierendes Code-Beispiel, wie man ein LED-Anzeigesystem von WeTelCo über RS232 ansteuern könnte. Vielleicht braucht es irgendwann mal jemand.

    Rückgabewerte überprüfen und Fehler abfangen fehlt größtenteils. Auch sollte man die bestehenden Einstellungen in einem termios struct abspeichern und beim Schließen des Ports wiederherstellen.

    Das könnt ihr selber machen 😛

    #include <stdio.h>   /* Standard input/output definitions */
    #include <string.h>  /* String function definitions */
    #include <unistd.h>  /* UNIX standard function definitions */
    #include <fcntl.h>   /* File control definitions */
    #include <errno.h>   /* Error number definitions */
    #include <termios.h> /* POSIX terminal control definitions */
    
    /*
     * 'open_port()' - Open serial port 1.
     *
     * Returns the file descriptor on success or -1 on error.
     */
    
    int open_port(void)
    {
    	int fd; /* File descriptor for the port */
    
      fd = open("/dev/ttyS0", O_RDWR | O_NOCTTY | O_NDELAY);
      if (fd == -1)
      {
    	 /*
    		* Could not open the port.
    		*/
    
    		perror("open_port: Unable to open /dev/ttyS0 - ");
      }
      else {
    		fcntl(fd, F_SETFL, 0);
    		//fcntl(fd,F_SETFL, FNDELAY);
    	}
    
      return (fd);
    }
    
    int write_to_port(int fd) {
    	int n=-1;	
    	n = write(fd, "111,5\r", 6);
      if (n < 0)
      	fputs("write() of 6 bytes failed!\n", stderr);
    }
    
    int close_port(int fd) {
    	int ret = close(fd);
    	if (ret != 0) {
    		printf("close returned %d", ret);
    	}
    }
    
    int initialize_com(int fd) {
    	struct termios options;
    
        /*
         * Get the current options for the port...
         */
    
        tcgetattr(fd, &options);
    
        /*
         * Set the baud rates to 9600...
         */
    
        cfsetispeed(&options, B9600);
        cfsetospeed(&options, B9600);
    
        /*
         * Enable the receiver and set local mode...
         */
    
        options.c_cflag |= (CLOCAL | CREAD);
    
    		/*
    		 * Set 8 data bits, 0 parity bit, 1 stop bit 		
    		 */
    
    		options.c_cflag &= ~PARENB;
    		options.c_cflag &= ~CSTOPB;
    		options.c_cflag &= ~CSIZE;
    		options.c_cflag |= CS8;
    
    		/*
    		 * Disable flow control
    		 */
    
    		options.c_iflag &= ~(IXON | IXOFF | IXANY);
    
    		/*
    		 * Disable hardware handshakes
    		 */
    
    		options.c_cflag &= ~CRTSCTS;
    
    		/*
         * Set to raw input/output
         */
    
    		options.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);
    		options.c_oflag &= ~OPOST;
    
    		/*
         * Set the new options for the port...
         */
    
    		/* 
    		 * Don't wait for any communication to finish
    		 */
    
        tcsetattr(fd, TCSANOW, &options);
    		//tcsetattr(fd, TCSADRAIN, &options);
    
    		return 0;
    }
    
    int read_from_port(int fd) {
    	ssize_t s;
    	char byte[256];
    	s = read(fd,byte,255);
    	if (s>0) {
    		printf("Read %x from port!\n", byte[0]);
    	}
    	else {
    		printf("Error reading from port!\n");
    	}
    	return 0;
    }
    
    int main() {
    	int fd = open_port();
    	if (fd > 0) {
    		initialize_com(fd);
    		printf("Writing character\n");
    		write_to_port(fd);
    		printf("Character written\n");
    		printf("Wating for character...\n");
    		read_from_port(fd);
    		close_port(fd);
    		printf("Port closed\n");
    	}
    
    	return 0;
    }
    

Anmelden zum Antworten