I am trying to read from RS-232 with serial connections by using serial libraries for C++ and some samples found at: http://www.codeproject.com/Articles/992/Serial-library-for-C
Is there any signal detection method or an event which lets me know. I connected the Rx and Neutral ONLY to the board using a serial to USB connector, and using serial libraries in Visual studio 2013 and writing the code in C++.
I want to write the ASCII data transmitted from my board, when it is restarted manually, to a text file, so I can parsing the data from a text file will be easy for me.
My board transmits sends data only when it is restarted. I am new to serial connections, and I wasn't able to figure out how to let my program understand to read the data when the board is reset.
I am using the listener program:
#define STRICT
#include <tchar.h>
#include <windows.h>
#include <stdio.h>
#include <string.h>
#include "Serial.h"
//C++ headers
#include <iostream>
#include <fstream>
#include <string>
enum { EOF_Char = 27 };
int ShowError (LONG lError, LPCTSTR lptszMessage)
{
    // Generate a message text
    TCHAR tszMessage[256];
    wsprintf(tszMessage,_T("%s\n(error code %d)"), lptszMessage, lError);
    // Display message-box and return with an error-code
    ::MessageBox(0,tszMessage,_T("Listener"), MB_ICONSTOP|MB_OK);
    return 1;
}
//int __cdecl _tmain (int /*argc*/, char** /*argv*/)
int WINAPI _tWinMain(HINSTANCE /*hInst*/, HINSTANCE /*hInstPrev*/, LPTSTR /*lptszCmdLine*/, int /*nCmdShow*/)
{
    CSerial serial;
    LONG    lLastError = ERROR_SUCCESS;
    const char* Port_name = "COM3";
    // Attempt to open the serial port (COM1)
    lLastError = serial.Open(_T(Port_name),0,0,false);
    if (lLastError != ERROR_SUCCESS)
        return ::ShowError(serial.GetLastError(), _T("Unable to open COM-port"));
    // Setup the serial port (9600,8N1, which is the default setting)
    lLastError = serial.Setup(CSerial::EBaud9600,CSerial::EData8,CSerial::EParNone,CSerial::EStop1);
    if (lLastError != ERROR_SUCCESS)
        return ::ShowError(serial.GetLastError(), _T("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)
        return ::ShowError(serial.GetLastError(), _T("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)
        return ::ShowError(serial.GetLastError(), _T("Unable to set COM-port read timeout."));
    // Keep reading data, until an EOF (CTRL-Z) has been received
    bool fContinue = true;
    do
    {
        // Wait for an event
        lLastError = serial.WaitEvent();
        if (lLastError != ERROR_SUCCESS)
            return ::ShowError(serial.GetLastError(), _T("Unable to wait for a COM-port event."));
        else
            return ::ShowError(serial.GetLastError(), _T("Waiting for a COM-port event."));
        // Save event
        const CSerial::EEvent eEvent = serial.GetEventType();
        // Handle break event
        if (eEvent & CSerial::EEventBreak)
        {
            printf("\n### BREAK received ###\n");
        }
        // Handle CTS event
        if (eEvent & CSerial::EEventCTS)
        {
            printf("\n### Clear to send %s ###\n", serial.GetCTS()?"on":"off");
        }
        // Handle DSR event
        if (eEvent & CSerial::EEventDSR)
        {
            printf("\n### Data set ready %s ###\n", serial.GetDSR()?"on":"off");
        }
        // Handle error event
        if (eEvent & CSerial::EEventError)
        {
            printf("\n### ERROR: ");
            switch (serial.GetError())
            {
            case CSerial::EErrorBreak:      printf("Break condition");          break;
            case CSerial::EErrorFrame:      printf("Framing error");            break;
            case CSerial::EErrorIOE:        printf("IO device error");          break;
            case CSerial::EErrorMode:       printf("Unsupported mode");         break;
            case CSerial::EErrorOverrun:    printf("Buffer overrun");           break;
            case CSerial::EErrorRxOver:     printf("Input buffer overflow");    break;
            case CSerial::EErrorParity:     printf("Input parity error");       break;
            case CSerial::EErrorTxFull:     printf("Output buffer full");       break;
            default:                        printf("Unknown");                  break;
            }
            printf(" ###\n");
        }
        // Handle ring event
        if (eEvent & CSerial::EEventRing)
        {
            printf("\n### RING ###\n");
        }
        // Handle RLSD/CD event
        if (eEvent & CSerial::EEventRLSD)
        {
            printf("\n### RLSD/CD %s ###\n", serial.GetRLSD()?"on":"off");
        }
        // Handle data receive event
        if (eEvent & CSerial::EEventRecv)
        {
            // Read data, until there is nothing left
            DWORD dwBytesRead = 0;
            char szBuffer[101];
            do
            {
                // Read data from the COM-port
                lLastError = serial.Read(szBuffer,sizeof(szBuffer)-1,&dwBytesRead);
                if (lLastError != ERROR_SUCCESS)
                    return ::ShowError(serial.GetLastError(), _T("Unable to read from COM-port."));
                if (dwBytesRead > 0)
                {
                    // Finalize the data, so it is a valid string
                    szBuffer[dwBytesRead] = '\0';
                    //writing data to text file
                    std::ofstream o("save.txt");
                    o << "Data: " << szBuffer << std::endl << "BytesRead: " <<dwBytesRead <<std::endl;
                    // Display the data
                    printf("%s", szBuffer);
                    // Check if EOF (CTRL+'[') has been specified
                    if (strchr(szBuffer,EOF_Char))
                        fContinue = false;
                }
            }
            while (dwBytesRead == sizeof(szBuffer)-1);
        }
    }
    while (fContinue);
    // Close the port again
    serial.Close();
    return 0; 
}
I did setup some break points at my while statements and was trying to restart the board. Then I get data written into my text file like this.
Trail 1:
Data: "H¢˜A,B™žX
BytesRead: 100
Trail 2:
Data: x]Ãßÿ$¢œŒ2Y¶SIeó1ñ\@ó8¬!)þ
BytesRead: 30
I know this data is not correct, I should get ASCII data. Are there any libraries which support a solution for my problem?
I need to read data after the UART is restarted and once it stops receiving data, it should write all the data to a text file.
Please help me with this, thank you very much.
                        
Setting up the wrong Baudrate in the setup function is giving wrong output.
and also
instead of this code below (which will overwrite the text file everytime and no data is seen)
will append the data to the text file, which will give the complete data which is transmitted by RS232 can be seen in the text file.