Jump to content
  • Advertisement

Archived

This topic is now archived and is closed to further replies.

Muzlack

Serial Port programming woes....

This topic is 5612 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts


#include <stdio.h>
#include <stdlib.h>
#include <ddraw.h>
#include <dinput.h>
#include <memory.h>

#include <mmsystem.h>
#include <vector>
#include <string>
using namespace std;

int main() {
	string portname="//./COM1";

	DCB m_dcb; //get current port settings

	BOOL b; //bools for checking

	//open our port

	HANDLE hComm =  CreateFile(portname.c_str(), GENERIC_READ | GENERIC_WRITE,0,0,OPEN_EXISTING,
		0,0);
	if(hComm==INVALID_HANDLE_VALUE) { //handle errors.

		printf("PROBLEM. #1\n");
		return (1);
	}
	
	b=GetCommState(hComm,&m_dcb);
	if(b==0) {
		printf("PROBLEM. #2\n");
		CloseHandle(hComm);
		return(1);
	}

	//fill in data.

	m_dcb.BaudRate=300;
	m_dcb.ByteSize=8;
	m_dcb.Parity=NOPARITY;
	m_dcb.StopBits=ONESTOPBIT;
	m_dcb.fBinary=TRUE;
	m_dcb.fDsrSensitivity=FALSE;
	m_dcb.fParity=FALSE;
	m_dcb.fOutX=false;
	m_dcb.fInX=false;
	m_dcb.fNull=false;
	m_dcb.fAbortOnError=TRUE;
	m_dcb.fOutxCtsFlow=FALSE;
	m_dcb.fOutxDsrFlow=false;
	m_dcb.fDtrControl=DTR_CONTROL_DISABLE;
	m_dcb.fDsrSensitivity=false;
	m_dcb.fRtsControl=RTS_CONTROL_DISABLE;
	
	b=SetCommState(hComm,&m_dcb);
	if(b==0) {
		printf("PROBLEM. #3\n");
		CloseHandle(hComm);
		return(1);
	}
	printf("Succesfully initialized stuff. I hope.\n");
	BYTE rx;
	BYTE resp=0;
	DWORD dwBytesTransferred=0;
	int i=0;
	char s[50];
	while(1) {
		for(int z=0;z<500;z++) {

			if(ReadFile(hComm,&rx,1,&dwBytesTransferred,0)) {
				if(dwBytesTransferred==1) {
					resp=rx; 
					s[i]=rx;	
				} else {
					break;
				}
			}
		}
		i=0;
		printf("TEXT RECIEVED: %s\n",s);

	}
	CloseHandle(hComm);
	return(0);
}
This code produces the output "Succesfully initiated..." Now, I THINK I have this set up right to continue reading the file for information sent. In hyperterminal, on the same settings, I can press the send button on the device, and it will display on the hyperterminal screen. This is all I need. I need to be able to, as fast and rapidly as possible get string after string that this may be sending. I also heard that I can "send" ?0 to the device, and it would continuously reply back, but I couldn''t get this to work under hyperterminal, so I''d like to go with the send button for now. Any comments on how to fix?

Share this post


Link to post
Share on other sites
Advertisement
i fiddle with the com port for a bit, i will send you my source code when i get home, can you e-mail me plz.

thanx
-danushka



A GOOD friend will come bail you out of jail...
but, a TRUE friend will be sitting next to you saying, "Damn, we fucked up."
Ingite 3D Game Engine Home -- Just click it

Share this post


Link to post
Share on other sites
Not exactly certain about what device you are trying to read from, but nevertheless, I pretty much followed one of the SDK samples to directly control my modem through the serial port.
Here is the relevant code I ended up using.


... snip ...

bool ModemAvailable()
{
if(hModem)
return false;
HANDLE temp= hModem=CreateFile( "COM1:", GENERIC_READ | GENERIC_WRITE,
0, // exclusive access

NULL, // no security attributes

OPEN_EXISTING,
FILE_FLAG_OVERLAPPED,
NULL
);
if(temp==INVALID_HANDLE_VALUE)
return false;
CloseHandle(temp);
return true;
}

DWORD WINAPI ReadingWorkerThread(LPVOID info)
{
BUNDLE *p=(BUNDLE*)(info);
if(!p || !p->hModem || !p->hWnd)
return 1;
DWORD rxevent=EV_RXCHAR | EV_RXFLAG;
DWORD readin;
bool doread=false;
bool waitingonread=false;
bool waitingonstat=false;
char readbuff[2050];
readbuff[2049]=0;
readbuff[2048]=0;
OVERLAPPED ovrstat={0};
OVERLAPPED ovrread={0};
SetCommMask(p->hModem, rxevent);
DWORD result=0;
ovrstat.hEvent=CreateEvent(NULL,TRUE,FALSE,NULL);
if(!ovrstat.hEvent)
return 10;
ovrread.hEvent=CreateEvent(NULL,TRUE,FALSE,NULL);
if(!ovrread.hEvent)
{
CloseHandle(ovrstat.hEvent);
return 11;
}
DWORD errors;

ClearCommError(p->hModem,&errors,NULL);

HANDLE evarray[3];
evarray[0]=ovrread.hEvent;
evarray[1]=ovrstat.hEvent;
evarray[2]=ghExitEvent;
DWORD err;
while(1)
{

if(!waitingonread)
{
if(!ReadFile(p->hModem,&readbuff,512,&readin,&ovrread))
{
err=GetLastError();
if(err!=ERROR_IO_PENDING)
{
SafeOutputDebugString("ReadFile failed");
result=1;
break;
}
waitingonread=true;
}
else
{
if(readin)
{
readbuff[readin]=0;
ProcessInput(readbuff,readin);
}
}
}

if(!waitingonstat)
{
DWORD rex=0;
if(!WaitCommEvent(p->hModem,&rex /*&rxevent*/,&ovrstat))
{
err=GetLastError();
if(err!=ERROR_IO_PENDING)
{
result=2;
break;
}
waitingonstat=true;
}
}
if(p->quit)
break;

if(waitingonread && waitingonstat)
{
DWORD res=WaitForMultipleObjects(3,evarray,FALSE,500);
switch(res)
{
case WAIT_OBJECT_0:
if(!GetOverlappedResult(p->hModem,&ovrread,&readin,FALSE))
{
err=GetLastError();
if(err!=ERROR_OPERATION_ABORTED)
{
result=3;
break;
}
}
if(readin)
{
readbuff[readin]=0;
ProcessInput(readbuff,readin);
}
waitingonread=false;
break;
case WAIT_OBJECT_0+1:
if(!GetOverlappedResult(p->hModem,&ovrstat,&readin,FALSE))
{
err=GetLastError();
if(err!=ERROR_OPERATION_ABORTED)
{
result=4;
break;
}
}
waitingonstat=false;
break;
case WAIT_OBJECT_0+2:
result=999;
ResetEvent(ghExitEvent);
break;
case WAIT_TIMEOUT:
break;
default:
result=5;
break;
}
if(result)
break;

}
}
if(result==999)
{
SafeOutputDebugString("************ READER THREAD EXITING BY WAIT_OBJECT_0+2");
result=0;
}
else
{
if(!result)
SafeOutputDebugString("************ READER THREAD EXITING NORMALLY");
}
CloseHandle(evarray[0]);
CloseHandle(evarray[1]);
return result;
}

bool OpenModem()
{
if(hModem)
return true;

reader_bundle.quit=FALSE;
hModem=CreateFile( "COM1:", GENERIC_READ | GENERIC_WRITE,
0, // exclusive access

NULL, // no security attributes

OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED,
NULL
);

if(hModem == INVALID_HANDLE_VALUE)
{
hModem=NULL;
return false;
}
DCB dcb = {0};
dcb.DCBlength = sizeof(dcb);
if(!GetCommState(hModem,&dcb))
{
hModem=NULL;
return false;
}

dcb.BaudRate=CBR_9600;
dcb.ByteSize=8;
dcb.Parity=NOPARITY;
dcb.StopBits=ONESTOPBIT;
dcb.fBinary=TRUE;
dcb.fParity=FALSE;
dcb.EvtChar = ''\0'';
dcb.fDtrControl=DTR_CONTROL_ENABLE;
dcb.fRtsControl=RTS_CONTROL_ENABLE;

dcb.fOutxCtsFlow = FALSE;
dcb.fOutxDsrFlow = FALSE;
dcb.fDsrSensitivity = FALSE;
dcb.fOutX = FALSE;
dcb.fInX = FALSE;
dcb.fTXContinueOnXoff = FALSE;
dcb.XonChar = ASCII_XON;
dcb.XoffChar = ASCII_XOFF;
dcb.XonLim = 0;
dcb.XoffLim = 0;

SetCommState(hModem,&dcb);
SetCommTimeouts(hModem,&gTimeouts);
SetupComm(hModem,2048,1024);

reader_bundle.hModem=hModem;
reader_bundle.hWnd=ghWnd;

readerThread=CreateThread(NULL,0,ReadingWorkerThread,&reader_bundle,0,&readerThreadId);
if(!readerThread)
{
CloseModem();
return false;
}
InitModem();
state=ackini;
return true;
}

void CloseModem()
{
reader_bundle.quit=TRUE;
if(ghExitEvent)
{
SetEvent(ghExitEvent);
Sleep(500); // lets wait a few a bit for reader thread to terminate nicely

}
if(hModem)
{
PurgeComm(hModem,PURGE_RXABORT | PURGE_TXABORT);
SetCommMask(hModem,0); // don''t trigger any events, and make WaitCommEvent exit immediately to signal other threads to quit

EscapeCommFunction(hModem,CLRDTR); // drop dtr to make modem hang up (since modem is configured to hangup when dtr is dropped)

CloseHandle(hModem);
hModem=NULL;
}
readerThreadId=0;
readerThread=NULL;
}

Share this post


Link to post
Share on other sites
Instead of Sleep(500), you can call WaitForSingleObject(readerThread, 5000) which will return either after 5000ms or once the reader thread terminates (whichever happens first). If it times-out, you shold call TerminateThread(readerThread) to make certain it dies.

Share this post


Link to post
Share on other sites
Is there any real differences in our code besides the way they are structured?

BTW--silvermace, still waiting for e-mail.

Share this post


Link to post
Share on other sites
Could I have that code also?
I do Robotics, and need some info on how to work the serial port under c++, i''ve been doing it undr VB6, but I want to connect it to my gfx engine, and to do that i need c++.

Thank you,

[Hugo Ferreira][Positronic Dreams]
I Am Digerati.

Share this post


Link to post
Share on other sites
quote:
Original post by Muzlack
Is there any real differences in our code besides the way they are structured?

BTW--silvermace, still waiting for e-mail.


There are some fairly big differences. For one, you are not using overlapped i/o. Second, you don''t seem to be using any type of flow control.

Share this post


Link to post
Share on other sites

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!