LinuxQuestions.org
Review your favorite Linux distribution.
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Reply
  Search this Thread
Old 05-24-2010, 02:19 PM   #1
MPRT
Member
 
Registered: Apr 2010
Location: Rio de Janeiro
Distribution: Ubuntu, Fedora, Slackware
Posts: 30

Rep: Reputation: 0
Single Board Computer Communication problem


Dear all,

I need to communicate a Single Board Computer so called PC104 (AMD GX466, 333 MHz, 512 MB DDR) with a sensor by RS232. The PC104 works with Slackware 13.0, without graphical interface.
Just to test it, I used a DB9 connector with Tx jumped with Rx. So, it should read the same data that were written. It’s all right when it communicates strings.
However, the communication protocol of the sensor is defined in hexadecimal numbers and I don’t know to format the read() and write() function to hexadecimal.

I show a piece of the code with the write() and read():

int nWrite;
int nRead;
char buffer[ 3 ];
char *bufptr;

bufptr = buffer;

nWrite = write(fd, “DB”, 2 );
nRead = read( fd, bufptr, 2 );

where fd is the file descriptor. But I don’t want to send “DB”. I need to send 0xDB (and read it), but I don’t know.

Could you help me please! Any advice will be very much appreciated!
Thank you very much!

MPRT
 
Old 05-25-2010, 07:34 AM   #2
hda7
Member
 
Registered: May 2009
Distribution: Debian wheezy
Posts: 252

Rep: Reputation: 31
The standard read and write functions should use any character values in the buffer. Most languages have a means to embed hex values in strings. I think the way to do it in C is like "\xdb" or "\xDB".
 
1 members found this post helpful.
Old 05-25-2010, 02:13 PM   #3
MPRT
Member
 
Registered: Apr 2010
Location: Rio de Janeiro
Distribution: Ubuntu, Fedora, Slackware
Posts: 30

Original Poster
Rep: Reputation: 0
Thank you very much, hda7!

I tested the code with the “\xDB” and it didn’t have any compilation problem. It seems the writing process was OK! However, the program was waiting the reading process that didn’t happen. I finished the program with CTRL+C.

I’ve been looking for a solution but unfortunately without success.

I also tried the following based on a C code (for Windows) provided by the sensor company. But it also wait the reading process. Thank you very much in advance for any comments!

unsigned char bufferWrt[3];
unsigned char *bufferWrtPtr;

unsigned char bufferRd[3];
unsigned char *bufferRdPtr;

bufferWrtPtr = bufferWrt;
bufferRdPtr = bufferRd;

bufferWrt[ 0 ] = 0xDB;
bufferWrt[ 1 ] = 0xA8;
bufferWrt[ 2 ] = 0xB9;

n = write( fd, bufferWrtPtr, 3 );
nRead = read( fd, bufferRdPtr, 3 );
 
Old 05-25-2010, 04:05 PM   #4
michaelk
Moderator
 
Registered: Aug 2002
Posts: 25,568

Rep: Reputation: 5865Reputation: 5865Reputation: 5865Reputation: 5865Reputation: 5865Reputation: 5865Reputation: 5865Reputation: 5865Reputation: 5865Reputation: 5865Reputation: 5865
May I suggest reading up on serial programing. FYI read/write length is based on bytes. So 0xDB is actually two characters and you need to transmit six characters not 3.


http://www.easysw.com/~mike/serial/serial.html
 
1 members found this post helpful.
Old 05-25-2010, 06:47 PM   #5
MPRT
Member
 
Registered: Apr 2010
Location: Rio de Janeiro
Distribution: Ubuntu, Fedora, Slackware
Posts: 30

Original Poster
Rep: Reputation: 0
Hello, MichaelK! Thank you for your comments!

I based the code I've been developing on several references but the most valuable I've found was that one you suggested me.

I guess I don't understand very well your comment about the 0xDB and I'm sorry about that. Because individual hex number is composed by 4 bits so 0xDB is composed by 8 bits (1101 1011).

Concerning the number of the bytes that should be read, I guess it can be less than the serial port buffer contains. Is it right?

Thank you again!
 
Old 05-25-2010, 07:11 PM   #6
michaelk
Moderator
 
Registered: Aug 2002
Posts: 25,568

Rep: Reputation: 5865Reputation: 5865Reputation: 5865Reputation: 5865Reputation: 5865Reputation: 5865Reputation: 5865Reputation: 5865Reputation: 5865Reputation: 5865Reputation: 5865
Never mind... Your correct... Where I was going no one knows. I guess I'm a bit tired... Yes, the value returned (nRead) is the actual number of characters read.

Last edited by michaelk; 05-25-2010 at 07:21 PM.
 
1 members found this post helpful.
Old 05-25-2010, 08:41 PM   #7
pixellany
LQ Veteran
 
Registered: Nov 2005
Location: Annapolis, MD
Distribution: Mint
Posts: 17,809

Rep: Reputation: 743Reputation: 743Reputation: 743Reputation: 743Reputation: 743Reputation: 743Reputation: 743
moved to programming
 
0 members found this post helpful.
Old 05-26-2010, 10:56 AM   #8
MPRT
Member
 
Registered: Apr 2010
Location: Rio de Janeiro
Distribution: Ubuntu, Fedora, Slackware
Posts: 30

Original Poster
Rep: Reputation: 0
Well, I tried to flush the I/O before reading and writing process as the piece of code is showing but it doesn’t work. It’s not able to read...
Do you have any idea to fix the problem? Thanks in advance!
MPRT

unsigned char bufferWrt[3];
unsigned char *bufferWrtPtr;

unsigned char bufferRd[3];
unsigned char *bufferRdPtr;

bufferWrtPtr = bufferWrt;
bufferRdPtr = bufferRd;

bufferWrt[ 0 ] = 0xDB;
bufferWrt[ 1 ] = 0xA8;
bufferWrt[ 2 ] = 0xB9;

tcflush( fd, TCIOFLUSH );
n = write( fd, bufferWrtPtr, 3 );
tcflush( fd, TCIOFLUSH );
nRead = read( fd, bufferRdPtr, 3 );
 
Old 05-26-2010, 11:36 AM   #9
hda7
Member
 
Registered: May 2009
Distribution: Debian wheezy
Posts: 252

Rep: Reputation: 31
Try changing the serial port settings: from the command line
Code:
stty -F <serial port device file> raw
It may be trying to buffer by lines.
 
1 members found this post helpful.
Old 05-26-2010, 12:38 PM   #10
michaelk
Moderator
 
Registered: Aug 2002
Posts: 25,568

Rep: Reputation: 5865Reputation: 5865Reputation: 5865Reputation: 5865Reputation: 5865Reputation: 5865Reputation: 5865Reputation: 5865Reputation: 5865Reputation: 5865Reputation: 5865
What is the value of nRead?
Are you using asynchronous input with a signal handler?
Posting your entire program might provide some better insight on your problems. With just this snippet I can only suggest that you could be trying to read characters before they are actually transmitted from the board.

http://tldp.org/HOWTO/Serial-Programming-HOWTO/
 
1 members found this post helpful.
Old 05-26-2010, 01:38 PM   #11
MPRT
Member
 
Registered: Apr 2010
Location: Rio de Janeiro
Distribution: Ubuntu, Fedora, Slackware
Posts: 30

Original Poster
Rep: Reputation: 0
Dear hda7! You are a genius! Congratulations and thank you very much! You really help me! It read the hex data that was sent!

However, the program is not so much stable...When I repeat the program, it spends some time to read and sometimes it reads 0 instead 0xDB. When it works it reads DB. I’m afraid because the sensor works with a range of acquisition frequency.
Well, I am not sure I did the right thing. I tried to put the command (stty –F /dev/ttyS0 ) in the code but there was an error at the compilation time. So, I just set the command before to execute the program...It could be the reason of the instability? If yes, how can I put it in the code?

I’m sending the code and I’d like to ask your suggestions.

Cheers,
MPRT

Quote:
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <termios.h>

int main()
{

int fd;
struct termios options;

//======OPEN THE SERIAL PORT======
fd = open ( "/dev/ttyS0", O_RDWR | O_NOCTTY | O_NDELAY );
if ( fd == -1 )
{
perror( "The serial port is not opened." );
}
else
{
fcntl( fd, F_SETFL, 0 );
printf( "\nThe serial port is open." );
}

//======SERIAL PORT CONFIGURATION======
tcgetattr( fd, &options );

options.c_cflag |= ( CLOCAL | CREAD );
options.c_cc[ VMIN ] = 0;
options.c_cc[ VTIME ] = 10;
cfsetispeed( &options, B115200 );
cfsetospeed( &options, B115200 );

options.c_cflag &= ~PARENB;
options.c_cflag &= ~CSTOPB;
options.c_cflag &= ~CSIZE;
options.c_cflag |= CS8;

options.c_cflag &= ~CRTSCTS;
options.c_iflag &= ~( IXON | IXOFF | IXANY );
options.c_oflag &= ~OPOST;

tcsetattr( fd, TCSANOW, &options );

//======WRITING PROCESS======
tcflush( fd, TCIOFLUSH );
int n;
unsigned char dataWrite;
dataWrite = 0xDB;

n = write( fd, &dataWrite, 1 );


if ( n < 0 )
{
printf( "\nThere was an error duting the writing process." );
}
else
{
printf( "\nWriting process was done! " );
}

//======READING PROCESS======
unsigned char dataRead;
int nRead;

tcflush( fd, TCIOCLUSH );
tcsetattr( fd, TCSANOW, &options );

printf( "\nStarting the reading process!" );
nRead = read( fd, &dataRead, 1 );

if ( nRead > 0 )
{
printf( "\nThe number of read bytes are %d ", nRead );
}

printf( "\nData read is %X\n", dataRead );

close ( fd );
return 0;
}; //End of the main function.
 
Old 05-26-2010, 01:54 PM   #12
MPRT
Member
 
Registered: Apr 2010
Location: Rio de Janeiro
Distribution: Ubuntu, Fedora, Slackware
Posts: 30

Original Poster
Rep: Reputation: 0
Hello, Michaelk! Yes, it’s better to put the entire code than a small piece. So, I just did it. As you can see, hda gave me an excelent idea. But it's still so instable. In any case, I'm very glad with the support that all of you are providing and it's very good keep contact with you!
 
Old 05-26-2010, 02:21 PM   #13
MPRT
Member
 
Registered: Apr 2010
Location: Rio de Janeiro
Distribution: Ubuntu, Fedora, Slackware
Posts: 30

Original Poster
Rep: Reputation: 0
Hello, colleagues!

I put a comment in the flush command (tcflush( fd, TCIOCLUSH ) before the read function. After that, the program works fine! There is no delay at the reading process!

To be more independent of external commands, it would be very interesting the “stty –F /dev/ttyS0 raw” be in the code. Now, I’ll do the code with more hex numbers.

Cheers,
MPRT
 
Old 05-26-2010, 06:49 PM   #14
hda7
Member
 
Registered: May 2009
Distribution: Debian wheezy
Posts: 252

Rep: Reputation: 31
Quote:
Originally Posted by MPRT View Post
Hello, colleagues!
To be more independent of external commands, it would be very interesting the “stty –F /dev/ttyS0 raw” be in the code.
See the man page termios(3); there are a collection of library functions that control terminal (and serial port) settings.
 
1 members found this post helpful.
  


Reply


Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
looking for a single board computer feh Linux - Embedded & Single-board computer 13 04-20-2011 02:34 AM
single board computer marceliszpak Linux - Embedded & Single-board computer 4 04-23-2010 04:10 AM
Single Board Computer evilrabbi Linux - Hardware 2 02-06-2007 06:13 PM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

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

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration