Hello,
I am having troubles with sending data through RS232. I am using the class from Ramon de Klein:
http://www.codeproject.com/system/serial.asp
There I am working with the simple Serial Class (Overlapped).
My problem is that I can only send 16 Byte all together. If I try to send more than 16 Byte, its sending an empty message and I get a NAK from the other side ( I monitored this with a monitoring tool).
This is what the Overlapped structure is set to after sending data:
<br />
Internal 258 unsigned long<br />
InternalHigh 16 unsigned long<br />
Offset 0 unsigned long<br />
OffsetHigh 0 unsigned long<br />
Pointer 0x00000000 void *<br />
hEvent 0x00000780 void *<br />
As you can see, InternalHigh is set to 16. I dont know why. I cant figure out why I am only allowed to send 16 Byte. The dwInQueue as well as the dwOutQueue is big enough to hold more data.
The problem is that I absolutely have no clue where to search for that problem.
Is there anything that restricts the number of bytes to send?
Which codepart can be relevant for you?
This the write method:
<br />
LONG CSerial::Write (const void* pData, size_t iLen, DWORD* pdwWritten, LPOVERLAPPED lpOverlapped, DWORD dwTimeout)<br />
{<br />
CheckRequirements(lpOverlapped,dwTimeout);<br />
<br />
_ASSERTE(!lpOverlapped || pdwWritten);<br />
<br />
m_lLastError = ERROR_SUCCESS;<br />
<br />
DWORD dwWritten;<br />
if (pdwWritten == 0)<br />
{<br />
pdwWritten = &dwWritten;<br />
}<br />
<br />
*pdwWritten = 0;<br />
<br />
if (m_hFile == 0)<br />
{<br />
m_lLastError = ERROR_INVALID_HANDLE;<br />
<br />
_RPTF0(_CRT_WARN,"CSerial::Write - Device is not opened\n");<br />
return m_lLastError;<br />
}<br />
<br />
#ifndef SERIAL_NO_OVERLAPPED<br />
<br />
if (!m_hevtOverlapped && (lpOverlapped || (dwTimeout != INFINITE)))<br />
{<br />
m_lLastError = ERROR_INVALID_FUNCTION;<br />
<br />
_RPTF0(_CRT_WARN,"CSerial::Write - Overlapped I/O is disabled, specified parameters are illegal.\n");<br />
return m_lLastError;<br />
}<br />
<br />
OVERLAPPED ovInternal;<br />
if (!lpOverlapped && m_hevtOverlapped)<br />
{<br />
memset(&ovInternal,0,sizeof(ovInternal));<br />
ovInternal.hEvent = m_hevtOverlapped;<br />
<br />
lpOverlapped = &ovInternal;<br />
}<br />
<br />
_ASSERTE(!m_hevtOverlapped || HasOverlappedIoCompleted(lpOverlapped));<br />
<br />
char bla[255] = {0x0};<br />
strcpy(bla, (char*)pData);<br />
<br />
if( bla[iLen-1] == 0x03 )<br />
iLen++;<br />
<br />
if (!::WriteFile(m_hFile,pData,iLen,pdwWritten,lpOverlapped))<br />
{<br />
long lLastError = ::GetLastError();<br />
<br />
if (lLastError != ERROR_IO_PENDING)<br />
{<br />
m_lLastError = lLastError;<br />
<br />
_RPTF0(_CRT_WARN,"CSerial::Write - Unable to write the data\n");<br />
return m_lLastError;<br />
}<br />
<br />
if (lpOverlapped == &ovInternal)<br />
{<br />
switch (::WaitForSingleObject(lpOverlapped->hEvent,dwTimeout))<br />
{<br />
case WAIT_OBJECT_0:<br />
if (!::GetOverlappedResult(m_hFile,lpOverlapped,pdwWritten,FALSE))<br />
{<br />
m_lLastError = ::GetLastError();<br />
<br />
_RPTF0(_CRT_WARN,"CSerial::Write - Overlapped completed without result\n");<br />
return m_lLastError;<br />
}<br />
break;<br />
<br />
case WAIT_TIMEOUT:<br />
CancelCommIo();<br />
<br />
m_lLastError = ERROR_TIMEOUT;<br />
return m_lLastError;<br />
<br />
default:<br />
m_lLastError = ::GetLastError();<br />
<br />
_RPTF0(_CRT_WARN,"CSerial::Write - Unable to wait until data has been sent\n");<br />
return m_lLastError;<br />
}<br />
}<br />
}<br />
else<br />
{<br />
if (lpOverlapped)<br />
::SetEvent(lpOverlapped->hEvent);<br />
}<br />
<br />
#else<br />
<br />
if (!::WriteFile(m_hFile,pData,iLen,pdwWritten,0))<br />
{<br />
m_lLastError = ::GetLastError();<br />
<br />
_RPTF0(_CRT_WARN,"CSerial::Write - Unable to write the data\n");<br />
return m_lLastError;<br />
}<br />
<br />
#endif<br />
<br />
return m_lLastError;<br />
}<br />
This is how I initialize the com port:
<br />
lLastError = rfi->serial.Open(_T("COM1"),10000,10000,true);<br />
if (lLastError != ERROR_SUCCESS)<br />
rfi->ShowError(rfi->serial.GetLastError(), _T("Unable to open COM-port"));<br />
<br />
lLastError = rfi->serial.Setup(CSerial::EBaud9600,CSerial::EData8,CSerial::EParNone,CSerial::EStop1);<br />
if (lLastError != ERROR_SUCCESS)<br />
rfi->ShowError(rfi->serial.GetLastError(), _T("Unable to set COM-port setting"));<br />
<br />
lLastError = rfi->serial.SetupHandshaking(CSerial::EHandshakeOff);<br />
if (lLastError != ERROR_SUCCESS)<br />
rfi->ShowError(rfi->serial.GetLastError(), _T("Unable to set COM-port handshaking"));<br />
<br />
lLastError = rfi->serial.SetMask(CSerial::EEventBreak |<br />
CSerial::EEventCTS |<br />
CSerial::EEventDSR |<br />
CSerial::EEventError |<br />
CSerial::EEventRing |<br />
CSerial::EEventRLSD |<br />
CSerial::EEventRecv);<br />
if (lLastError != ERROR_SUCCESS)<br />
rfi->ShowError(rfi->serial.GetLastError(), _T("Unable to set COM-port event mask"));<br />
<br />
lLastError = rfi->serial.SetupReadTimeouts(CSerial::EReadTimeoutNonblocking);<br />
if (lLastError != ERROR_SUCCESS)<br />
rfi->ShowError(rfi->serial.GetLastError(), _T("Unable to set COM-port read timeout."));<br />
<br />
HANDLE hevtOverlapped = ::CreateEvent(0,TRUE,FALSE,0);;<br />
if (hevtOverlapped == 0)<br />
rfi->ShowError(rfi->serial.GetLastError(), _T("Unable to create manual-reset event for overlapped I/O."));<br />
<br />
OVERLAPPED ov = {0};<br />
ov.hEvent = hevtOverlapped;<br />
<br />
HANDLE hevtStop = ::CreateEvent(0,TRUE,FALSE,_T("Overlapped_Stop_Event"));<br />
if (hevtStop == 0)<br />
rfi->ShowError(rfi->serial.GetLastError(), _T("Unable to create manual-reset event for stop event."));<br />
I am searching for a solution for some days now, and it would be really really great to get some help, at least getting a starting point where to look at.
DKT
|