Still celebrating National IT Professionals Day with 3 months of free Premium Membership. Use Code ITDAY17

x
?
Solved

serial port gurus  URGENT

Posted on 1999-10-05
4
Medium Priority
?
418 Views
Last Modified: 2013-11-15
hi

i'm developing an application to read data
from  a serial port of the PC , on Windows95
The strange behaviour , i'm observing is that
sometimes , i'm missing out some characters

i'm posting the extracts of the code here .
This is a direct read case ..ie ,No error
checking protocol exists.

Could someone tell me the possible reasons of me missing
out characters ??

this functions are meant to be called from a pb application
the caller first calls opencomm() and then calls chat()
with the obtained handle
the problem is in the chat() function's readfile
ie sometimes some characters are missing

i hope i have made myself clear.
This is urgent ,Please get back at u'r earliest .

Regards
Suresh

int __declspec(dllexport) __stdcall OpenComm(char *commport,int baudrate,int bits,char parity,int stop,
                              HANDLE *retHandle)
{
      HANDLE comHandle;
      BOOL success;
      DCB dcb;
      COMMTIMEOUTS timeouts;
      char buf[1000];

      
      comHandle = CreateFile(commport,
            GENERIC_READ|GENERIC_WRITE,
            0, 0, OPEN_EXISTING,
            //FILE_FLAG_OVERLAPPED, 0);
            FILE_ATTRIBUTE_NORMAL, 0);

      if (comHandle == INVALID_HANDLE_VALUE) {
                        return (int)-1;
      }      

      // Get the current COMM settings
      success = GetCommState(comHandle, &dcb);
      if (!success)
            return (int)-2;
      
            
      dcb.BaudRate = baudrate;
      dcb.ByteSize = bits;

      switch (parity) {
      case 'O' : dcb.Parity = ODDPARITY;break;
      case 'N' : dcb.Parity = NOPARITY;break;
      case 'E' : dcb.Parity = EVENPARITY;break;
      }

      switch (stop) {
      case 1   : dcb.StopBits = ONESTOPBIT;break;
      /* case 1.5 : dcb.StopBits = ONE5STOPBITS;break; */
      case 2   : dcb.StopBits = TWOSTOPBITS;break;
      }

      // Set flow control
      dcb.fInX = dcb.fOutX = TRUE;
      dcb.XonLim = 50;
      dcb.XoffLim = 200;
      dcb.XonChar = XON;
      dcb.XoffChar = XOF;


      // Save the COMM settings
      success = SetCommState(comHandle, &dcb);
      if (!success)
            return (int) -3;
            

      // Set the timeouts
      timeouts.ReadIntervalTimeout                  = MAXDWORD;
      timeouts.ReadTotalTimeoutMultiplier            = MAXDWORD ;
      timeouts.ReadTotalTimeoutConstant            = 100;
      timeouts.WriteTotalTimeoutMultiplier      = 10 ;
      timeouts.WriteTotalTimeoutConstant            = 100 ;
      success = SetCommTimeouts( comHandle, &timeouts ) ;

      if (!success)
            
            return (int) -4;
      

      // Set the DTR line
      EscapeCommFunction(comHandle, SETDTR);

      *retHandle = comHandle;


      return (int) 1;
}


/* read from scanner ,write to outfile */

int __declspec(dllexport) __stdcall Chat (HANDLE comHandle,char *outfile )

/*      returns number of records
      outfile is file to store data output from scanner
      infile  is file to be read in and transmitted to scanner
 */


      char in_buf[1024]
      char c;
      DWORD in_cnt = 0;
      DWORD      numRead,numWrite;
      BOOL      success = TRUE;
      // BOOL      cont = TRUE;
      int      stx_flag = 0;

      
      DWORD      error = 0;
      int      rec_cnt = 0;
      int t = 0, nothing_to_read = 0, more_to_read = 1;
      HANDLE      inHandle,outHandle;




      memset(in_buf,'\0',sizeof(in_buf));

      outHandle = CreateFile(outfile,
            GENERIC_WRITE,
            0, 0, CREATE_ALWAYS,
            FILE_ATTRIBUTE_NORMAL, 0);

      if (outHandle == INVALID_HANDLE_VALUE) {

            error = OUTFILE_ERROR;
      }

      
      while (success && error == 0 && more_to_read)
      {
            
            success = ReadFile(comHandle, &c, 1,&numRead, 0);

            if(!success) // i'm having problems here
                  break;


            if (numRead != 1)
            {

      
                  // no outstanding, or nothing after some time
                  if (more_to_read == 1 || nothing_to_read >= 50)
                  
                  {
                        if(rec_cnt)
                              error=1;

                        break;
                  }


                  
                  nothing_to_read++;
                  continue;
            }

            nothing_to_read = 0;
            more_to_read++;

            switch (c)
            {
            case STX : /* transmission starts with stx*/
                  
                  stx_flag = 1;
                  break;

            case ETX : /* and ends with etx/etb */
            case ETB :
                  more_to_read=0;
                  break;
            default :
                  in_buf[in_cnt] = c;
                  in_cnt++;
            
                  if(stx_flag && c == LF)
                  {
                                /* write output to file */
                        success = WriteFile (outHandle,      in_buf,in_cnt,&numWrite,NULL);
                        FlushFileBuffers(outHandle);
                        if (! success) {
                              continue;
                        }
                        if (numWrite != in_cnt) {
                              success=FALSE;
                              continue;
                        }
                        //in_buf[0] = 0;
                        memset(in_buf,'\0',sizeof(in_buf));
                        in_cnt = 0;
                  }
            
                  
                  }/* switch */
            
      }// while
      CloseHandle (inHandle);
      CloseHandle (outHandle);
      
}



0
Comment
Question by:nsuresh
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
4 Comments
 
LVL 6

Expert Comment

by:zebada
ID: 2099851
I haven't looked at your code in detail, but it looks OK.
Try this code, it works for me...

synchcom.h
----------
// *************************************************************************
// *                                                                       *
// *                       (C) - 1999 Paul Blackmore                       *
// *                                                                       *
// *************************************************************************
//
// Modifications
// -------------------------------------------------------------------------
// Version | When        | Who | Why
// --------+-------------+-----+--------------------------------------------
// 1.0     | 1999-Sep-21 | PSB | Created program
//         |             |     |
// --------+-------------+-----+--------------------------------------------
//         |             |     |
//         |             |     |
// -------------------------------------------------------------------------


#if !defined(SC_H_INCLUDED)
#define SC_H_INCLUDED

#include  <windows.h>

#ifdef _WIN32
  #ifdef _SCDLL
    #define SC_DLL __declspec(dllexport)
  #else
    #define SC_DLL __declspec(dllimport)
  #endif
#else
  #define SC_DLL
#endif

// SyncCom Errors:
#define SCE_BASE        20000       // Base of SyncCom error numbers.
#define SCE_INIT        SCE_BASE+0  // Com port not initialised, call comInit() first.
#define SCE_READ        SCE_BASE+1  // No data read.
#define SCE_WRITE       SCE_BASE+2  // No data written.
#define SCE_CREATE      SCE_BASE+3  // Can't create connection to com port.
#define SCE_SETUP       SCE_BASE+4  // Can't setup buffers for com port.
#define SCE_GETCOM      SCE_BASE+5  // Can't read com port settings.
#define SCE_SETCOM      SCE_BASE+6  // Can't write com port settings.
#define SCE_BUILD       SCE_BASE+7  // Can't build Device Control Block.
#define SCE_GETCOMTIME  SCE_BASE+8  // Can't read com port timeout settings.
#define SCE_SETCOMTIME  SCE_BASE+9  // Can't write com port timeout settings.

#define SCE_PEAK        SCE_BASE+9  // Upper bound of SyncCom error numbers.

// Constants
#define MAX_ERRMSGLEN   1024                // Maximum error message length
#define MAX_BUFLEN      80          // Maximum length of data buffer
#define MAX_COMSPECLEN  64          // Maximum length of com specification

// Global variables
extern SC_DLL int       errCode;    // Error code
extern SC_DLL char      errText[];  // error message

// API Functions
SC_DLL int scInit(int comid,char *comspec);
//     Initialises com port with compsec.
//         comid is the COM port number 1=COM1, 2=COM2 etc
//         comspec is the COM port specification: "baud=8192 parity=N stop=1 data=8"
//     Return value:
//         0: OK
//        -1: FAIL check global variables: errCode and errText

SC_DLL int scTimeOut(int t1,int t2,int t3);
//     Sets up com port timeouts, default: t1=5,t2=1,t3=10.
//         Each byte must be received within t1 milliseconds of previous byte.
//         All bytes must be received within (t2*bytes reqested)+t3 milliseconds.
//     Return value:
//         0: OK
//        -1: FAIL check global variables: errCode and errText

SC_DLL int scDone(void);
//     Closes com port and releases it for other applications
//     Return value:
//         0: OK
//        -1: FAIL check global variables: errCode and errText

SC_DLL int scRead(char *buf,int bufSize);
//     Attempts to reads bufSize bytes of data from comport into buf.
//     Return value:
//       >=0: OK, number of bytes read.
//        -1: FAIL check global variables: errCode and errText

SC_DLL int scWrite(char *buf,int bufSize);
//     Attempts to write bufSize bytes of data from buf to comport.
//     Return value:
//       >=0: OK, number of bytes written.
//        -1: FAIL check global variables: errCode and errText

#endif

synchcom.c
----------
// *************************************************************************
// *                                                                       *
// *                       (C) - 1999 Paul Blackmore                       *
// *                                                                       *
// *************************************************************************
//
// Modifications
// -------------------------------------------------------------------------
// Version | When        | Who | Why
// --------+-------------+-----+--------------------------------------------
// 1.0     | 1999-Sep-21 | PSB | Created program
//         |             |     |
// --------+-------------+-----+--------------------------------------------
//         |             |     |
//         |             |     |
// -------------------------------------------------------------------------

#define _SCDLL

#include <stdio.h>
#include "synchcom.h"

SC_DLL int    errCode;
SC_DLL char   errText[MAX_ERRMSGLEN+1];

static HANDLE       *comfd=NULL;
static COMMTIMEOUTS ct;
static DCB          dcb;
static char         comName[32];

static char         *scErrList[SCE_PEAK] = {
                      "Com port is not initialised, call scInit() first.\n",
                      "No data received.\n",
                      "No data sent.\n",
                      "Can't create connection to com port.",
                      "Can't setup buffers for com port.",
                      "Can't read com port settings.",
                      "Can't write com port settings.",
                      "Can't build Device Control Block.",
                      "Can't read com port timeout settings.",
                      "Can't write com port timeout settings."
                    };
static char         aldl[1024];
static BYTE         eprom[0x10000];

static void scError(int e);

// -------------------------------------------------------------------------
SC_DLL int
scInit(int comid,char *comspec)
{

  sprintf(comName,"COM%d:",comid);

  if ( (comfd=CreateFile(comName,GENERIC_READ|GENERIC_WRITE,0,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL))==INVALID_HANDLE_VALUE ) {
    scError(SCE_CREATE);
    return -1;
  }
   
  if ( !SetupComm(comfd,1024,1024)!=0 ) {
    scError(SCE_SETUP);
    return -1;
  }

  if ( !GetCommState(comfd,&dcb) ) {
    scError(SCE_GETCOM);
    return -1;
  }

  if ( !BuildCommDCB(comspec,&dcb) ) {
    scError(SCE_BUILD);
    return -1;
  }

  // Set minimal flow control
  dcb.fOutxCtsFlow = 0;
  dcb.fOutxDsrFlow = 0;
  dcb.fDtrControl = DTR_CONTROL_DISABLE;
  dcb.fDsrSensitivity = 0;
  dcb.fOutX = 0;
  dcb.fInX = 0;
  dcb.fRtsControl = RTS_CONTROL_DISABLE;

  if ( !SetCommState(comfd,&dcb) ) {
    scError(SCE_SETCOM);
    return -1;
  }

  // Set default timeouts
  if ( scTimeOut(5,1,10)<0 ) {
    printf("Error %d: %s\n",errCode,errText);
    return -1;
  }

  return 0;
}

// -------------------------------------------------------------------------
SC_DLL int
scDone()
{
  if ( comfd==NULL ) {
    scError(SCE_INIT);
    return -1;
  }

  CloseHandle(comfd);
  comfd = NULL;

  return 0;
}

// -------------------------------------------------------------------------
SC_DLL int
scTimeOut(int t1,int t2,int t3)
{
  if ( comfd==NULL ) {
    scError(SCE_INIT);
    return -1;
  }

  if ( !GetCommTimeouts(comfd,&ct) ) {
    scError(SCE_GETCOMTIME);
    return -1;
  }

  // t1: Maximum number of millisecond to wait between each received byte.
  // t2: Wait for t2*nBytesToRead milliseconds for all bytes to be received.
  // t3: Wait an additional t3 milliseconds.

  ct.ReadIntervalTimeout = t1;
  ct.ReadTotalTimeoutMultiplier = t2;
  ct.ReadTotalTimeoutConstant = t3;

  ct.WriteTotalTimeoutMultiplier = 10;
  ct.WriteTotalTimeoutConstant = 100;
 
  if ( !SetCommTimeouts(comfd,&ct) ) {
    scError(SCE_SETCOMTIME);
    return -1;
  }
  return 0;
}

// -------------------------------------------------------------------------
SC_DLL int
scRead(char *buf,int bufSize)
{
  int  bytesRead;

  if ( comfd==NULL ) {
    scError(SCE_INIT);
    return -1;
  }

  if ( !ReadFile(comfd,buf,bufSize,&bytesRead,NULL) ) {
    scError(SCE_READ);
    return -1;
  }
  return bytesRead;
}

// -------------------------------------------------------------------------
SC_DLL int
scWrite(char *buf,int bufSize)
{
  int bytesWritten;

  if ( comfd==NULL ) {
    scError(SCE_INIT);
    return -1;
  }

  if ( !WriteFile(comfd,buf,bufSize,&bytesWritten,NULL) ) {
    scError(SCE_WRITE);
    return -1;
  }
  return bytesWritten;
}

// -------------------------------------------------------------------------
static void
scError(int e)
{
  errCode = e;
  if ( SCE_BASE<=errCode && errCode<=SCE_PEAK )
    strcpy(errText,scErrList[errCode-SCE_BASE]);
  else
    strcpy(errText,"Unknown error");
}
0
 
LVL 2

Accepted Solution

by:
baeg earned 1000 total points
ID: 2102971
Try this It works, but I only cutting off my source code. !st call Hcomm to get the hComm handler, then U can call write/read functions, this code can bring up windows standard serial setup dialog too. Some of variables definition maybe missing, but you can find out the types, and some function (e.g. pr("")) which you dont need so cut them out. And If you dont need to write the registry with your params the cut that lines begining theApp.xxx

Good Luck



HANDLE hComm;

long Hcomm()
{
ujra:
      if (!hComm) {
            DCB m_dcb = {0};
          COMMTIMEOUTS m_ctmoTimeout;
 
      // open the port
            if ( (hComm = CreateFile( "COM1",GENERIC_READ | GENERIC_WRITE,
              0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL,
              NULL )) == (HANDLE) -1 ){

                  hComm=0;
                  if (AfxMessageBox("Can't Open COM1, because it is in already use!",MB_RETRYCANCEL|MB_ICONINFORMATION|MB_ICONINFORMATION   )==IDRETRY) goto ujra;
                  return 0;
            }
   
            m_dcb.DCBlength=sizeof(m_dcb);

  // get the Device Control Block
            if ( !GetCommState( hComm, &m_dcb ) ) {
              CloseHandle(hComm);
              hComm=0;
              if (AfxMessageBox("Can't get COM1 device block!",MB_RETRYCANCEL|MB_ICONINFORMATION|MB_ICONINFORMATION)==IDRETRY) goto ujra;
              return 0;      
            }
   
  // put in our values
        m_dcb.BaudRate = theApp.GetProfileInt(serial,"Baud",2400);       //!!!!!!!!!!!!
        m_dcb.fDtrControl = DTR_CONTROL_ENABLE;
        m_dcb.fDsrSensitivity = FALSE;
        m_dcb.fOutX = FALSE;
        m_dcb.fInX = FALSE;
        m_dcb.fNull = FALSE;
        m_dcb.fRtsControl = RTS_CONTROL_ENABLE;
        m_dcb.fAbortOnError = TRUE;
        m_dcb.ByteSize = theApp.GetProfileInt(serial,"Data",8);                         //!!!!!!!!!!!!
        m_dcb.Parity =   theApp.GetProfileInt(serial,"Parity",NOPARITY);        //!!!!!!!!!!!!
        m_dcb.StopBits = theApp.GetProfileInt(serial,"Stop",ONESTOPBIT);                //!!!!!!!!!!!!
   
        if ( !SetCommState(hComm, &m_dcb) ){
              CloseHandle(hComm);
              hComm=0;
              if (AfxMessageBox("Can't set COM1 status!",MB_RETRYCANCEL|MB_ICONINFORMATION)==IDRETRY) goto ujra;
              return 0;      
        }
   
  // set the comm timeout
        if ( !GetCommTimeouts(hComm, &m_ctmoTimeout) ){
              CloseHandle(hComm);
              hComm=0;
              if (AfxMessageBox("Can't get COM1 TimeOut variables!",MB_RETRYCANCEL|MB_ICONINFORMATION)==IDRETRY) goto ujra;
              return 0;      
        }

  // timeout after COMM_TIMEOUT_MS milliseconds
         m_ctmoTimeout.ReadIntervalTimeout = 15L;
        m_ctmoTimeout.ReadTotalTimeoutMultiplier = 10L;
        m_ctmoTimeout.ReadTotalTimeoutConstant = 60L;
        m_ctmoTimeout.WriteTotalTimeoutMultiplier = 1L;
        m_ctmoTimeout.WriteTotalTimeoutConstant = 60L;

        if ( !SetCommTimeouts(hComm, &m_ctmoTimeout) ){
              CloseHandle(hComm);
              hComm=0;
              if (AfxMessageBox("Can't set COM1 TimeOut variables!",MB_RETRYCANCEL|MB_ICONINFORMATION)==IDRETRY) goto ujra;
              return 0;      
        }

        {
              char s[256];
              sprintf (s,"COM1: %lu Baud, %lu bit data, ",m_dcb.BaudRate,m_dcb.ByteSize);
              switch (m_dcb.Parity) {
              case NOPARITY:  sprintf(s+strlen(s),"No Parity, ");break;
              case ODDPARITY: sprintf(s+strlen(s),"Odd Parity, ");break;          
              case EVENPARITY:sprintf(s+strlen(s),"Even Parity, ");break;          
              case MARKPARITY:sprintf(s+strlen(s),"Mark Parity, ");break;          
              case SPACEPARITY:sprintf(s+strlen(s),"Space Parity ");break;        
              default: sprintf(s+strlen(s),"Unknow Parity ");break;        
              }

              switch (m_dcb.StopBits) {
              case ONESTOPBIT:   sprintf(s+strlen(s),"1 stop bit");break;      
              case ONE5STOPBITS: sprintf(s+strlen(s),"1.5 stop bit");break;      
              case TWOSTOPBITS:  sprintf(s+strlen(s),"2 stop bits ");break;      
              default:           sprintf(s+strlen(s),"Unknow stop bits");break;      
              }

              Pr(s);
        }

        return 1;
      }
      else return 1;
}

void OnSetup()
{
      COMMCONFIG cc;


//      if (!Hcomm()) return;

    cc.dwSize=sizeof(cc);  
    cc.wVersion=0;  
      GetCommState( hComm, &cc.dcb );
    cc.dwProviderSubType=0;
    cc.dwProviderOffset=0;
    cc.dwProviderSize=0;
 
      if (CommConfigDialog("COM1",GetSafeHwnd(),&cc)) {


        theApp.WriteProfileInt(serial,"Baud",cc.dcb.BaudRate);
        theApp.WriteProfileInt(serial,"Data",cc.dcb.ByteSize);
        theApp.WriteProfileInt(serial,"Parity",cc.dcb.Parity);
        theApp.WriteProfileInt(serial,"Stop",cc.dcb.StopBits);

        CloseHandle(hComm);
        hComm=0;
        if (!Hcomm()) return;
      }
}


void Write(long num)
{
  DWORD wr=0;
  char s[256];
        if (!Hcomm()) {
              Pr("Write Command Aborted");
              return;
        }
        if (!WriteFile( hComm,buff,num,&wr,NULL)) {
              Pr("S: Sending Error");
              return;
        }
        if (wr!=(DWORD)num) {
              sprintf(s,"E: Error %l bytes are sent, instead of %lu",wr,num);
              Pr(s);         
        }
        
        sprintf (s,"S: ");
      for (long a=0; a<num; a++)         
              sprintf (s+strlen(s),"%02x ",buff[a]);
        
        Pr(s);         
}

void ReadChk(long num,long ID)
{
  DWORD wr=0;
  char s[256];
  unsigned char rbuff[256];
  if (!hComm) {
          Pr("Read Command Aborted");
          return;
  }

  if (!ReadFile( hComm,rbuff,200,&wr,NULL)) {
            Pr("R: TimeOut Error");
             sprintf (s,"E: ");
              for (long a=0; a<num; a++)         
                    sprintf (s+strlen(s),"%02x ",rbuff[a]);
            Pr(s);

            if (ID) {
                  s[0]=0;
                    for (long a=1; a<num; a++)         
                          sprintf (s+strlen(s),"%02x ",rbuff[a]);
                  SetDlgItemText(ID,s);
            }
            return;
  }

  if (wr!=(DWORD)num) {
          sprintf(s,"E: Error %lu bytes are received, instead of %lu",wr,num);
        Pr(s);
  }

   sprintf (s,"R: ");

   for (long a=0; a<num; a++)         
              sprintf (s+strlen(s),"%02x ",rbuff[a]);
   
  Pr(s);

        if (ID) {
            s[0]=0;
              for (long a=1; a<num; a++)         
                  sprintf (s+strlen(s),"%02x ",rbuff[a]);
            SetDlgItemText(ID,s);
      }
  if (buff[0]!=rbuff[0]) Pr("R: Wrong checked command");

}
0
 

Author Comment

by:nsuresh
ID: 2115416
i could not try this out ,
will do that soon
incidentally i found the same problem with the accessories/hyperterm also

thanx a lot
suresh


0
 
LVL 1

Expert Comment

by:Moondancer
ID: 6821310
This question was awarded, but never cleared due to the JSP-500 errors of that time.  It was "stuck" against userID -1 versus the intended expert whom you awarded.  This corrects that and the expert will now receive these points, all verified.
Moondancer
Moderator @ Experts Exchange
0

Featured Post

Hire Technology Freelancers with Gigs

Work with freelancers specializing in everything from database administration to programming, who have proven themselves as experts in their field. Hire the best, collaborate easily, pay securely, and get projects done right.

Question has a verified solution.

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

This article was originally published on Monitis Blog, you can check it here . If you have responsibility for software in production, I bet you’d like to know more about it. I don’t mean that you’d like an extra peek into the bowels of the sourc…
In this article I discuss my selections of the Top Four free Outlook OST File Viewers available. Open, view and read even damaged OST files by using these tools. They all provide a clear preview of all data such as emails, notes, tasks, calendars, e…
The viewer will learn how to successfully create a multiboot device using the SARDU utility on Windows 7. Start the SARDU utility: Change the image directory to wherever you store your ISOs, this will prevent you from having 2 copies of an ISO wit…
In this brief tutorial Pawel from AdRem Software explains how you can quickly find out which services are running on your network, or what are the IP addresses of servers responsible for each service. Software used is freeware NetCrunch Tools (https…

721 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