Binary Access to a Serial Port

Hello All

I'm currently working on an application to get information from a commercial module that makes use of RS232 communications. The information that the unit sends is full floating point, encoded not as ASCII text but split up into the constituent bytes and sent serially. At current I am developing and testing the application on my desktop using Debian, but it will eventually need to run on embedded Linux, so I am keen to stay away from non standard libraries if I can.

I have run into a problem receiving data over the serial port. My current code makes use of:

unistd.h
fcntl.h
termios.h

The code uses the open() function to open /dev/ttyS0 for read and write, with ndelay and and noctty set. It then goes on to set the speed, data size, parity etc appropriately. Finally it spawns a pthread to handle the data reception, which is done using read().

Upon running the code I didn't get any output, so I inserted a series of cout statements to let me know what data was being received, and it became evident that corruption was occurring. The beginning of each message is a fixed sequence of 0xFA 0xFF 0x32 and 0x30, and I use this to make sure I am reading the correct part of the data sequence. However the cout statements showed no such input. They did reveal,at the correct byte spacing, a sequence of 0x7A 0x7F 0x32 0x30, and no values above 127 or below 0. Leading me to the conclusion that the most significant bit is being set to 0 by the settings and functions that I'm using.

This doesn't fully surprise me, as I think the port is being treaded as an ASCII file rather than a binary file. However I can not find anything in the above libraries to allow me to set the file to binary over ASCII. Clearing the Canonical flag didn't help either. I know that the module is working correctly, as I have written a C# class to do the same job and it works perfectly.

I have played around using fdopen to create an stdio.h FILE object from the file descriptor returned by open(), and then tried using fread() to read the file. But depending on the opening mode I either get an error or end of file (r,w,a give errors r+,w+,a+ give EOF). I have also tried opening the serial port using open, setting the properties, closing it and reopening it using an fstream object but the constructor hangs, presumably due to the fact that nonblock has been cleared by me closing the file.

Has anyone got any suggestions as to how to cure the problem?

Many Thanks

Russell

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64

#include <iostream>
#include <unistd.h>
#include <fcntl.h>
#include <termios.h>

int portHandle;

int main(int argc, char* argv[])
{
	portHandle = open("/dev/ttyS0", O_RDWR | O_NOCTTY | O_NDELAY);
	
	if (portHandle != -1)
	{
		fcntl(portHandle, F_SETFL, 0);		//clear Ndelay now its open
		
		struct termios portSettings;
		
		cfsetispeed(&portSettings, B115200);
		cfsetospeed(&portSettings, B115200);
		
		portSettings.c_cflag &= ~PARENB;
		portSettings.c_cflag &= ~CSTOPB;
		portSettings.c_cflag &= ~CSIZE;
		portSettings.c_cflag |= CS8;
		portSettings.c_cflag |= CREAD;
		
		portSettings.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);
		
		tcsetattr(portHandle, TCSANOW, &portSettings); 
		
		//Spawn Thread
	}
}

//.............

void* task(void *threadInputs)
{
	//..................
	unsigned char data;
	
	while (1)
	{
		int portRet = read(portHandle, &data, 1);
		
		if (portRet >0)
		{
			//process the code
			std::cout<<(int)data<<"\n";
		}
		else if (portRet == 0)
		{
			std::cout<<"return 0\n";
		}
		else
		{
			std::cout<<"error\n";
		}
	}
	
	return NULL;
}

If you're reading binary data, you might try using the ntoh functions. There are also hton functions. The ntoh functions take binary data that is in network byte order and changes it to the ordering of the receiving host. As you might have guessed, hton functions take data that is in host-byte order and puts it in network-byte order.

This is especially true if you are sending between two different architectures, say Linux and Windows.
Topic archived. No new replies allowed.