Solved

RS-232 communication

Posted on 1997-03-10
6
291 Views
Last Modified: 2013-12-03
I am writing in Borland C Win16, and I have a problem when sending and recieving files over the comport.
I have opened the comport and then filled the complete DCB structure and then used SetCommState to set the struct.
Then I have a small loop where I reads data from a file
and then sends the same data to the comport.
It looks more or less like this

do
{
      IOStatus = _lread(hFile,(void _huge*)pBuf,fSize);
      if(IOStatus==0)
        break;
      /* This is the only control I does when sending */
      /* Is that correct ? */
      do
      {  
         err=GetComError(PortResult,&comstat);
      }while((outQue-comstat.cbOutQue)<IOStatus);
    WriteComm(PortResult,(const void FAR*)pBuf,IOStatus);
}while(IOStatus>=fSize);

But it seems like the handshaking does not work with higher baudrates, or maybe not at all, with lower baudrates maybe the handshaking is not needed.. And if I understood everything right I don't need to take care of the handshaking only not to send more then is room in the outque.
It does not matter whether I use software or hardware flow control.
Would be very happy if someone could help me or explane to me what can be the problem or what I do wrong.
    Best Regards
    Tord Karlstrom
0
Comment
Question by:tord
  • 3
  • 2
6 Comments
 
LVL 1

Expert Comment

by:gvg
ID: 1298799
I don't know if this is you actual code but if it is I have few comments

while((outQue-comstat.cbOutQue)>IOStatus);

This doesn't work.   comstat.cbOutQue is getting smaller when the port is sending so (outQue-comstat.cbOutQue) whitch indicates how much space you have in the queue is growing so you get stuck in an
endless loop.

The sign should be changed to < instead of >

You also have an extra do loop with no while.  I can't see that this extra loop makes any problem if it compiles.

Handshaking depends on what the receiver wants.  If the receiver
doesn't use handshake you shouldn't either.  But if handshake is not
used you have to be sure that the sender and receiver are both using
the same baudrate.
0
 

Author Comment

by:tord
ID: 1298800
Edited text of question
0
 

Author Comment

by:tord
ID: 1298801
I'am very sorry that my question included a few errors. The example
I did give was not taken from my real source.
Of course the > sign should be < and not the extra do loop should be included.

But the problems still exists. When I go with baudrates over 56000 baud it seems like this problem occur.
I always get a buffer overflow on the recieving side.
But it works better when both computers have more or less the same cpuspeed.
Is this correct ?
I have tried to use EscapeCommFunction to control the handshaking myself but it does not work ?
I hope I get a good answer.
0
How to run any project with ease

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

 

Expert Comment

by:MikeDabbs
ID: 1298802
How exactly are you setting up the DCB?  I'm sure I could get an answer for you if I saw this section of cade as well.
0
 

Author Comment

by:tord
ID: 1298803
Here are my DCB structure. As you can see I have a Machine structure where I have all my parameters wich have been set from a dialogbox.
Port i a string that is "COM1:" or "COM2:"
Everything works good up to 19200 and sometimes 38400 baud
but then my problems starts.
Is it a problem that I am sending from a Pentium machine to a 386 machine ?


   #define inQue 1024
   #define outQue 128

   if((PortResult=OpenComm(Port,inQue,outQue))>=0)
   {
      GetCommState(PortResult,&DCB);

      if(Machine.Baud==0)
        DCB.BaudRate=CBR_110;
      else
      if(Machine.Baud==1)
        DCB.BaudRate=CBR_300;
      else
      if(Machine.Baud==2)
        DCB.BaudRate=CBR_600;
      else
      if(Machine.Baud==3)
        DCB.BaudRate=CBR_1200;
      else
      if(Machine.Baud==4)
        DCB.BaudRate=CBR_2400;
      else
      if(Machine.Baud==5)
        DCB.BaudRate=CBR_4800;
      else
      if(Machine.Baud==6)
        DCB.BaudRate=CBR_9600;
      else
      if(Machine.Baud==7)
        DCB.BaudRate=CBR_19200;
      else
      if(Machine.Baud==8)
        DCB.BaudRate=CBR_38400;
      else
      if(Machine.Baud==9)
        DCB.BaudRate=CBR_56000;
      else
      if(Machine.Baud==10)
        DCB.BaudRate=CBR_128000;
      else
      if(Machine.Baud==11)
        DCB.BaudRate=CBR_256000;

      /* Machine.ByteSize=1/2/3/4
      DCB.ByteSize = Machine.Bytesize+4;

      if(Machine.Stopbits==1)
        DCB.StopBits       = ONESTOPBIT;
      else
      if(Machine.Stopbits==2)
        DCB.StopBits       = ONE5STOPBITS;
      else
      if(Machine.Stopbits==3)
        DCB.StopBits       = TWOSTOPBITS;

      if(Machine.Parity==0)
        DCB.Parity       = NOPARITY;
      else
      if(Machine.Parity==1)
        DCB.Parity       = EVENPARITY;
      else
      if(Machine.Parity==2)
        DCB.Parity       = ODDPARITY;
      else
      if(Machine.Parity==3)
        DCB.Parity       = MARKPARITY;

      if(Machine.Binary==0)
        DCB.fBinary  = 0;
      else
        DCB.fBinary  = 1;

      /* Machine.RtsCts=0/1
      DCB.fRtsflow = DCB.fOutxCtsFlow = (UINT)Machine.RtsCts;
      if(DCB.fRtsflow)
      {
        DCB.CtsTimeout  = 30;  /* Have tried to set to 0
        DCB.fRtsDisable = 0;
      }
      else
      {
        DCB.CtsTimeout  = 0;
        DCB.fRtsDisable = 1;
      }

      /* Machine.DtrDsr=0/1
      DCB.fDtrflow = DCB.fOutxDsrFlow = (UINT)Machine.DtrDsr;
      if(DCB.fDtrflow)
      {
        DCB.DsrTimeout  = 50;  /* Have tried to set to 0
        DCB.fDtrDisable = 0;
      }
      else
      {
        DCB.DsrTimeout  = 0;
        DCB.fDtrDisable = 1;
      }

      /* Machine.XonXoff=0/1
      DCB.fOutX = DCB.fInX  = (UINT)Machine.XonXoff;

      DCB.XonChar                     = 0x11;
      DCB.XoffChar                    = 0x13;
      DCB.XonLim                      = 128;
      DCB.XoffLim                     = inQue-256;
      if(Machine.Binary==0)
        DCB.fNull                       = 1;
      else
        DCB.fNull                       = 0;

      /* Machine.ParControl=0/1
      DCB.fParity = Machine.ParControl ;

      if(SetCommState(&DCB)!=0)
      {
          MessageBox(NULL,"Error","",MB_OK);
      }

0
 

Accepted Solution

by:
MikeDabbs earned 50 total points
ID: 1298804
You look as though you're being quite thorough while setting up the DCB.  I never try to do everything myself.  Have you investigated the BuildCommDCB function?  It sets up a lot of the DCB for you based on a definition string (i.e. COM1:9600,n,8,1)  Then you fill in the rest.  I do this, then fill in the remainder of the fields I NEED to set.  Aside from the easy ones like BAUD rate, parity, data and stop bits, these are the ones I use:

      dcb.fBinary = 1;
      dcb.fOutxCtsFlow = 1;
      dcb.fOutX = dcb.fInX = 1;
      dcb.fRtsflow = 1;
      dcb.XonChar = XON; // ascii 0x11
      dcb.XoffChar = XOFF; // ascii 0x13
      dcb.XonLim = inQue/4;
      dcb.XoffLim = (inQue*3)/4;

It looks very similar to what you have.  That's why I think that something is missing that BuildCommDCB is handling for me.  This code fragment works for me at ANY speed and (processor speed willing) never loses any characters.  It lacks the customization of what TYPE of handshaking to use, though.  I think most of them default to ON anyway, except for XON/XOFF.
0

Featured Post

What Should I Do With This Threat Intelligence?

Are you wondering if you actually need threat intelligence? The answer is yes. We explain the basics for creating useful threat intelligence.

Join & Write a Comment

As more and more people are shifting to the latest .Net frameworks, the windows presentation framework is gaining importance by the day. Many people are now turning to WPF controls to provide a rich user experience. I have been using WPF controls fo…
Entering time in Microsoft Access can be difficult. An input mask often bothers users more than helping them and won't catch all typing errors. This article shows how to create a textbox for 24-hour time input with full validation politely catching …
This is Part 3 in a 3-part series on Experts Exchange to discuss error handling in VBA code written for Excel. Part 1 of this series discussed basic error handling code using VBA. http://www.experts-exchange.com/videos/1478/Excel-Error-Handlin…
Sending a Secure fax is easy with eFax Corporate (http://www.enterprise.efax.com). First, Just open a new email message.  In the To field, type your recipient's fax number @efaxsend.com. You can even send a secure international fax — just include t…

757 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

22 Experts available now in Live!

Get 1:1 Help Now