Thread: read write serial port

  1. #1
    Registered User
    Join Date
    Apr 2013
    Posts
    66

    read write serial port

    Hello guys, i have a code which used to connect my hardware through the USB port. Sending data in HEX format and when the hardware reply or gives out an output, it will direct go to a .txt file.

    PROBLEM: Sometimes the output data from the hardware is correct and sometimes not. seems like i'm missing something like flushing/cleaning something before any process is done. please do point which line and how to solve it. Thanks in advanced. Below is the code:

    Code:
     #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 */
     #include <stdlib.h>
    
     /*
      * '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/ttyUSB0", O_RDWR | O_NOCTTY | O_NDELAY);
    
       if (fd < 0) {                                              /* Could not open the port */
         fprintf(stderr, "open_port: Unable to open /dev/ttyUSB0 - %s\n",
                 strerror(errno));
       }
    
       return (fd);
     }
    
    void main()
    {
     int mainfd=0, i;                                            /* File descriptor */
     char cnt, result2;
     unsigned char result,chout;
     struct termios options;
     FILE *fp;
       
     mainfd = open_port();
    
     fcntl(mainfd, F_SETFL, FNDELAY);                  /* Configure port reading */
                                         /* Get the current options for the port */
     tcgetattr(mainfd, &options);
     cfsetispeed(&options, B19200);                 /* Set the baud rates to 19200 */
     cfsetospeed(&options, B19200);
        
                                       /* Enable the receiver and set local mode */
     options.c_cflag |= (CLOCAL | CREAD);
     options.c_cflag &= ~PARENB; /* Mask the character size to 8 bits, no parity */
     options.c_cflag &= ~CSTOPB;
     options.c_cflag &= ~CSIZE;
     options.c_cflag |=  CS8;                              /* Select 8 data bits */
     options.c_cflag &= ~CRTSCTS;               /* Disable hardware flow control */  
     
                                     /* Enable data to be processed as raw input */
     options.c_lflag &= ~(ICANON | ECHO | ISIG);
           
                                            /* Set the new options for the port */
     tcsetattr(mainfd, TCSANOW, &options);
     
     tcflush(mainfd, TCIOFLUSH); // Clear both the input and output buffers.
    
     result2 = tcsetattr(mainfd, TCSANOW, &options);
     if ( result2 == -1 ) { perror("error: tcsetattr"); }
     if ( result2 != 0 ) { fprintf(stderr,"error in tcsetattr, result = %d\n", result2); }
    
     
    
     result2 = write(mainfd,"\xF5\x23\x00\x00\x00\x00\x23\xF5",8);
     if ( result2 == -1 ) { perror("error: write"); }
     if ( result2 != 8 ) { fprintf(stderr,"error in write, result = %d\n", result2); }
      
     usleep(3000000);      /* wait for 3 second*/
    
    
    
     fp = fopen("results_eigenvalue.txt", "w");   /*open and write into existing file*/
    
     for(i=0;i<207;i++)
    {
     result = read(mainfd, &chout, sizeof(chout));          /* Read character from ABU (Auto buffering Unit) */
     if ( result == -1 ) { perror("error: read"); }
      if ( i >= 12){
        fprintf(fp,"%d ",chout); }
    
    }      
    
                                           
      close(mainfd);        /* Close the serial port */
     }

  2. #2
    Registered User
    Join Date
    Aug 2005
    Location
    Austria
    Posts
    1,990
    Code:
    fprintf(fp,"%d ",chout);
    Your format "%d" doesn't match the type of chout ( unsigned char ).
    if you want to write chout as an int to the file then you should cast it to int
    e.g.
    Code:
    fprintf(fp,"%d ",(int)chout);
    Kurt

  3. #3
    Registered User
    Join Date
    Apr 2013
    Posts
    66
    Quote Originally Posted by ZuK View Post
    Code:
    fprintf(fp,"%d ",chout);
    Your format "%d" doesn't match the type of chout ( unsigned char ).
    if you want to write chout as an int to the file then you should cast it to int
    e.g.
    Code:
    fprintf(fp,"%d ",(int)chout);
    Kurt
    Done. Thanks Kurt, but the problem is still the same.

  4. #4
    Registered User
    Join Date
    Nov 2011
    Posts
    161
    Sometimes working, sometimes not sounds more like path then software. Have you tried lower baud rates?

  5. #5
    Registered User
    Join Date
    May 2010
    Posts
    4,632
    Are you sure you're actually reading something in this snippet:
    Code:
     for(i=0;i<207;i++)
    {
     result = read(mainfd, &chout, sizeof(chout));          /* Read character from ABU (Auto buffering Unit) */
     if ( result == -1 ) { perror("error: read"); }
      if ( i >= 12){
        fprintf(fp,"%d ",chout); }
     
    }
    It is possible that read returned without reading a byte. You should check the return value from read() to insure it did in fact read the correct number of bytes from the port. When dealing with serial ports reading an improper number of bytes is not necessarily a failure.

    You may want to insure the port timeout values are set properly.

    Another option might be to open the port in blocking mode instead of non-blocking, which I don't really recommend.

    Jim

  6. #6
    Registered User
    Join Date
    Apr 2013
    Posts
    1,658
    Why did you disable the hardware flow control?

  7. #7
    Registered User
    Join Date
    Nov 2009
    Location
    Maryland, USA
    Posts
    46
    Quote Originally Posted by rcgldr View Post
    Why did you disable the hardware flow control?
    Flow control is a throwback to the days of the teletype. I don't think it's every any more useful than a 5-bit word size.

    Quote Originally Posted by jimblumberg View Post
    It is possible that read returned without reading a byte.
    Good point.

  8. #8
    Registered User
    Join Date
    May 2010
    Posts
    4,632
    Flow control is a throwback to the days of the teletype. I don't think it's every any more useful than a 5-bit word size.
    Not necessarily true. If you're receiving a lot of data and high speeds, especially on a busy machine, flow control can be a useful tool, but only if both sides of the link support flow control.

    Jim

  9. #9
    Registered User
    Join Date
    Apr 2013
    Posts
    66
    Quote Originally Posted by FloridaJo View Post
    Sometimes working, sometimes not sounds more like path then software. Have you tried lower baud rates?
    No but the baudrate i used is specified in the hardware user manual.

  10. #10
    Registered User
    Join Date
    Apr 2013
    Posts
    66
    Quote Originally Posted by jimblumberg View Post
    Are you sure you're actually reading something in this snippet:
    Code:
     for(i=0;i<207;i++)
    {
     result = read(mainfd, &chout, sizeof(chout));          /* Read character from ABU (Auto buffering Unit) */
     if ( result == -1 ) { perror("error: read"); }
      if ( i >= 12){
        fprintf(fp,"%d ",chout); }
     
    }
    It is possible that read returned without reading a byte. You should check the return value from read() to insure it did in fact read the correct number of bytes from the port. When dealing with serial ports reading an improper number of bytes is not necessarily a failure.

    You may want to insure the port timeout values are set properly.

    Another option might be to open the port in blocking mode instead of non-blocking, which I don't really recommend.

    Jim
    I've check the return value from read many times and it does return the correct number of bytes returned. The problem is the content of the returned value. sometimes i et the correct value and sometimes not. The format of the output was correct.

  11. #11
    Registered User
    Join Date
    Apr 2013
    Posts
    66
    Quote Originally Posted by rcgldr View Post
    Why did you disable the hardware flow control?
    I don't really know how to use it and the hardware user manual doesn't mention anything about it. I did thought of using it but no sure how.

  12. #12
    Registered User
    Join Date
    Apr 2013
    Posts
    1,658
    Quote Originally Posted by rcgldr View Post
    Why did you disable the hardware flow control?
    Quote Originally Posted by Marvin Gorres View Post
    I don't really know how to use it and the hardware user manual doesn't mention anything about it. I did thought of using it but no sure how.
    The hardware handshake should prevent receiver overrun errors. Try setting it to enabled and see if the program still works or if this fixes anything. If not, you can always change the code back and disable the hardware handshake.

  13. #13
    Registered User
    Join Date
    May 2010
    Posts
    4,632
    The hardware handshake should prevent receiver overrun errors.
    Only if both receiver and transmitter are capable of handshaking. Also the cabling must also have the proper connections to enable hardware handshaking.

    Jim

  14. #14
    Registered User
    Join Date
    Nov 2009
    Location
    Maryland, USA
    Posts
    46
    Quote Originally Posted by rcgldr View Post
    The hardware handshake should prevent receiver overrun errors.
    That's the theory, but we're mimicking a UART here so the hardware doesn't do it. The handshaking signal can only cause an interrupt and then it's up to software to stop sending. And it's up to software to notice the buffer's getting full and set the handshaking signal in the first place.

    But the maximum rate that most UARTs can send is a 115.2Kbps. Even the tiniest modern microcontroller can receive that rate without overflow, assuming interrupts aren't disabled too long, and if they are then handshaking wouldn't work anyway. And we're only doing 19.2Kbps here.

    The real reason they used handshaking was that an extra few bytes of RAM for a buffer was very expensive, so they absolutely had to process (e.g. print on the teletype) all data as it was received.

  15. #15
    Registered User
    Join Date
    Apr 2013
    Posts
    1,658
    Quote Originally Posted by KenJackson View Post
    That's the theory, but we're mimicking a UART here so the hardware doesn't do it.
    OK, so this is not a UART that uses CTS (clear to send) and RTS (request to send) like protocol (like RS232).

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Write to serial port
    By sombrancelha in forum C++ Programming
    Replies: 14
    Last Post: 06-01-2012, 08:08 AM
  2. Serial port read/write problem
    By ojaro in forum C Programming
    Replies: 5
    Last Post: 06-25-2010, 08:26 AM
  3. Can't Read From Serial Port
    By HalNineThousand in forum Linux Programming
    Replies: 14
    Last Post: 03-20-2008, 05:56 PM
  4. How to read from a serial port
    By WDT in forum C++ Programming
    Replies: 6
    Last Post: 05-10-2004, 06:31 AM
  5. read from and write to serial port
    By wazilian in forum Networking/Device Communication
    Replies: 3
    Last Post: 04-25-2004, 08:22 AM