none
serialport is not eventing fast enough..

    Question

  • hey guys.. i thought i posted a thread. but looks like either it was deleted or that it didnt get posted.
    in any case i am trying again.

    i m trying to catch some fast incoming packets via serialport. i am sedning some chars via serial port using atmega88 an embedded chip. i can see the data coming well via hyperterminal. no problem there. but when i try to catch the data via my serialport program it seems that its skipping a few chars. its not eventing in all of them accurately. any thoughts?

    I am using the following code:

     

    public: System::Void myPort_DataReceived(System::Object^ sender, System::IO::Ports::SerialDataReceivedEventArgs^ e) {

    unsigned char byte = myPort->ReadChar();

    if(byte == 0x01) //this is the start of a frame

    {

    //do something

    }

    else if (byte == 0x0A) //this is new line feed, means new line in a frame

    {

    //do something

    }
    else

    //do something else

    }

     

    anyidea why my code is not catching all the incoming?

    • Edited by luvocean1 Friday, July 25, 2008 12:39 PM code not showing properly.
    Friday, July 25, 2008 12:36 PM

Answers

  • Thats interesting , 
    did u try out to use the  ReadExisting() ,note the return value is string .

    RxString = serialPort1.ReadExisting();

    I am not sure if a even can be missed , but the problem can be many events .
    You should rather try to buffer and send data as string/array  instead of char by char .

    Vikas
    • Marked as answer by Yan-Fei Wei Sunday, August 03, 2008 2:44 PM
    Tuesday, July 29, 2008 4:26 PM

All replies

  • What is the bits per second ?
    Did u check the flow control in the hyperterminal and your project is same .?
    Vikas
    Friday, July 25, 2008 5:42 PM
  • i have played with dtr and rts and it makes no difference. my baud rate is 115200 and i get the same results with 230400kbps. it cant too fast come on :(
    Saturday, July 26, 2008 12:29 PM
  • I've been also working with the serial port lately and I decided to resort to the Win32 API and this code has worked fine for me. It is not nice, but it works; maybe someone may enhance it a little bit and post a better version.

    First, you derive a concrete class from SerialPortManager (it may be your own window or dialog using multiple inheritance perhaps):

    #ifndef SERIAL_PORT_MANAGER_H  
    #define SERIAL_PORT_MANAGER_H  
     
    class SerialPortManager  
    {  
    public:  
        virtual void onReceive(char c) = 0;  
    };
    #endif  
     

    Then you just create an instance of SerialPort (usually as a member to a window or dialog class):

    #ifndef SERIAL_PORT_H  
    #define SERIAL_PORT_H
    #include "sportmgr.h"  
    #include <windows.h>  
     
    class SerialPort  
    {  
        static DWORD WINAPI serialPortThread(LPVOID pParam);  
        OVERLAPPED CreateOverlappedStructure();  
        BOOL waitForData();  
        BOOL get(BYTE &byte);  
        HANDLE m_hThread;  
        DWORD m_dwThreadID;  
        BOOL m_bPortReady;  
        HANDLE m_hCom;  
        SerialPortManager *serialPortManager_;  
    public:  
        SerialPort(unsigned int portNumber = 0, SerialPortManager *serialPortManager = 0);  
        ~SerialPort();  
        void setSerialPortManager(SerialPortManager *serialPortManager);  
        bool open(unsigned int portNumber);  
        bool close();  
        // setSpeed  
        bool put(BYTE byte);  
        bool isOpen() const;  
    };
    #endif  
     
    #include "serial.h"  
    #include <strstream>  
     
    DWORD WINAPI SerialPort::serialPortThread(LPVOID pParam)  
    {  
        SerialPort *serialPort = static_cast<SerialPort *>(pParam);  
        BYTE byte;  
     
        while ("Thread is not terminated") {  
            serialPort->waitForData();  
            if (serialPort->get(byte))  
                serialPort->serialPortManager_->onReceive(byte);  
        }  
        ExitThread(0);  
        return 0;  
    }  
     
    SerialPort::SerialPort(unsigned int portNumber, SerialPortManager *serialPortManager)  
        : m_bPortReady(FALSE), serialPortManager_(serialPortManager)  
    {  
        if (portNumber != 0)  
            m_bPortReady = open(portNumber);  
    }  
     
    SerialPort::~SerialPort()  
    {  
        close();  
    }  
     
    bool SerialPort::isOpen() const 
    {  
        return m_bPortReady == TRUE;  
    }  
     
    bool SerialPort::put(BYTE byte)  
    {  
     
        OVERLAPPED osWrite = CreateOverlappedStructure();  
        DWORD dwBytesWritten;  
        BOOL fRes;  
     
        if (osWrite.hEvent == NULL)  
            return FALSE;  
        if (!WriteFile(m_hCom, &byte, 1, &dwBytesWritten, &osWrite)) {  
            if (GetLastError() != ERROR_IO_PENDING) {  
                fRes = FALSE;  
            } else {  
                if (!GetOverlappedResult(m_hCom, &osWrite, &dwBytesWritten, TRUE))  
                    fRes = FALSE;  
                else 
                    // Write operation completed successfully.  
                    fRes = TRUE;  
            }  
        } else 
            fRes = TRUE;  
        CloseHandle(osWrite.hEvent);  
        return fRes == TRUE;  
    }  
     
    BOOL SerialPort::get(BYTE &byte)  
    {  
        OVERLAPPED osRead = CreateOverlappedStructure();  
        DWORD dwBytesRead;  
        BOOL fRes = FALSE;  
     
        if (osRead.hEvent == NULL)  
            return FALSE;  
     
        if (!ReadFile(m_hCom, &byte, 1, &dwBytesRead, &osRead)) {  
            if (GetLastError() != ERROR_IO_PENDING) {  
                fRes = FALSE;  
            } else {  
                if (!GetOverlappedResult(m_hCom, &osRead, &dwBytesRead, TRUE))  
                    fRes = FALSE;  
                else 
                    // Read operation completed successfully.  
                    fRes = TRUE;  
            }  
        } else 
            fRes = TRUE;  
        CloseHandle(osRead.hEvent);  
        return fRes;  
    }  
     
    BOOL SerialPort::waitForData()  
    {  
        OVERLAPPED osWait = CreateOverlappedStructure();  
        DWORD dwEvtMask = EV_RXCHAR;  
        DWORD dwBytes;  
        BOOL fRes;  
     
        if (osWait.hEvent == NULL)  
            return FALSE;  
        if (!WaitCommEvent(m_hCom, &dwEvtMask, &osWait)) {  
            if (GetLastError() != ERROR_IO_PENDING) {  
                fRes = FALSE;  
            } else {  
                if (!GetOverlappedResult(m_hCom, &osWait, &dwBytes, TRUE))  
                    fRes = FALSE;  
                else 
                    // Wait operation completed successfully.  
                    fRes = TRUE;  
            }  
        } else 
            fRes = TRUE;  
        CloseHandle(osWait.hEvent);  
        return fRes;  
    }  
     
    OVERLAPPED SerialPort::CreateOverlappedStructure()  
    {  
        OVERLAPPED o;  
     
        o.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);  
        o.Internal = 0;  
        o.InternalHigh = 0;  
        o.Offset = 0;  
        o.OffsetHigh = 0;  
        return o;  
    }  
     
    bool SerialPort::open(unsigned int portNumber)  
    {  
        char *deviceName[4] = { "Com1""Com2""Com3""Com4" };  
        DCB dcb;  
        m_hCom = CreateFile(deviceName[portNumber - 1],  
            GENERIC_READ | GENERIC_WRITE,  
            FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,  
            OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL);  
        m_bPortReady = SetupComm(m_hCom, 128, 128);  
        if (m_bPortReady == 0)  
            return false;  
        GetCommState(m_hCom, &dcb);  
        dcb.BaudRate = CBR_115200;  
        dcb.ByteSize = 8;  
        dcb.Parity = NOPARITY;  
        dcb.StopBits = ONESTOPBIT;  
        dcb.fAbortOnError = TRUE;  
        m_bPortReady = SetCommState(m_hCom, &dcb);  
        m_hThread = CreateThread(NULL, 0, SerialPort::serialPortThread,  
            static_cast<LPVOID>(this), 0, &m_dwThreadID);  
        return true;  
    }  
     
    bool SerialPort::close()  
    {  
        TerminateThread(m_hThread, 0);  
        if (m_hCom != INVALID_HANDLE_VALUE)  
            CloseHandle(m_hCom);  
        return true;  
    }  
     
    void SerialPort::setSerialPortManager(SerialPortManager *serialPortManager)  
    {  
        serialPortManager_ = serialPortManager;  
    }  
     
    Saturday, July 26, 2008 3:35 PM
  • Thats interesting , 
    did u try out to use the  ReadExisting() ,note the return value is string .

    RxString = serialPort1.ReadExisting();

    I am not sure if a even can be missed , but the problem can be many events .
    You should rather try to buffer and send data as string/array  instead of char by char .

    Vikas
    • Marked as answer by Yan-Fei Wei Sunday, August 03, 2008 2:44 PM
    Tuesday, July 29, 2008 4:26 PM
  • hhm.. i tried all that. i think it became much better with Read function. this function actually returns how many bytes were read. when i get a chance i may post the code but i still dont think it was 100%. I need to test more.

    in the mean time i am thinking of changing to USB option. I am going to be using Atmels UC3A0512 embedded uC with USB on it. Looks like now i would have to write a usb driver? is this true? how is this going to be integrated with visual studio? or when I write the driver I just install the dirver and it creates a virtual commport?? is that how it works?

    any advice on how to get started on USB and visual studio C++??
    Tuesday, August 05, 2008 9:22 AM
  •  
    If  you just want to read and write data to the usb ,
    U need to write a driver          http://www.codeproject.com/KB/cs/Intel_OpenCV.aspx
    U can do it with libusb-win32  http://libusb-win32.sourceforge.net/

    Good Article to read first
    http://msmvps.com/blogs/vandooren/archive/2006/06/15/Is-it-possible-to-create-_2800_USB_2900_-device-drivers-with-Visual-C_2B002B003F00_.aspx



    luvocean1 - Posted on Tuesday, August 05, 2008 4:22:41 AM
    hhm.. i tried all that. i think it became much better with Read function. this function actually returns how many bytes were read. when i get a chance i may post the code but i still dont think it was 100%. I need to test more.

    Do let me know the outcome of your results once you have done your testing
    Vikas
    • Edited by vikas amin Monday, August 11, 2008 7:41 PM just font change
    Monday, August 11, 2008 7:40 PM