I'm trying to send some hex string to a serial port, and directly read its answer in c++. If there is no answer it should timeout after a given period of time.
To be clear: I'm searching for the most simple way to achieve this.
Sorry if my question is dumb, but im new to this topic, thanks in advance!
EDIT: Sorry that I forgot to mention, it should run on Linux.
this should be similar to your declaration:
Setup(CSerial::EBaud9600,CSerial::EData8,CSerial::EParNone,CSerial::EStop1);
Setup(CSerial::EBaudrate(9600),
CSerial::EDataBits(8),
CSerial::EParity(NOPARITY),
CSerial::EStopBits(ONESTOPBIT));
Reading data:
// Read data, until there is nothing left
DWORD dwBytesRead = 0;
BYTE abBuffer[100];
do
{
// Read data from the COM-port
serial.Read(abBuffer,sizeof(abBuffer),&dwBytesRead);
if (dwBytesRead > 0)
{
// TODO: Process the data
}
}
while (dwBytesRead == sizeof(abBuffer));
More details can be found here on code project: http://www.codeproject.com/Articles/992/Serial-library-for-C
Please note: I am used to programming serial ports in c#, and so (to the best of my knowledge) believe this would work for you. (I would also like to point outall serial port communication is send actually through as hex, but may be read via the buffer as a decimal value ( please refer to http://www.asciitable.com/ for converstion, or use something similar to UTF8 encoding)
EDIT - As per comment;
Please refer to : http://msdn.microsoft.com/en-gb/library/windows/hardware/hh439614(v=vs.85).aspx for details on serial port read/write timeouts
Write timeout will be similar to;
[BrowsableAttribute(true)]
public:
property int WriteTimeout {
int get ();
void set (int value);
}
Which allows you to get or set the timeout attribute
Full Program
public:
static void Main()
{
String^ name;
String^ message;
StringComparer^ stringComparer = StringComparer::OrdinalIgnoreCase;
Thread^ readThread = gcnew Thread(gcnew ThreadStart(PortChat::Read));
// Create a new SerialPort object with default settings.
_serialPort = gcnew SerialPort();
// Allow the user to set the appropriate properties.
_serialPort->PortName = SetPortName(_serialPort->PortName);
_serialPort->BaudRate = SetPortBaudRate(_serialPort->BaudRate);
_serialPort->Parity = SetPortParity(_serialPort->Parity);
_serialPort->DataBits = SetPortDataBits(_serialPort->DataBits);
_serialPort->StopBits = SetPortStopBits(_serialPort->StopBits);
_serialPort->Handshake = SetPortHandshake(_serialPort->Handshake);
// Set the read/write timeouts
_serialPort->ReadTimeout = 500;
_serialPort->WriteTimeout = 500;
_serialPort->Open();
_continue = true;
readThread->Start();
Console::Write("Name: ");
name = Console::ReadLine();
Console::WriteLine("Type QUIT to exit");
while (_continue)
{
message = Console::ReadLine();
if (stringComparer->Equals("quit", message))
{
_continue = false;
}
else
{
_serialPort->WriteLine(
String::Format("<{0}>: {1}", name, message) );
}
}
readThread->Join();
_serialPort->Close();
}
static void Read()
{
while (_continue)
{
try
{
String^ message = _serialPort->ReadLine();
Console::WriteLine(message);
}
catch (TimeoutException ^) { }
}
}
EDIT 2
Please refer to Linux Serial Port: Blocking Read with Timeout where this has been declared in the question and some of the answers may prove useful to you as well! :)
I recently came for the same issue and I found a good solution using select() Read the documentation here: manpages.courirer-mta.org/htmlman2/select2.html
In your case you need to setup the timeout, which is the 5th argument of select:
struct timeval timeout;
timeout.tv_sec = 0 ; // seconds
timeout.tv_usec = 1000 ; // microseconds
Hope this helps.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.