nsuresh
asked on
serial port gurus URGENT
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.ReadIntervalTimeo ut = MAXDWORD;
timeouts.ReadTotalTimeoutM ultiplier = MAXDWORD ;
timeouts.ReadTotalTimeoutC onstant = 100;
timeouts.WriteTotalTimeout Multiplier = 10 ;
timeouts.WriteTotalTimeout Constant = 100 ;
success = SetCommTimeouts( comHandle, &timeouts ) ;
if (!success)
return (int) -4;
// Set the DTR line
EscapeCommFunction(comHand le, 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,NU LL);
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);
}
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.ReadIntervalTimeo
timeouts.ReadTotalTimeoutM
timeouts.ReadTotalTimeoutC
timeouts.WriteTotalTimeout
timeouts.WriteTotalTimeout
success = SetCommTimeouts( comHandle, &timeouts ) ;
if (!success)
return (int) -4;
// Set the DTR line
EscapeCommFunction(comHand
*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(
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,NU
FlushFileBuffers(outHandle
if (! success) {
continue;
}
if (numWrite != in_cnt) {
success=FALSE;
continue;
}
//in_buf[0] = 0;
memset(in_buf,'\0',sizeof(
in_cnt = 0;
}
}/* switch */
}// while
CloseHandle (inHandle);
CloseHandle (outHandle);
}
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
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
will do that soon
incidentally i found the same problem with the accessories/hyperterm also
thanx a lot
suresh
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
Moondancer
Moderator @ Experts Exchange
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:",c
if ( (comfd=CreateFile(comName,
scError(SCE_CREATE);
return -1;
}
if ( !SetupComm(comfd,1024,1024
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.ReadTotalTimeoutMultipl
ct.ReadTotalTimeoutConstan
ct.WriteTotalTimeoutMultip
ct.WriteTotalTimeoutConsta
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,bufSiz
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,bufSi
scError(SCE_WRITE);
return -1;
}
return bytesWritten;
}
// --------------------------
static void
scError(int e)
{
errCode = e;
if ( SCE_BASE<=errCode && errCode<=SCE_PEAK )
strcpy(errText,scErrList[e
else
strcpy(errText,"Unknown error");
}