Solved

RS-232 communication

Posted on 1997-03-10
6
292 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
Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

 

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

Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

This article shows how to make a Windows 7 gadget that accepts files dropped from the Windows Explorer.  It also illustrates how to give your gadget a non-rectangular shape and how to add some nifty visual effects to text displayed in a your gadget.…
If you have ever found yourself doing a repetitive action with the mouse and keyboard, and if you have even a little programming experience, there is a good chance that you can use a text editor to whip together a sort of macro to automate the proce…
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…
This is used to tweak the memory usage for your computer, it is used for servers more so than workstations but just be careful editing registry settings as it may cause irreversible results. I hold no responsibility for anything you do to the regist…

863 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

25 Experts available now in Live!

Get 1:1 Help Now