Search code examples
cftdi

Reading serial data from c program is working partially


I want to read the content of a pen-drive data connected to a FTDI board through a c program. I have the following code using which I can read partial data but that also happens sometimes not every time I connect the board to PC. Can you please tell me what changes should be made to the code

#include<stdio.h>
#include<stdlib.h>
#include<fcntl.h>
#include<errno.h>
#include <termios.h>
#include <unistd.h>
#include<string.h>
int n = 0;
struct termios tty;
struct termios tty_old;


main()
{
    unsigned char buf[100];
    int fd;
    fd= open("/dev/ttyUSB0", O_RDWR| O_NOCTTY);

    if(fd>0)
    {
         printf("Port opened\n");
    }
    memset (&tty, 0, sizeof tty);
    printf("set attributes\n");
    /* Error Handling */
    if ( tcgetattr ( fd, &tty ) != 0 )
    {
        printf("Error from tcgetattr:%d \n",strerror(errno));
    }

    /* Save old tty parameters */
    tty_old = tty;
    memset(&tty,0,sizeof(tty));
        tty.c_iflag=0;
        tty.c_oflag=0;
    tty.c_lflag=0;


    /* Set Baud Rate */
    cfsetospeed (&tty, (speed_t)B9600);
    cfsetispeed (&tty, (speed_t)B9600);

    /* Setting other Port Stuff */
    tty.c_cflag     &=  ~PARENB;        // Make 8n1
    tty.c_cflag     &=  ~CSTOPB;
    tty.c_cflag     &=  ~CSIZE;
    tty.c_cflag     |=  CS8;

    tty.c_cflag     &=  ~CRTSCTS;       // no flow control
    tty.c_cc[VMIN]      =   1;                  // read doesn't block
    tty.c_cc[VTIME]     =   5;                  // 0.5 seconds read timeout
    tty.c_cflag     |=  CREAD | CLOCAL;     // turn on READ & ignore ctrl lines

    /* Make raw */
    cfmakeraw(&tty);


    /* Flush Port, then applies attributes */
    tcflush( fd, TCIFLUSH );
    if (tcsetattr (fd, TCSANOW, &tty) != 0)
    {
        printf("Error from tcsetattr:%d \n");
    }


    while(1)
    {
        printf("Do read and write\n");
        n = read(fd,&buf, sizeof buf);
        if (n < 0)
        {
            printf("Error reading:\n ");
            break;
        }
        else if (n == 0)
        {
                printf("Read nothing!\n");
            break;
        }
        else
        {
            buf[n]='\0';
            printf("%s",buf);
        }
    }   
}

Solution

  • As you are using an FTDI USB-to-serial converter, care must be taken in which order you connect the devices.

    After you connect the FTDI to the computer, the operating system sees a new serial device. Usually, this will make it try to handshake with the serial device (you can see that on some FTDI adapter boards on the blinking LEDs for rx/tx).

    However, your peripherial might not be able to deal with that handshake and gets into an inconsistent or unknown (to you) state.

    Thus it is important to first connect the FTDI to the computer and then connect the peripherial (your pen-drive) to the FTDI. This makes sure that the device does not see the handshake and your program can directly talk to it.