LinuxQuestions.org
Download your favorite Linux distribution at LQ ISO.
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 12-02-2008, 12:20 AM   #1
nasr-noor
LQ Newbie
 
Registered: Aug 2005
Posts: 15
Blog Entries: 1

Rep: Reputation: 0
Unhappy Serial Receive Problem


Hi,
I have 2 PC one has Windows and send data frame on serial port, and another is fedora 9 and receive data.

I send integer value(Not ASCII code),for example 00000000(Not 48) for number 0.

problem:
when I send 00000000,00001101,00010001,00010011 for 0,13,17,19 on linux I receive NULL or wrong characters on fedora, but when I receive them on windows its ok.

do you know whats the problem?
 
Old 12-02-2008, 08:09 AM   #2
theNbomr
LQ 5k Club
 
Registered: Aug 2005
Distribution: OpenSuse, Fedora, Redhat, Debian
Posts: 5,399
Blog Entries: 2

Rep: Reputation: 908Reputation: 908Reputation: 908Reputation: 908Reputation: 908Reputation: 908Reputation: 908Reputation: 908
What are you using to read the serial data? If it is some program that you wrote, show us the relevant code fragments.

--- rod.
 
Old 12-07-2008, 04:19 AM   #3
nasr-noor
LQ Newbie
 
Registered: Aug 2005
Posts: 15

Original Poster
Blog Entries: 1

Rep: Reputation: 0
Here is some of code :
//**************************************
//****** Receive Code in Linux *********
bool setSerial(char* portName,int parity)
{
struct termios options;
//open port
portNumber = open(portName,O_RDWR | O_NOCTTY | O_NDELAY);
if(portNumber == -1)
printf("port openning error\n");
//get the current setting of the serial port
tcgetattr(portNumber,&options);
//---------set the setting
fcntl(portNumber, F_SETFL, FNDELAY);
options.c_lflag &= ~(ICANON | ECHO | ISIG);
cfsetispeed(&options,B9600);
cfsetospeed(&options,B9600);
if(parity==0) //no parity
{
options.c_cflag &= ~PARENB;
options.c_cflag &= ~CSTOPB;
options.c_cflag &= ~CSIZE;
options.c_cflag |= CS8;
}
else if(parity==1) //odd parity
{
options.c_cflag |= PARENB;
options.c_cflag |= PARODD;
options.c_cflag |= ~CSTOPB;
options.c_cflag |= ~CSIZE;
options.c_cflag |= CS7;
}
else //even parity
{
options.c_cflag |= PARENB;
options.c_cflag |= ~PARODD;
options.c_cflag |= ~CSTOPB;
options.c_cflag |= ~CSIZE;
options.c_cflag |= CS7;
}
options.c_cflag |= (CLOCAL | CREAD);
//apply the setting to the serial port
if(tcsetattr(portNumber, TCSANOW, &options)!= 0)
printf("port setting error\n");
return true;
}

void readData(void)
{
for(j=0 ; j < readNo ; j++)
{
switch(FRAMEFLAG)
{
case 0 :if( buffer[j] == '$' )
FRAMEFLAG = 1;
break;

case 1 :Number = buffer[j];
FRAMEFLAG = 2;
break;

case 2 :if( buffer[j] == ~Number )
FRAMEFLAG = 3;
else
FRAMEFLAG = 0;
break;

case 3 :High = buffer[j];
FRAMEFLAG = 4;
break;

case 4 :Low = buffer[j];
FRAMEFLAG = 5;
break;

case 5 :if( buffer[j] == '*' )
frameEnd = true;
FRAMEFLAG = 0;
break;
}
if( frameEnd )
{
frameEnd = false;
OrderNumber = charToInt(Number);
Value = charToInt(High) * 256 + charToInt(Low);
printf("Number %d Data is : %d \n", OrderNumber, Value);
}
}
}

void* readThreadFunc(void* arg)
{
while(READON)
{
readNo = read(portNumber, buffer, bufSize);
if( readNo > 0 )
{
readData();
}
}
return NULL;
}

int main(int argc, char **argv)
{
char portNo[12] = "/dev/ttyS0";
if( !setSerial(portNo,0) ) return -1;
pthread_create(&readThread, NULL, &readThreadFunc, NULL);

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

//close serial port
if(close(portNumber) == -1) return -1;
return 1;
}

//**************************************
//****** Send Code in Windows **********

void CSendDlg:oExecute()
{
while(Run)
{
for( i=0 ; num < 250 ; i++ )
{
transmit=MainArray.GetAt(i);
if(transmit!=0)
{
SendArray.Format("%c",transmit);
MySerial.Write(SendArray);
}
//windows don't send 0x00 (it's NULL)
else
{
SendArray="";
MySerial.Write(SendArray,1);
}
}
i=0;
}
}
 
Old 12-07-2008, 04:35 AM   #4
ta0kira
Senior Member
 
Registered: Sep 2004
Distribution: FreeBSD 9.1, Kubuntu 12.10
Posts: 3,078

Rep: Reputation: Disabled
Try converting them with htonl before sending, then ntohl when receiving. That will force transmission in a universal integer format, then it will convert to the receiving host's format on the other end. I don't know what the Windows equivalents are.
ta0kira

PS Your code is very difficult to read.

Last edited by ta0kira; 12-07-2008 at 04:38 AM.
 
Old 12-07-2008, 12:21 PM   #5
theNbomr
LQ 5k Club
 
Registered: Aug 2005
Distribution: OpenSuse, Fedora, Redhat, Debian
Posts: 5,399
Blog Entries: 2

Rep: Reputation: 908Reputation: 908Reputation: 908Reputation: 908Reputation: 908Reputation: 908Reputation: 908Reputation: 908
Reading between the lines, it looks as if your Windows code is intended to be used as part of some higher level protocol. I would expect there to be a simpler API that allows you to merely send arbitrary streams of data, or even a byte-at-a-time send function. This is what you want, in order to explore where the conversion/translation is taking place.
As ta0kira said, you code is difficult to read ([code] tags would really help), but I see no obvious errors.
Can you try to create a diagnostic component on your Linux host, or some other host, which simply sends some basic data fragments under your control? Especially the bytes in question. If your Linux box has more than one serial port, you can use it to send known buffers, and see how the receiver responds. I would also consider writing a barebones receiver that dumps the received data in some human-readable format (how 'od -cb' displays binary as an example). If your high-level application is failing, you need to be able to closely inspect the lower levels to see what is truly being received.
Just to confirm that the Linux serial subsystem itself is not faulty, try setting up a Kermit file transfer between it and your Windows host.
--- rod.
 
Old 12-12-2008, 10:51 AM   #6
kalleanka
Member
 
Registered: Aug 2003
Location: Mallorca, Spain
Distribution: xubuntu
Posts: 551

Rep: Reputation: 38
well I would flush both in an out before reading.

I will come back after revising my code. Its on another computer.

Probebly some setting is wrong in setserial. Normaly its like that and I usally use a ocilloscope to detect it. Its fastest like that.
 
  


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
how to transfer and receive filein any format to and from serial port amit_pansuria Programming 3 07-18-2007 10:43 AM
how to transfer and receive file using serial port from my application amit_pansuria Programming 5 06-14-2007 05:27 PM
how to increase serial receive email buffer size? HZC Programming 0 02-14-2005 10:32 PM
RE:Email Receive Problem norm Linux - General 0 01-08-2002 04:23 AM

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

All times are GMT -5. The time now is 07:01 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