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;
}
|