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.