Find the answer to your Linux question:
Results 1 to 7 of 7
Hello! I'm not sure if this goes here because is my first thread. I have a problem with some program that tries to send and receive info through serial port ...
  1. #1
    Just Joined!
    Join Date
    Nov 2011
    Posts
    6

    Serial communication

    Hello! I'm not sure if this goes here because is my first thread. I have a problem with some program that tries to send and receive info through serial port (virtual). I need to send 2 commands and I can do it properly but then I need to read info buf the program gets blocked...

    The code is here
    Code:
    #include <stdio.h> // standard input / output functions
    #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 definitionss
    #include <time.h>   // time calls
    
    int open_port(void)
    {
    	int fd; // file description for the serial port
    	fd = open("/dev/ttyUSB0", O_RDWR | O_NOCTTY | O_NDELAY);
    	return(fd);
    }
    
    int configure_port(int fd)      // configure the port
    {
    	struct termios port_settings;      // structure to store the port settings in
    
    	cfsetispeed(&port_settings, B19200);    // set baud rates
    	cfsetospeed(&port_settings, B19200);
    
    	port_settings.c_cflag &= ~PARENB;    // set no parity
    	port_settings.c_cflag &= CSTOPB;     // 2 stop bytes
    	port_settings.c_cflag &= CREAD; 
    	port_settings.c_cflag &= CLOCAL;
    	port_settings.c_cflag &= ~CSIZE;     //8 bites of data 
    	port_settings.c_cflag |= CS8;      
    
    	tcsetattr(fd, TCSANOW, &port_settings);    // apply the settings to the port NOW
    	return(fd);
    
    }
    
    int read_info(int fd)   // query modem with an AT command
    {
            char datos[10];
    	char command = 0x53, address=0x52,size=0x07;
    	sprintf(datos,"%c%c%c", command,address,0x57);
    	write(fd,datos,3); 
    	sleep(1);
    	printf("Frist write issued");
    	command = 0x54, address=0x53;
    	sprintf(datos,"%c%c%c", command,address,size);
    	write(fd,datos,3); 
    	printf("Second write issued");
    	int rd = read(fd,datos,7);//Here is the trouble!
    	int i;
    	for(i=0;i<10;i++) {printf("Datos[%d]: %c\n",i,datos[i]);}
    
    }
    int main(void)
    {
    	int fd = open_port();
    	configure_port(fd);
    	printf("PORT PREPARED!\n");
    	read_info(fd);
    	return(0);
    }
    I hope somebody can tell me what I'm doing wrong... and I have to say that the writing was okey so the parameters seem to be right too.

  2. #2
    Linux Newbie
    Join Date
    Mar 2010
    Posts
    121
    You mean it blocks indefinitely? For a non-blocking file descriptor to a terminal in canonical mode (which is what you have) it will block until it reads a complete line. Is the end you're reading from sending a

  3. #3
    Just Joined!
    Join Date
    Nov 2011
    Posts
    6
    Yes, it blocks forever. Maybe I'm using something wrong so I'll explain what the program is doing...

    The frist command says "I'm going to check your status", the second says "Adress 0x53 read 7 bytes" and then the device fills its buffer with the info I need to get, so I read it this way. Probably the problem is that, as soon as it's not a modem, it dosen't send carriage return, could be that?

  4. #4
    Linux Newbie
    Join Date
    Mar 2010
    Posts
    121
    Possibly - like I said, unless you tell the device otherwise, it will wait for a complete line of text before passing you the data.

    On the other hand, I also notice you don't check the return values of any of the functions you call for errors - this is a programming error. For all you know, you may simply not have permission to open the device. Also, your comments say you're using AT commands, but all the AT commands I've used need carriage return/line feed after them, but you don't seem to be sending them.

    If all else fails, have you tried using minicom to send the commands directly?

  5. #5
    Just Joined!
    Join Date
    Nov 2011
    Posts
    6
    Well, you are right, I don't check errors properly but I know the device recieves them because a led blinks when you do it,by the way I will fix that later. The device is a USB to I2c converter that works as a virtual COM port so I use commands especific to this device, not AT. By this reason I don't need to send carriage return to end a command, only to follow the proper format.

    So the problem seems to be that the read function is expecting carriage return to end transimision and unblock, do you know how can we solve it?

    Thx for your help.

  6. #6
    Just Joined!
    Join Date
    Nov 2011
    Posts
    6
    Any suggestions? Please!

  7. #7
    Linux Newbie
    Join Date
    Mar 2010
    Posts
    121
    Have you tried disabling canonical mode? To do this, clear the ICANON flag in c_lflag before setting the port settings. Other than that, get a serial comms program like minicom and see what it shows you about what's happening on the wire.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
...