how to use serial port in UDK using windows DLL and DLLBind directive?

Posted by Shayan Abbas on Game Development See other posts from Game Development or by Shayan Abbas
Published on 2012-12-13T17:53:00Z Indexed on 2012/12/13 23:21 UTC
Read the original article Hit count: 349

Filed under:
|

I want to use serial port in UDK, For that purpose i use a windows DLL and DLLBind directive. I have a thread in windows DLL for serial port data recieve event. My problem is: this thread doesn't work properly. Please Help me.

below is my code

SerialPortDLL Code:

// SerialPortDLL.cpp : Defines the exported functions for the DLL application.
//

#include "stdafx.h"
#include "Cport.h"

extern "C"
{
    // This is an example of an exported variable
    //SERIALPORTDLL_API int nSerialPortDLL=0;

    // This is an example of an exported function.
    //SERIALPORTDLL_API int fnSerialPortDLL(void)
    //{
    //  return 42;
    //}

    CPort *sp;

    __declspec(dllexport) void Open(wchar_t* portName)
    {
        sp = new CPort(portName);
        //MessageBox(0,L"ha ha!!!",L"ha ha",0);
        //MessageBox(0,portName,L"ha ha",0);
    }

    __declspec(dllexport) void Close()
    {
        sp->Close();
        MessageBox(0,L"ha ha!!!",L"ha ha",0);
    }

    __declspec(dllexport) wchar_t *GetData()
    {
        return sp->GetData();
    }

    __declspec(dllexport) unsigned int GetDSR()
    {
        return sp->getDSR();
    }

    __declspec(dllexport) unsigned int GetCTS()
    {
        return sp->getCTS();
    }

    __declspec(dllexport) unsigned int GetRing()
    {
        return sp->getRing();
    }
}

CPort class code:

#include "stdafx.h"
#include "CPort.h"
#include "Serial.h"

CSerial serial;
HANDLE HandleOfThread;
LONG lLastError = ERROR_SUCCESS;
bool fContinue = true;
HANDLE hevtOverlapped;
HANDLE hevtStop;
OVERLAPPED ov = {0};
//char szBuffer[101] = "";
wchar_t *szBuffer = L"";
wchar_t *data = L"";

DWORD WINAPI ThreadHandler( LPVOID lpParam ) 
{
    // Keep reading data, until an EOF (CTRL-Z) has been received
    do
    {
        MessageBox(0,L"ga ga!!!",L"ga ga",0);

        //Sleep(10);
        // Wait for an event
        lLastError = serial.WaitEvent(&ov);
        if (lLastError != ERROR_SUCCESS)
        {
            //LOG( "    Unable to wait for a COM-port event" );
        }

        // Setup array of handles in which we are interested
        HANDLE ahWait[2];
        ahWait[0] = hevtOverlapped;
        ahWait[1] = hevtStop;

        // Wait until something happens
        switch (::WaitForMultipleObjects(sizeof(ahWait)/sizeof(*ahWait),ahWait,FALSE,INFINITE))
        {
        case WAIT_OBJECT_0:
            {
                // Save event
                const CSerial::EEvent eEvent = serial.GetEventType();

                // Handle break event
                if (eEvent & CSerial::EEventBreak)
                {
                    //LOG( "    ### BREAK received ###" );
                }

                // Handle CTS event
                if (eEvent & CSerial::EEventCTS)
                {
                    //LOG( "    ### Clear to send %s ###", serial.GetCTS() ? "on":"off" );
                }

                // Handle DSR event
                if (eEvent & CSerial::EEventDSR)
                {
                    //LOG( "    ### Data set ready %s ###", serial.GetDSR() ? "on":"off" );
                }

                // Handle error event
                if (eEvent & CSerial::EEventError)
                {
                    switch (serial.GetError())
                    {
                        case CSerial::EErrorBreak:      /*LOG( "    Break condition" );*/           break;
                        case CSerial::EErrorFrame:      /*LOG( "    Framing error" );*/             break;
                        case CSerial::EErrorIOE:        /*LOG( "    IO device error" );*/           break;
                        case CSerial::EErrorMode:       /*LOG( "    Unsupported mode" );*/          break;
                        case CSerial::EErrorOverrun:    /*LOG( "    Buffer overrun" );*/            break;
                        case CSerial::EErrorRxOver:     /*LOG( "    Input buffer overflow" );*/     break;
                        case CSerial::EErrorParity:     /*LOG( "    Input parity error" );*/        break;
                        case CSerial::EErrorTxFull:     /*LOG( "    Output buffer full" );*/        break;
                        default:                        /*LOG( "    Unknown" );*/                   break;
                    }
                }

                // Handle ring event
                if (eEvent & CSerial::EEventRing)
                {
                    //LOG( "    ### RING ###" );
                }

                // Handle RLSD/CD event
                if (eEvent & CSerial::EEventRLSD)
                {
                    //LOG( "    ### RLSD/CD %s ###", serial.GetRLSD() ? "on" : "off" );
                }

                // Handle data receive event
                if (eEvent & CSerial::EEventRecv)
                {
                    // Read data, until there is nothing left
                    DWORD dwBytesRead = 0;
                    do
                    {
                        // Read data from the COM-port
                        lLastError = serial.Read(szBuffer,33,&dwBytesRead);
                        if (lLastError != ERROR_SUCCESS)
                        {
                            //LOG( "Unable to read from COM-port" );
                        }

                        if( dwBytesRead == 33 && szBuffer[0]=='$' )
                        {
                            // Finalize the data, so it is a valid string
                            szBuffer[dwBytesRead] = '\0';

                            ////LOG( "\n%s\n", szBuffer );

                            data = szBuffer;
                        }
                    }
                    while (dwBytesRead > 0);
                }
            }
            break;

        case WAIT_OBJECT_0+1:
            {
                // Set the continue bit to false, so we'll exit
                fContinue = false;
            }
            break;

        default:
            {
                // Something went wrong
                //LOG( "Error while calling WaitForMultipleObjects" );
            }
            break;
        }
    }
    while (fContinue);

    MessageBox(0,L"kka kk!!!",L"kka ga",0);
    return 0; 
}

CPort::CPort(wchar_t *portName)
{
    // Attempt to open the serial port (COM2)
    //lLastError = serial.Open(_T(portName),0,0,true);
    lLastError = serial.Open(portName,0,0,true);

    if (lLastError != ERROR_SUCCESS)
    {
        //LOG( "Unable to open COM-port" );
    }

    // Setup the serial port (115200,8N1, which is the default setting)
    lLastError = serial.Setup(CSerial::EBaud115200,CSerial::EData8,CSerial::EParNone,CSerial::EStop1);
    if (lLastError != ERROR_SUCCESS)
    {
        //LOG( "Unable to set COM-port setting" );
    }

    // Register only for the receive event
    lLastError = serial.SetMask(CSerial::EEventBreak |
                                CSerial::EEventCTS   |
                                CSerial::EEventDSR   |
                                CSerial::EEventError |
                                CSerial::EEventRing  |
                                CSerial::EEventRLSD  |
                                CSerial::EEventRecv);
    if (lLastError != ERROR_SUCCESS)
    {
        //LOG( "Unable to set COM-port event mask" );
    }

    // Use 'non-blocking' reads, because we don't know how many bytes
    // will be received. This is normally the most convenient mode
    // (and also the default mode for reading data).
    lLastError = serial.SetupReadTimeouts(CSerial::EReadTimeoutNonblocking);
    if (lLastError != ERROR_SUCCESS)
    {
        //LOG( "Unable to set COM-port read timeout" );
    }

    // Create a handle for the overlapped operations
    hevtOverlapped = ::CreateEvent(0,TRUE,FALSE,0);;
    if (hevtOverlapped == 0)
    {
        //LOG( "Unable to create manual-reset event for overlapped I/O" );
    }

    // Setup the overlapped structure
    ov.hEvent = hevtOverlapped;

    // Open the "STOP" handle
    hevtStop = ::CreateEvent(0,TRUE,FALSE,_T("Overlapped_Stop_Event"));
    if (hevtStop == 0)
    {
        //LOG( "Unable to create manual-reset event for stop event" );  
    }

    HandleOfThread = CreateThread( NULL, 0, ThreadHandler, 0, 0, NULL);
}

CPort::~CPort()
{
   //fContinue = false;
   //CloseHandle( HandleOfThread );
   //serial.Close();
}

void CPort::Close()
{
   fContinue = false;
   CloseHandle( HandleOfThread );
   serial.Close();
}

wchar_t *CPort::GetData()
{
    return data;
}

bool CPort::getCTS()
{
    return serial.GetCTS();
}

bool CPort::getDSR()
{
    return serial.GetDSR();
}

bool CPort::getRing()
{
    return serial.GetRing();
}

Unreal Script Code:

class MyPlayerController extends GamePlayerController
    DLLBind(SerialPortDLL);

dllimport final function Open(string portName);
dllimport final function Close();
dllimport final function string GetData();

© Game Development or respective owner

Related posts about udk

Related posts about unreal