This is a multi-part message in MIME format.
--------------313F5E0791F
Content-Type: text/plain; charset=us-ascii
Content-Transfer-Encoding: 7bit
Quote:
> I am writing an app that needs to get data from a serial port. I have
> it working up to the point that it opens a serial port, configures it,
> and then uses WaitCommEvent. I have it set so it returns on a character
> recieve. Here in lies the problem. It never reads anything from the
> port? If anyone as access to a simple example that reads data like this
> using ReadFile, I would greatly appreciate emailing it to me.
> I have a deadline that is closing, and I don't want to have to by a
> third party library, like Greanleaf's, to do this simple function.
> Thanks in advance,
> Nik
The attachment is a class that starts a thread, test for a modem, dials
and reads data from the serial port. Hope it helps...
Cecil
--
Cecil Galbraith
Free programmer's utilities and MFC tips at
http://www.concentric.net/~cgalbrai
--------------313F5E0791F
Content-Type: text/plain; charset=us-ascii; name="CommTime.h"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline; filename="CommTime.h"
// CCommTime class header file
// Copyright 1996 CustomSoft (http://www.concentric.net/~cgalbrai)
// Cecil A. Galbraith
// 3217 Linden Parkway
// Harrisburg, Pennsylvania 17110 USA
#define WM_THREADFINISHED (WM_USER + 100)
#define WM_THREADMESSAGE (WM_USER + 101)
class CCommTime: public CWnd
{
public:
CCommTime();
~CCommTime();
protected:
char szTelephoneNumber[_MAX_PATH];
char szComPort[6];
DWORD iBaudRate;
public:
int Create(CWnd * pParent,char * pNum,char * pPort,DWORD iBaud);
void SetTelephoneNumber(char * pNum);
char * GetTelephoneNumber();
void SetComPort(char * pPort);
char * GetComPort();
void SetBaudRate(DWORD iBaudRate);
DWORD GetBaudRate();
void DialPhone();
void HangUpPhone();
static UINT ThreadFunc(LPVOID pParam);
Quote:
};
#define CCOMMTIME
--------------313F5E0791F
Content-Type: text/plain; charset=us-ascii; name="CommTime.cpp"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline; filename="CommTime.cpp"
// CCommTime class implementation file
// Copyright 1996 CustomSoft (http://www.concentric.net/~cgalbrai)
// Cecil A. Galbraith
// 3217 Linden Parkway
// Harrisburg, Pennsylvania 17110 USA
#include "stdafx.h"
#include "TabClock32.h"
#include "time.h"
#include "CommTime.h"
struct {
int iCommFlag;
int iBaudRate;
char szNumber[_MAX_PATH];
char szCom[6];
HWND hWnd;
Quote:
} m_ThreadInfo;
CCommTime::CCommTime()
{
szTelephoneNumber[0] = NULL;
szComPort[0] = NULL;
m_ThreadInfo.iCommFlag = 0;
Quote:
}
CCommTime::~CCommTime()
{
Quote:
}
int CCommTime::Create(CWnd * pParent,char * pNum,char * pPort,DWORD iBaud)
{
strcpy(szTelephoneNumber,pNum);
strcpy(szComPort,pPort);
iBaudRate = iBaud;
CString csClassName;
csClassName = AfxRegisterWndClass(CS_HREDRAW | CS_VREDRAW);
if(!CreateEx(NULL,
csClassName,
NULL,
WS_CHILD,
1,
1,
1,
1,
pParent->GetSafeHwnd(),
NULL,
NULL)) return 0;
return 1;
Quote:
}
void CCommTime::SetTelephoneNumber(char * pNum)
{
strcpy(szTelephoneNumber,pNum);
Quote:
}
char * CCommTime::GetTelephoneNumber()
{
return szTelephoneNumber;
Quote:
}
void CCommTime::SetBaudRate(DWORD iBaud)
{
iBaudRate = iBaud;
Quote:
}
DWORD CCommTime::GetBaudRate()
{
return iBaudRate;
Quote:
}
void CCommTime::SetComPort(char * pPort)
{
strcpy(szComPort,pPort);
Quote:
}
char * CCommTime::GetComPort()
{
return szComPort;
Quote:
}
void CCommTime::DialPhone()
{
CWinThread * pThread;
// get phone number and com port into global structure
strcpy(m_ThreadInfo.szCom,szComPort);
strcpy(m_ThreadInfo.szNumber,szTelephoneNumber);
m_ThreadInfo.iBaudRate = iBaudRate;
m_ThreadInfo.hWnd = GetParent()->GetSafeHwnd();
// create the thread
pThread = AfxBeginThread(ThreadFunc,this);
Quote:
}
UINT CCommTime::ThreadFunc(LPVOID pParam)
{
CTabClock32App * pApp;
pApp = (CTabClock32App *)AfxGetApp();
pApp->iThreadFlag = 1;
// shuts up the compiler
pParam = pParam;
// comm stuff starts here...
DCB dcb;
HANDLE hCom;
DWORD dwError;
hCom = CreateFile(m_ThreadInfo.szCom,
GENERIC_READ | GENERIC_WRITE,
// comm devices must be opened w/exclusive-access
0,
// no security attrs
NULL,
// comm devices must use OPEN_EXISTING
OPEN_EXISTING,
// not overlapped I/O
0,
// hTemplate must be NULL for comm devices
NULL
);
if (hCom == INVALID_HANDLE_VALUE) {
dwError = GetLastError();
AfxMessageBox("COM port selected is unavailable...");
CloseHandle(hCom);
m_ThreadInfo.iCommFlag = 0;
pApp->iThreadFlag = 0;
::SendMessage(m_ThreadInfo.hWnd,WM_THREADFINISHED,0,0);
AfxEndThread(0);
return 0;
}
if (!GetCommState(hCom,&dcb)) {
AfxMessageBox("Internal communications failure 0x01");
CloseHandle(hCom);
m_ThreadInfo.iCommFlag = 0;
pApp->iThreadFlag = 0;
::SendMessage(m_ThreadInfo.hWnd,WM_THREADFINISHED,0,0);
AfxEndThread(0);
return 0;
}
// Fill in the DCB: baud rate (by user) , 8 data bits, no parity, 1 stop bit
dcb.BaudRate = m_ThreadInfo.iBaudRate;
dcb.ByteSize = 8;
dcb.Parity = NOPARITY;
dcb.StopBits = ONESTOPBIT;
unsigned long counter;
counter = 0;
if (!SetCommState(hCom,&dcb)) {
AfxMessageBox("Internal communications failure 0x02");
CloseHandle(hCom);
m_ThreadInfo.iCommFlag = 0;
pApp->iThreadFlag = 0;
::SendMessage(m_ThreadInfo.hWnd,WM_THREADFINISHED,0,0);
AfxEndThread(0);
return 0;
}
// set time outs
COMMTIMEOUTS CTO;
::GetCommTimeouts(hCom,&CTO);
CTO.ReadTotalTimeoutConstant = 5000;
::SetCommTimeouts(hCom,&CTO);
// Testing for Modem Operation
unsigned long iNumberBytes;
char phone[20];
// check for OK return from modem indicating modem is ready
char szOKBuffer[20];
memset(szOKBuffer,NULL,20);
// Get attention (AT) - reset modem (Z0) - check for OK return
strcpy(phone,"ATQ2V1\r\n");
WriteFile(hCom,phone,8,&iNumberBytes,NULL);
// Send connecting message to main dialog to status text control
::SendMessage(m_ThreadInfo.hWnd,WM_THREADMESSAGE,1,0);
Sleep(125);
ReadFile(hCom,szOKBuffer,19,&iNumberBytes,NULL);
// szOKBuffer contains ATZ0 \r \n \r \n O K \r \n ......
if(!strstr(szOKBuffer,"OK")) {
if(AfxMessageBox("The modem is indicating Not Ready\nattempt to dial anyway?",MB_YESNO) == IDNO) {
CloseHandle(hCom);
m_ThreadInfo.iCommFlag = 0;
pApp->iThreadFlag = 0;
::SendMessage(m_ThreadInfo.hWnd,WM_THREADFINISHED,0,0);
AfxEndThread(0);
return 0;
}
}
// dial the number
strcpy(phone,"ATDT");//13034944774
strcat(phone,m_ThreadInfo.szNumber);
strcat(phone,"\r\n");
char szReadBuffer[4];
szReadBuffer[1] = NULL;
unsigned long iDialStringLength = strlen(phone);
while(counter < iDialStringLength) {
szReadBuffer[0] = phone[counter];
WriteFile(hCom,szReadBuffer,1,&iNumberBytes,NULL);
if(m_ThreadInfo.iCommFlag) {
WriteFile(hCom,"+++\r\n",5,&iNumberBytes,NULL);
CloseHandle(hCom);
m_ThreadInfo.iCommFlag = 0;
pApp->iThreadFlag = 0;
::SendMessage(m_ThreadInfo.hWnd,WM_THREADFINISHED,0,0);
AfxEndThread(0);
return 0;
}
counter++;
}
// connecting message
::SendMessage(m_ThreadInfo.hWnd,WM_THREADMESSAGE,2,0);
//Sleep(7000);
counter = 0;
iNumberBytes = 0;
int asteriskcounter = 0;
char szStorageBuffer[1000];
char szWriteBuffer[4];
char * pStorageBuffer;
pStorageBuffer = szStorageBuffer;
*pStorageBuffer = NULL;
char szSec[4];
char szMin[4];
char szHr[4];
iNumberBytes = 0;
int iBufferLength = 0;
while(counter < 700) {
// receiving data message
ReadFile(hCom,szWriteBuffer,1,&iNumberBytes,NULL);
szWriteBuffer[1] = NULL;
strcat(szStorageBuffer,szWriteBuffer);
counter++;
if(strstr(szStorageBuffer,"BUSY")) {
::SendMessage(m_ThreadInfo.hWnd,WM_THREADMESSAGE,6,0);
Sleep(1000);
DWORD Errors;
::ClearCommError(hCom,&Errors,NULL);
m_ThreadInfo.iCommFlag = 1;
}
if(m_ThreadInfo.iCommFlag) {
::SendMessage(m_ThreadInfo.hWnd,WM_THREADMESSAGE,5,0);
WriteFile(hCom,"ATH0\r\n",6,&iNumberBytes,NULL);
Sleep(1000);
CloseHandle(hCom);
m_ThreadInfo.iCommFlag = 0;
pApp->iThreadFlag = 0;
::SendMessage(m_ThreadInfo.hWnd,WM_THREADFINISHED,0,0);
AfxEndThread(0);
return 0;
}
iBufferLength = strlen(szStorageBuffer);
if(iBufferLength > 20 && iBufferLength < 22)
::SendMessage(m_ThreadInfo.hWnd,WM_THREADMESSAGE,3,0);
}
if(!strstr(szStorageBuffer,"National Institute of Standards and Technology")) {
AfxMessageBox("Please check the telephone number and try again...");
CloseHandle(hCom);
m_ThreadInfo.iCommFlag = 0;
pApp->iThreadFlag = 0;
::SendMessage(m_ThreadInfo.hWnd,WM_THREADFINISHED,0,0);
AfxEndThread(0);
return 0;
}
CloseHandle(hCom);
// setting system time message
::SendMessage(m_ThreadInfo.hWnd,WM_THREADMESSAGE,4,0);
Sleep(1000);
// point to first asterisk in the buffer
if(!(pStorageBuffer = strstr(szStorageBuffer,"*"))) {
// if no asterisk is found, bail out
AfxMessageBox("Buffer configuration not as expected...");
m_ThreadInfo.iCommFlag = 0;
pApp->iThreadFlag = 0;
::SendMessage(m_ThreadInfo.hWnd,WM_THREADFINISHED,0,0);
AfxEndThread(0);
}
// step to seconds, remembering \r\n pairs that we can't see
pStorageBuffer += 24 * sizeof(char);
*(pStorageBuffer + (2 * sizeof(char))) = NULL;
strcpy(szSec,pStorageBuffer);
// step back to min
pStorageBuffer -= 3 * sizeof(char);
*(pStorageBuffer + (2 * sizeof(char))) = NULL;
strcpy(szMin,pStorageBuffer);
// step back to hours
pStorageBuffer -= 3 * sizeof(char);
*(pStorageBuffer + (2 * sizeof(char))) = NULL;
strcpy(szHr,pStorageBuffer);
// note that ZULU time is five hours
...
read more »