Serial Device: Reading 8N1 works, but writing a single byte fails - c

In my program I read from the serial device (Linux, 8N1) without any problem. But in the case I want to write out a single byte, I get nothing out on the interface. I assume that my serial output settings are wrong. But there aren't that many ways how to set c_oflag...
My code:
#define TTYDEVICE "/dev/ttyS0"
#define BAUDRATE B9600
int openSerialDevice(const char* devTTY, struct termios oldTio) {
//----< Open serial device >----------------------------------
int fileDescriptor;
// fd = open("/dev/ttyS0", O_RDWR | O_NOCTTY | O_NDELAY);
fileDescriptor = open(devTTY, O_RDWR | O_NOCTTY);
//fileDescriptor = open(devTTY, O_RDWR | O_NOCTTY /*| OPOST*/);
if (fileDescriptor == -1) {
perror("Error while opening serial interface occurred!");
return -99;
}
// set new parameters to the serial device
struct termios newtio;
bzero(&newtio, sizeof(newtio));
newtio.c_cflag = BAUDRATE | CRTSCTS | CS8 | CLOCAL | CREAD;
// set to 8N1
newtio.c_cflag &= ~PARENB;
newtio.c_cflag &= ~CSTOPB;
newtio.c_cflag &= ~CSIZE;
newtio.c_cflag |= CS8;
newtio.c_iflag = IGNPAR;
// output mode to
//newtio.c_oflag = 0;
newtio.c_oflag |= OPOST;
/* set input mode (non-canonical, no echo,...) */
newtio.c_lflag = 0;
newtio.c_cc[VTIME] = 10; /* inter-character timer 1 sec */
newtio.c_cc[VMIN] = 0; /* blocking read disabled */
tcflush(fileDescriptor, TCIFLUSH);
if (tcsetattr(fileDescriptor, TCSANOW, &newtio)) {
perror("could not set the serial settings!");
return -99;
}
//----< / Open serial device >----------------------------------
return fileDescriptor;
}
int ACK[1] = { 6 };
int main() {
// old termios to restablish
struct termios oldTIO;
// filedescriptor
int fd;
fd = openSerialDevice(TTYDEVICE, oldTIO);
if ((fd == -1) | (fd == -99)) {
perror("Could not open TTY-Device. Exit on failure!");
return EXIT_FAILURE;
}
write(fd, ACK, 1); // Problem !!
return 0:
}
Now, if I use
screen /dev/ttyS1 9600 8n1
to verify what's coming out on /dev/ttyS0. I can't see anything. Same if I sniff with Docklight 1.8.
Any suggestions? thanks

How do you verify nothing is coming out ?
You can try to drop the RTSCTS, and try again. Infact, if you want minimal interference from the tty layer, you should set your terminal to raw, using this :
cfmakeraw(&newtio);

You're giving write() the data argument of ACK, which is a pointer to int. This is probably not what you mean. Depending on the endianness of the computer you're on, this means write() will "see" a buffer containing the chars { 6, 0, 0, 0 } (little-endian) or { 0, 0, 0, 6 } (big-endian). This assumes that sizeof (int) == 4 is true, adjust for other sizes as needed, the problem remains.
You should very probably make the buffer unsigned char instead. Also, if you had made the call like this:
int wrote = write(fd, ACK, sizeof ACK);
printf("Wrote %d bytes\n", wrote);
You would have gotten direct feedback. You should test something like this, to see that the write actually succeeds.

The activated Hardware-Flow-Control (CRTSCTS) was the reason why write() blocked and finally nothing has appeared on the serial output.
thanks!
Code snap which works:
int openSerialDevice(const char* devTTY, struct termios oldTio) {
//----< Open serial device >----------------------------------
int fileDescriptor;
// fd = open("/dev/ttyS0", O_RDWR | O_NOCTTY | O_NDELAY);
fileDescriptor = open(devTTY, O_RDWR | O_NOCTTY);
//fileDescriptor = open(devTTY, O_RDWR | O_NOCTTY /*| OPOST*/);
if (fileDescriptor == -1) {
perror("Error while opening serial interface occurred!");
return -99;
}
// set new parameters to the serial device
struct termios newtio;
fcntl(fileDescriptor, F_SETFL, 0);
// set everything to 0
bzero(&newtio, sizeof(newtio));
// again set everything to 0
bzero(&newtio, sizeof(newtio));
newtio.c_cflag |= BAUDRATE; // Set Baudrate first time
newtio.c_cflag |= CLOCAL; // Local line - do not change "owner" of port
newtio.c_cflag |= CREAD; // Enable receiver
newtio.c_cflag &= ~ECHO; // Disable echoing of input characters
newtio.c_cflag &= ~ECHOE;
// set to 8N1
newtio.c_cflag &= ~PARENB; // no parentybyte
newtio.c_cflag &= ~CSTOPB; // 1 stop bit
newtio.c_cflag &= ~CSIZE; // Mask the character size bits
newtio.c_cflag |= CS8; // 8 data bits
// output mode to
newtio.c_oflag = 0;
//newtio.c_oflag |= OPOST;
// Set teh baudrate for sure
cfsetispeed(&newtio, BAUDRATE);
cfsetospeed(&newtio, BAUDRATE);
newtio.c_cc[VTIME] = 10; /* inter-character timer */
newtio.c_cc[VMIN] = 0; /* blocking read until */
tcflush(fileDescriptor, TCIFLUSH); // flush pending data
// set the new defined settings
if (tcsetattr(fileDescriptor, TCSANOW, &newtio)) {
perror("could not set the serial settings!");
return -99;
}
//----< / Open serial device >----------------------------------
return fileDescriptor;
}

Related

Serial reads from a sensor using USB-serial cable in linux using C

I have been trying to read the responses from a serial temperature sensor interfaced to my raspberry pi using a USB to serial converter.
I can see that the writes to the sensor device seem to work. However when I try to read back from the serial chip the read fails with -1.
I did try to use the same baud rate 9600 8 bit no parity settings using realterm program and was able to read and write hex values as expected, kindly point me in the right direction.
void serial_write(char parameter,char value) {
int fd;
uint8_t bytes_wr;
char wr_buffer[3];
fd = open("/dev/ttyUSB0",O_RDWR | O_NOCTTY | O_NDELAY);
if (fd == -1)
ERROR("Error! in Opening ttyUSB0 \n");
else
DEBUG("ttyUSB0 Opened Successfully \n");
struct termios SerialPortSettings;
tcgetattr(fd, &SerialPortSettings);
cfsetispeed(&SerialPortSettings,B9600);
cfsetospeed(&SerialPortSettings,B9600);
SerialPortSettings.c_cflag &= ~PARENB;
SerialPortSettings.c_cflag &= ~CSTOPB;
SerialPortSettings.c_cflag &= ~CSIZE;
SerialPortSettings.c_cflag |= CS8;
SerialPortSettings.c_cflag &= ~CRTSCTS;
SerialPortSettings.c_cflag |= CREAD | CLOCAL;
SerialPortSettings.c_iflag &= ~(IXON | IXOFF | IXANY);
SerialPortSettings.c_iflag &= ~(ICANON | ECHO | ECHOE | ISIG);
SerialPortSettings.c_oflag &= ~OPOST;
if ((tcsetattr(fd,TCSANOW,&SerialPortSettings)) != 0)
ERROR("ERROR ! in Setting attributes \n");
else
DEBUG("BaudRate=9600\tStopBits=1\tParity=none \n");
wr_buffer[0] = write;
wr_buffer[1] = parameter;
wr_buffer[2] = value;
bytes_wr = write(fd, wr_buffer,sizeof(wr_buffer));
DEBUG("Total Bytes written: %d \n", sizeof(wr_buffer));
close(fd);
}
The above function seems to write as expected to the serial port, however when I try to read, the reads fails with a -1
char serial_read(char parameter) {
int fd, read_length, i;
uint8_t bytes_wr;
char wr_buffer[2];
fd = open("/dev/ttyUSB0",O_RDWR | O_NOCTTY | O_NDELAY);
if (fd == -1)
ERROR("Error! in Opening ttyUSB0 \n");
else
DEBUG("ttyUSB0 Opened Successfully \n");
struct termios SerialPortSettings;
tcgetattr(fd, &SerialPortSettings);
cfsetispeed(&SerialPortSettings,B9600);
cfsetospeed(&SerialPortSettings,B9600);
SerialPortSettings.c_cflag &= ~PARENB;
SerialPortSettings.c_cflag &= ~CSTOPB;
SerialPortSettings.c_cflag &= ~CSIZE;
SerialPortSettings.c_cflag |= CS8;
SerialPortSettings.c_cflag &= ~CRTSCTS;
SerialPortSettings.c_cflag |= CREAD | CLOCAL;
SerialPortSettings.c_iflag &= ~(IXON | IXOFF | IXANY);
SerialPortSettings.c_iflag &= ~(ICANON | ECHO | ECHOE | ISIG);
SerialPortSettings.c_oflag &= ~OPOST;
if ((tcsetattr(fd,TCSANOW,&SerialPortSettings)) != 0)
ERROR("ERROR ! in Setting attributes \n");
else
DEBUG("BaudRate=9600\tStopBits=1\tParity= none\n");
wr_buffer[0] = read;
wr_buffer[1] = parameter;
bytes_wr = write(fd, wr_buffer,sizeof(wr_buffer));
DEBUG("Total Bytes written: %d \n", sizeof(wr_buffer));
usleep(8000);
tcflush(fd,TCIFLUSH);
char rd_buffer[4];
read_length = read(fd, rd_buffer,sizeof(rd_buffer));
DEBUG("Total bytes read = %d \n",read_length);
for (i==0;i<read_length;i++){
DEBUG("rd_buffer[%d]=%x \n",i,rd_buffer[i]);
}
close(fd);
return rd_buffer[0];
}
With realterm windows application all writes and reads seem to work fine.
From the open(2) manpage:
O_NONBLOCK or O_NDELAY
When possible, the file is opened in nonblocking mode.
Neither the open() nor any subsequent operations on the file
descriptor which is returned will cause the calling process to
wait.
For a serial connection, the end result will be that if you ask to read some number of bytes from the serial port and there are no characters waiting, then read will return with -1 and 'errno' will probably be EAGAIN or EWOULDBLOCK.
So your usleep(8000) was probably an attempt to wait long enough for the device to respond but the device may not have data for you; especially if it is in the middle of an adc operation, it might take longer than 8ms.
There are a few things you can do:
You can (in pseudo code):
int retries=10;
while(retries--) {
read_length = read(fd, rd_buffer,sizeof(rd_buffer));
if(read_length > 0)
break;
usleep(1000);
}
Unfortunately, one side effect of this is that if the temperature sensor is sending you a lengthy string and your program read()s while the temperature sensor is still writing, you will get a partial string. So if you know the length of string that you're waiting to receive, you could use an ioctl() to find out how many characters are waiting:
ioctl(fd, FIONREAD, &bytes_avail);
So the pseudo code would look more like:
int retries=10;
int bytes_avail=0;
while(retries--) {
if (ioctl(fd, FIONREAD, &bytes_avail) < 0) {
fprintf(stderr, "ioctl failed\n");
return; // Do something here
}
if (bytes_avail >= sizeof(rd_buffer)) {
read_length = read(fd, rd_buffer,sizeof(rd_buffer));
if(read_length > 0)
break;
}
usleep(1000);
}
If the temperature sensor sends an ascii string that is terminated with a newline or carriage-return, then the code would look different.

read() is blocked forever on raspberry pi 3 UART

The C read() function frequently get blocked, especially if there is nothing connected on the Gpio pins (tx / rx), but I just hoped it would stop for itself when there is no conection, the same when there is wire conection but no data to read, but it just get blocked until I force it to finish.
Open
fd = open("/dev/serial0", O_RDWR | O_NDELAY | O_NOCTTY | O_NONBLOCK);
Read
n = read( fd, value, 1 );
if (n < 0) {
printf ( "Error = %s\n", strerror( errno ) );
}
else if (n == 0) {
printf ( "Read Nothing...\n");
}
Set attribs
int setAttr(int fd)
{
//Read the configureation of the port
struct termios options;
tcgetattr( fd, &options );
//Set Baud Rate
cfsetispeed( &options, B9600 );
cfsetospeed( &options, B9600 );
//Setting other Port Stuff
options.c_cflag &= ~PARENB; /*Make 8n1 */
options.c_cflag &= ~CSTOPB;
options.c_cflag &= ~CSIZE; /* Mask the character size bits */
options.c_cflag |= CS8; /* Select 8 data bits */
options.c_cflag &= ~CRTSCTS; /* No flow control */
options.c_cc[VMIN] = 0; /*READ doesn't block */
options.c_cc[VTIME] = 1; /* 0.1 seconds read timout */
options.c_cflag |= CREAD | CLOCAL; /* Turn on READ & ignore crtl lines */
//Make raw
cfmakeraw(&options);
//Flush port, then applies attributes
tcflush(fd, TCIOFLUSH);
return tcsetattr( fd, TCSANOW, &options );
}
For a UART port with nothing but tx/rx pins, there is no distinct "nothing connected" status. For the functionality you want, the port would need DCE/DTR pins and the CLOCAL flag (ignore modem control lines) would have to be removed from the termios settings.
I just add the code below, after open() and it's not blocked anymore when tx/rx pins are not connected. Probably the port was going blocked after open().
if (fd == -1)
{
/*
* Could not open the port.
*/
perror("open_port: Unable to open /dev/serial0 - ");
}
else fcntl(fd, F_SETFL, O_NONBLOCK);

UART blocks on read

I have a problem with my uart read (on raspberry pi). It works ok but it stops in a loop and waits on data...
I made an option O_NDELAY but is stops even so.
I use two terminal windows:
one is used for uart program
on the second i write:
echo '123445' > /dev/ttyAMA0
(raspberry Pi uart port)
Complete code is below.
#include <stdio.h>
#include <unistd.h> //Used for UART
#include <fcntl.h> //Used for UART
#include <termios.h> //Used for UART
int main(int argv, char * argc[])
{
// Setting Up The UART
//-------------------------
//----- SETUP USART 0 -----
//-------------------------
//At bootup, pins 8 and 10 are already set to UART0_TXD, UART0_RXD (ie the alt0 function) respectively
int uart0_filestream = -1;
//OPEN THE UART
//The flags (defined in fcntl.h):
// Access modes (use 1 of these):
// O_RDONLY - Open for reading only.
// O_RDWR - Open for reading and writing.
// O_WRONLY - Open for writing only.
//
// O_NDELAY / O_NONBLOCK (same function) - Enables nonblocking mode. When set read requests on the file can return immediately with a failure status
// if there is no input immediately available (instead of blocking). Likewise, write requests can also return
// immediately with a failure status if the output can't be written immediately.
//
// O_NOCTTY - When set and path identifies a terminal device, open() shall not cause the terminal device to become the controlling terminal for the process.
uart0_filestream = open("/dev/ttyAMA0", O_RDWR | O_NOCTTY | O_NDELAY); //Open in non blocking read/write mode
if (uart0_filestream == -1)
{
//ERROR - CAN'T OPEN SERIAL PORT
printf("Error - Unable to open UART. Ensure it is not in use by another application\n");
}
//CONFIGURE THE UART
//The flags (defined in termios.h - see http://pubs.opengroup.org/onlinepubs/007908799/xsh/termios.h.html):
// Baud rate:- B1200, B2400, B4800, B9600, B19200, B38400, B57600, B115200, B230400, B460800, B500000, B576000, B921600, B1000000, B1152000, B1500000, B2000000, B2500000, B3000000, B3500000, B4000000
// CSIZE:- CS5, CS6, CS7, CS8
// CLOCAL - Ignore modem status lines
// CREAD - Enable receiver
// IGNPAR = Ignore characters with parity errors
// ICRNL - Map CR to NL on input
// PARENB - Parity enable
// PARODD - Odd parity (else even)
struct termios cfg;
//get existing configuration setup
tcgetattr(uart0_filestream, &cfg);
//fcntl(deviceFD, F_SETFL, FNDELAY);
fcntl(uart0_filestream, F_SETFL, 0);
////set both incoming and outgoing baud rates...
cfsetispeed(&cfg, B115200);
cfsetospeed(&cfg, B115200);
cfg.c_cflag |= (CLOCAL | CREAD);
////8N1 (8 data bits, No parity, 1 stop bit)
cfg.c_cflag &= ~PARENB;
cfg.c_cflag &= ~CSTOPB;
cfg.c_cflag &= ~CSIZE;
cfg.c_cflag |= CS8;
cfg.c_cflag &= ~CRTSCTS; //~CNEW_RTSCTS; //disable hardware flow control
//use RAW unbuffered data mode (eg, not canonical mode)
cfg.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG | IGNBRK);
cfg.c_iflag &= ~(IGNPAR | IXON | IXOFF | IXANY);
//raw (unprocessed) output mode
cfg.c_oflag &= ~OPOST;
tcsetattr(uart0_filestream, TCSANOW, &cfg);
//Transmitting Bytes
//----- TX BYTES -----
unsigned char tx_buffer[20];
unsigned char *p_tx_buffer;
p_tx_buffer = &tx_buffer[0];
*p_tx_buffer++ = 'H';
*p_tx_buffer++ = 'e';
*p_tx_buffer++ = 'l';
*p_tx_buffer++ = 'l';
*p_tx_buffer++ = 'o';
if (uart0_filestream != -1)
{
int count = write(uart0_filestream, &tx_buffer[0], (p_tx_buffer - &tx_buffer[0])); //Filestream, bytes to write, number of bytes to write
if (count < 0)
{
printf("UART TX error\n");
}
}
//Receiving Bytes
//----- CHECK FOR ANY RX BYTES -----
while(1) {
printf("loop\n");
if (uart0_filestream != -1)
{
// Read up to 255 characters from the port if they are there
unsigned char rx_buffer[256];
int rx_length = read(uart0_filestream, (void*)rx_buffer, 255); //Filestream, buffer to store in, number of bytes to read (max)
if (rx_length < 0)
{
//An error occured
printf("UART RX error\n");
}
else if (rx_length == 0)
{
//No data waiting
printf("no data UART RX test commit\n");
}
else
{
//Bytes received
rx_buffer[rx_length] = '\0';
printf("%i bytes read : %s\n", rx_length, rx_buffer);
//break;
}
}
sleep(1);
}
//Closing the UART if no longer needed
//----- CLOSE THE UART -----
close(uart0_filestream);
return 0;
}
I used to have the same problem, and problem is not related with code and solution is just disable login on serial port,
there is a file at /etc/inittab
open this file with nano and find this line:
T0:23:respawn:/sbin/getty -L ttyAMA0 115200 vt100
and put a # char at begining this line than save and reboot and it is working weirdly.
You can use O_NONBLOCK flag to make the read/write operation non blocking.

Read from serial port linux

I'm trying to read from serial port, but always get 0 (zero) characters back. Already read the "Serial Programming Guide for POSIX Operating Systems", but can't find out why the program not waiting (blocking).
The 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 */
void main()
{
printf("Hello world\n");
int fd; /* File descriptor for the port */
int n;
int bytes;
char c;
char buffer[10];
char *bufptr;
struct termios options;
fd = open("/dev/ttyUSB0", O_RDWR | O_NOCTTY | O_NDELAY);
if (fd == -1) {
perror("open_port: Unable to open /dev/ttyUSB0 - ");
}
else {
fcntl(fd, F_SETFL, FNDELAY);
}
tcgetattr( fd, &options );
/* SEt Baud Rate */
cfsetispeed( &options, B9600 );
cfsetospeed( &options, B9600 );
//I don't know what this is exactly
options.c_cflag |= ( CLOCAL | CREAD );
// Set the Charactor size
options.c_cflag &= ~CSIZE; /* Mask the character size bits */
options.c_cflag |= CS8; /* Select 8 data bits */
// Set parity - No Parity (8N1)
options.c_cflag &= ~PARENB;
options.c_cflag &= ~CSTOPB;
options.c_cflag &= ~CSIZE;
options.c_cflag |= CS8;
// Disable Hardware flowcontrol
// options.c_cflag &= ~CNEW_RTSCTS; -- not supported
// Enable Raw Input
options.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);
// Disable Software Flow control
options.c_iflag &= ~(IXON | IXOFF | IXANY);
// Chose raw (not processed) output
options.c_oflag &= ~OPOST;
if ( tcsetattr( fd, TCSANOW, &options ) == -1 )
printf ("Error with tcsetattr = %s\n", strerror ( errno ) );
else
printf ( "%s\n", "tcsetattr succeed" );
fcntl(fd, F_SETFL, 0);
// Write to the port
n = write(fd, "1", 1);
if (n < 0) {
fputs("write() of 1 bytes failed!\n", stderr);
}
// Read from the port
//fcntl(fd, F_SETFL, FNDELAY);
bytes = read(fd, &buffer, sizeof(buffer));
printf("number of bytes read is %d\n", bytes);
printf("%s\n", buffer);
//perror ("read error:");
close(fd);
}
This information was originally from the Serial Programming Guide1.
The reason you are getting a 0 return value is because of this line:
fcntl(fd, F_SETFL, FNDELAY);
If you want a normal blocking read, unset that flag.
1. http://www.easysw.com/~mike/serial/serial.html#2_5_4 (now defunct)
You are using O_NDELAY
O_NONBLOCK or O_NDELAY
When possible, the file is opened in non-blocking mode. Neither the open() nor any subsequent operations on the file
descriptor which is returned will cause the calling process to
wait. For the handling of FIFOs (named pipes), see also fifo(7). For
a discussion of the effect of O_NONBLOCK in conjunction with mandatory
file locks and with file leases, see fcntl(2).
EDIT: You're doing the same thing in your fcntl() call, as well.

Reading and writing binary data over serial port

So I searched around, and couldn't exactly find what I needed. I need help reading and writing binary data over a serial port, and would appreciate any advice you may have. Please note, I asked a question similar to this earlier when I was at a different stage of this project.
Below are programs. The first program opens a file "test.jpg", reads it in binary mode and stores the result in a buffer. It then closes the file, and is supposed to send that file over a serial port.
The second program creates a file called "testout.jpg", and is supposed to read in the data sent from the previous program.
I have a hunch that the problem in my code lies in the second program. Perhaps I need to use fread for that too? I tried, but I cannot figure out how to implement it for a serial port as I am relatively new to programming.
Many thanks for your time.
Serial write:
#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>
int main()
{
//writing
int writeport = open_port("/dev/ttyUSB0");
//open file
FILE *file;
char *buffer;
int fileLen;
file = fopen("test.jpg", "rb");
//get file size
fseek(file, 0, SEEK_END);
fileLen = ftell(file);
fseek(file, 0, SEEK_SET);
buffer = (char *)malloc(fileLen + 1);
//read file contents
fread(buffer, fileLen, 1, file);
fclose(file);
int n = write(writeport, buffer, fileLen + 1);
if (n < 0)
fputs("write() of bytes failed!\n", stderr);
//closing ports
close(writeport);
}
int open_port(char str[])
{
int fd = open(str, O_RDWR | O_NOCTTY | O_NONBLOCK); // ?? NDELAY or NONBLOCK?
if (fd == -1)
{
perror("open_port: Unable to open /dev/ttyS0 - ");
}
else
fcntl(fd, F_SETFL, 0);
struct termios options;
tcgetattr(fd, &options); //this gets the current options set for the port
// setting the options
cfsetispeed(&options, B9600); //input baudrate
cfsetospeed(&options, B9600); // output baudrate
options.c_cflag |= (CLOCAL | CREAD); // ?? enable receicer and set local mode
//options.c_cflag &= ~CSIZE; /* mask the character size bits */
options.c_cflag |= CS8; /* select 8 data bits */
options.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG); // choosing raw input
options.c_iflag &= ~INPCK; // disable parity check
options.c_iflag &= ~(IXON | IXOFF | IXANY); // disable software flow control
options.c_oflag |= OPOST; // ?? choosing processed output
options.c_cc[VMIN] = 0; // Wait until x bytes read (blocks!)
options.c_cc[VTIME] = 0; // Wait x * 0.1s for input (unblocks!)
// settings for no parity bit
options.c_cflag &= ~PARENB;
options.c_cflag &= ~CSTOPB;
options.c_cflag &= ~CSIZE;
options.c_cflag |= CS8;
tcsetattr(fd, TCSANOW, &options); //set the new options ... TCSANOW specifies all option changes to occur immediately
return (fd);
}
Serial read:
#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 */
int main()
{
//reading
int readport = open_port("/dev/ttyUSB1");
//open resultant file
FILE *file;
//system("rm testout.jpg");
file = fopen("testout.jpg", "wb");
//trying to read one character at a time
char buff;
int n = 1;
while (n > 0)
{
n = read(readport, &buff, 1);
//printf("%c", buff, buff);
**//I tried these three methods, with little success**
//fprintf(file, "%c", buff);
//fwrite(&buff, 1, 1, file);
//write(file, &buff, 1);
}
//closing ports
close(readport);
fclose(file);
}
int open_port(char str[])
{
int fd = open(str, O_RDWR | O_NOCTTY | O_NONBLOCK); // ?? NDELAY or NONBLOCK?
if (fd == -1)
{
perror("open_port: Unable to open /dev/ttyS0 - ");
}
else
fcntl(fd, F_SETFL, 0);
struct termios options;
tcgetattr(fd, &options); //this gets the current options set for the port
// setting the options
cfsetispeed(&options, B9600); //input baudrate
cfsetospeed(&options, B9600); // output baudrate
options.c_cflag |= (CLOCAL | CREAD); // ?? enable receicer and set local mode
//options.c_cflag &= ~CSIZE; /* mask the character size bits */
options.c_cflag |= CS8; /* select 8 data bits */
options.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG); // choosing raw input
options.c_iflag &= ~INPCK; // disable parity check
options.c_iflag &= ~(IXON | IXOFF | IXANY); // disable software flow control
options.c_oflag |= OPOST; // ?? choosing processed output
options.c_cc[VMIN] = 0; // Wait until x bytes read (blocks!)
options.c_cc[VTIME] = 0; // Wait x * 0.1s for input (unblocks!)
// settings for no parity bit
options.c_cflag &= ~PARENB;
options.c_cflag &= ~CSTOPB;
options.c_cflag &= ~CSIZE;
options.c_cflag |= CS8;
tcsetattr(fd, TCSANOW, &options); //set the new options ... TCSANOW specifies all option changes to occur immediately
return (fd);
}
file = fopen( "zname.jpg", "wb" );
while (1) {
n = read(readport, &buff, 1);
if (n == -1) switch(errno) {
case EAGAIN: /* sleep() */
continue;
...
default: goto quit;
}
if (n ==0) break;
fputc(buff, file);
}
quit:
fclose (file);
...
Even better than sleep() and loop, would be to use select/poll. (You'd still have to check for EAGAIN)

Resources