LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Linux - Newbie (https://www.linuxquestions.org/questions/linux-newbie-8/)
-   -   How do I read and write to /dev/ttyUSB0 in C? (https://www.linuxquestions.org/questions/linux-newbie-8/how-do-i-read-and-write-to-dev-ttyusb0-in-c-675382/)

LinuxTexan 10-09-2008 04:26 PM

How do I read and write to /dev/ttyUSB0 in C?
 
I have a device that uses the FTDI chip and connects OK. I modified the settings using stty without issue. I can send a file to it using "cat command_file.txt > /dev/ttyUSB0" and the device reacts to the command as I expect.

My problem is that I can't get my C code to communicate with it. I was trying to use fopen() and fprinf() to send my data but I'm not really sure that's what I should be using. The original C code works under Windows using standard Windows API calls. I'm trying to port the software to Linux and I don't fully understand why the file routines aren't working. Neither function returns an error.

johnson_steve 10-09-2008 05:55 PM

Well I'm not that great with C; I'm just learning myself but I do have the same FTDI device as you and I know that you should be able to use it just like a standard serial port, so take a look at some C tutorials for working with the serial port under linux and you should be able to get it working in no time :)

LinuxTexan 10-09-2008 06:02 PM

Well, duh. I found the open and read commands. It turns out /dev/ttyUSB0 was set to canonical mode as well. Changing these fixed it.

Sometimes you just have to whine for help and the answer comes to you.

Thanks, anyway.

LinuxTexan 10-09-2008 06:03 PM

Steve,
I responded before I saw your response. The 'duh' was meant at myself and not you. Thanks for your input.
Michael

johnson_steve 10-09-2008 06:16 PM

duh. I realise that. the open and close commands wirk with serial ports where as the fopen command is for files?

LinuxTexan 10-10-2008 08:58 AM

Yes. The open and close commands, along with read and write, are used with the low level hardware devices. Serial devices fall in that category. The fopen and etc. work on files only.

This little fact was detailed in my pocket C manual as a peculiarity with UNIX/Linux and is not part of ANSI C. I stumbled across that section purely by coincidence after my first post.

Revising my code to use the correct functions allowed me to talk to the device. Reading didn't work until I realized that canonical mode was on. Canonical mode is a fancy way of saying get data until an end of data of some sort occurs. Great for files, not so great for hardware. Turning canonical mode off means that data will be received a byte at a time or a timeout occurs which is more typical of device communications.

Sending "stty -F /dev/ttyUSB0 -icanon min 1 time 1" will make the device get at least one character or will stop and return to the program after 100 milliseconds. "time" increments in 0.1 second increments. You can set "min" to whatever mininum message length you require.

Hope this comes in handy for someone else.

serenissimus 11-10-2008 07:37 AM

FDTI same problem
 
Hello,

it seems someone else is having a similar problem. I have a FTDI chip based data collection device (DLPIO8), which I am trying to connect to a Ubuntu 8.04, 2.6 kernel machine.

I can see the device both on the system level and with a terminal program, and apparently also can write to it in C, but reading is difficult.

I tried canonical (as the device provides CR/LF pair terminated strings) but this does produce some irreproducible results. Therefore I would like to do raw mode and use the device in binary mode. However, I cannot figure out the serial comm settings required (basically it should be 115200, 8N1) but there are myriad other settings (I assume most critical are timeouts) apart from that.

May I ask LinuxTexan which settings you used ? Moreover it would be helpful if you could publish the termios parameters that you used for the device attributes.

thanks in advance.

s

johnson_steve 11-10-2008 09:55 AM

The FTDI chip should work at any speed, so you need to know what speed the hardware on the other end of the FTDI chip suports.

serenissimus 11-10-2008 03:05 PM

thx, in fact the serial comm settings seem to be allright, the terminal program works with the device. i can write to it, then get the answer string (in ASCII, canonical mode).

My problem is that I want to use bitmode and apart from 115200, 8N1 and canonical, there seems to be something else required for initialising the device properly in raw mode. I use a termios struct to initialize the device. I do not use stty. When reading the thread I was therefore wondering what other parameters were used. a program listing would be optimal.

s

LinuxTexan 11-11-2008 09:28 AM

I made it work this way:

1) I defined three variables for my app. I need to send up to 4 chars and receive up to 19. Obviously you will want to tailor this.:

int usbdev; /* handle to FTDI device */
char command[5]; /* buffer of data to send */
char response[20]; /* receive buffer */

1)I added a system call to my code using stty for 115200 Baud 8N1:
system("stty -F /dev/ttyUSB0 115200 cs8 -cstopb -parity -icanon min 1 time 1");

2) Later in my code I opened the device for reading/writing:
usbdev = open("/dev/ttyUSB0", O_RDWR);

3) I then used write to send, example uses 2 chars. These are defined prior to the call and can be any value from 0 to 255 for each char.:

write(usbdev, command, 2);

4) For receive, use the read command with the number of chars to receive, example uses 1:

read(usbdev, response, 1);

5) Add the following to close the device:

close(usbdev);


Hope this helps.

serenissimus 11-11-2008 12:37 PM

great,

that worked well, now I have to write some code to process & decode the binary output. I still fail to understand why the termios call did not work, but that is secondary now.

thank you for the quick & efficient help.

s

Disciple1102 07-22-2010 11:42 AM

I have the same problem as you all had, except I can't get what I have to work. I am using the same stty command that you used. It doesn't change anything.

I cant send a message and I know it is getting received ( an LED blinks to confirm the command ) However, I am not getting a response back.

I am using fopen instead of open. Open does the same exact thing in this case. By which I mean the message is getting sent but no response is being seen.

I have a java program that looks at the ports on the system and allows you to send messages and see the responses. Similar to portMon on windows. When I run this java program, my code that I wrote in C works. I cannot figure out why this is.

Can someone shed some light on this problem?

My code in short:

// Message to be sent
char message[] = { ... };

//change baud
system("stty -F /dev/ttyUSB0 115200 cs8 -cstopb -parity -icanon min 100 time 1");

//fopen file
FILE * ann = fopen("/dev/ttyUSB0", "r+");

// send message
fwrite( message, sizeof(char), 8, ann);

// read response
fread(rMessage, sizeof(char), 8, ann);



The code never makes it past the fread statement.

Sianur 11-24-2010 03:03 AM

Quote:

Originally Posted by Disciple1102 (Post 4042096)
// send message
fwrite( message, sizeof(char), 8, ann);

// read response
fread(rMessage, sizeof(char), 8, ann);

The code never makes it past the fread statement.

I had the same problem recently. In my case it was solved by adding a delay between writing a command and reading the responce for device to complete the operation.


All times are GMT -5. The time now is 07:47 AM.