Hi Stefan,
happy new 2016. I was away for a while because of my work.
I'm studying your great QT source code and iI'm tryng to adapt some routines to my (Arduino) needs;
I submit to your attention two simple routines (for reading serial data lines in a not-blocking manner) I've added to my personal version of scriptSerialPort.h:
// PASERRA NEW SERIAL ROUTINES
///This function checks if a data line is ready to be read
Q_INVOKABLE bool canReadLine(){return m_serialPort.canReadLine();}
///Returns serial bytes until EOL ('\n') char (not included).
// the EOL recognition char is '\n' but this version accepts also "\r\n"
Q_INVOKABLE QString readLine()
{
QByteArray data = m_serialPort.readLine();
int size = data.size();
int eol2 = (int)data.at(size-2);
data.remove(size-1,1); // remove last char: EOL ('\n' )
if (eol2 == 13) data.remove(size-2,1); //remove '\r' if present (see Arduino's Println())
QString str(data); // send data without EOL char(s)
return str;
}
this a short script to show how to use them:
varstr="";functionstopScript(){serialPort.close();scriptThread.appendTextToConsole("script has been stopped");}scriptThread.appendTextToConsole('script has started');// serialPort readData routinefunctionserialReceive(){if(serialPort.canReadLine()){str=serialPort.readLine();varstrArray=str.split(",");scriptThread.appendTextToConsole(strArray[1]);// if str is "1,2,3" it prints '2'return;}scriptThread.appendTextToConsole("not receive Line");}// serialPortvarportName="\\\\.\\COM3";varserialPort=scriptThread.createSerialPort();serialPort.readyReadSignal.connect(serialReceive);serialPort.setPortName(portName);serialPort.setDTR(false);if(serialPort.open()){serialPort.setBaudRate(115200);//115200serialPort.setDataBits(8);serialPort.setParity("None");serialPort.setStopBits("1");serialPort.setFlowControl("None");serialPort.setDTR(true);serialPort.setRTS(true);}else{scriptThread.messageBox("Critical",'Error','Unable to open serial port');scriptThread.stopScript();}
If you want you can modify/test/add the above code to the next official version of ScriptCommunivcator.
Greetings,
Pier Andrea.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
///This function reads a line (a line ends with a '\n') of ASCII characters.
///If removeNewLine is true then the '\n' will not returned (is removed from the received line)
///If removeCarriageReturn is true then a '\r' in front of '\n' will also not returned.
///Note: If no new data line is ready for reading this functions returns an empty string.
Q_INVOKABLE QString readLine(bool removeNewLine=true, bool removeCarriageReturn=true)
{
QString result;
if(canReadLine())
{
result = m_serialPort.readLine();
if(removeNewLine && removeCarriageReturn)
{
//Remove '\r\n'
result.replace("\r\n", "");
}
else if(removeNewLine)
{
//Remove '\n'
result.replace("\n", "");
}
}
return result;
}
Greetings,
Stefan
Last edit: Stefan Zieker 2016-01-02
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Hi Stefan,
your code is much more elegant than mine! I've started to program in QT just Yesterday and I have to learn much more things about this specific C++ implementation. I've discovered another thing about the readLine() routine. serialReceive() is called every time you have a serial event while readLine() returns ONLY a line of data. In case you have more lines of data waiting to be read (immagine that the MCU sends a lot of data at very high speed), they stay in the buffer until NEXT data is received (more lines to read). In this way you coud have an accumulation of incoming data in the input buffer. The ideal situation could be to check if there are more lines to read inside the serialReceive() routine before leaving it (i.e. a while cicle that checks if the readLine() return is an empty string.
Cheers,
Pier Andrea.
Last edit: Anonymous 2016-01-02
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
I do not know if I did understand you correctly. But I would write your QtScript function like this:
// serialPort readData routinefunctionserialReceive(){while(serialPort.canReadLine()){str=serialPort.readLine();varstrArray=str.split(",");scriptThread.appendTextToConsole(strArray[1]);// if str is "1,2,3" it prints '2'}}
Thank you Stefan,
both the routines are useful! The fisrt routine is the classical approach (this in particular I had in my mind). The second routine is great: you can increae the parsing speed and immediately plot ASCII data!
You are great!
Pier Andrea.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
I've found a strange behaviour in your last two routines (when only \n is present in the line they are unable to remove it (no problem with \r\n sequence); the following routines work very well altough no so elegant:
View and moderate all "User Contributions" comments posted by this user
Mark all as spam, and block user from posting to "Discussion"
Hi Stefan,
happy new 2016. I was away for a while because of my work.
I'm studying your great QT source code and iI'm tryng to adapt some routines to my (Arduino) needs;
I submit to your attention two simple routines (for reading serial data lines in a not-blocking manner) I've added to my personal version of scriptSerialPort.h:
this a short script to show how to use them:
If you want you can modify/test/add the above code to the next official version of ScriptCommunivcator.
Greetings,
Pier Andrea.
Hi Pier ,
nice to hear you again :-) and thx for your new idea. I will add this in the next version of ScriptCommunicator.
Greetings,
Stefan
Last edit: Stefan Zieker 2016-01-02
Hi Pier,
I changed your function to:
Greetings,
Stefan
Last edit: Stefan Zieker 2016-01-02
Hi Pier,
I have uploaded a new test version of ScriptCommunicator (Files/Test).
Best regards,
Stefan
View and moderate all "User Contributions" comments posted by this user
Mark all as spam, and block user from posting to "Discussion"
Hi Stefan,
your code is much more elegant than mine! I've started to program in QT just Yesterday and I have to learn much more things about this specific C++ implementation. I've discovered another thing about the readLine() routine. serialReceive() is called every time you have a serial event while readLine() returns ONLY a line of data. In case you have more lines of data waiting to be read (immagine that the MCU sends a lot of data at very high speed), they stay in the buffer until NEXT data is received (more lines to read). In this way you coud have an accumulation of incoming data in the input buffer. The ideal situation could be to check if there are more lines to read inside the serialReceive() routine before leaving it (i.e. a while cicle that checks if the readLine() return is an empty string.
Cheers,
Pier Andrea.
Last edit: Anonymous 2016-01-02
Hi Pier,
I do not know if I did understand you correctly. But I would write your QtScript function like this:
Or do you mean this:
Best regards,
Stefan
Last edit: Stefan Zieker 2016-01-02
View and moderate all "User Contributions" comments posted by this user
Mark all as spam, and block user from posting to "Discussion"
Thank you Stefan,
both the routines are useful! The fisrt routine is the classical approach (this in particular I had in my mind). The second routine is great: you can increae the parsing speed and immediately plot ASCII data!
You are great!
Pier Andrea.
View and moderate all "User Contributions" comments posted by this user
Mark all as spam, and block user from posting to "Discussion"
I've found a strange behaviour in your last two routines (when only \n is present in the line they are unable to remove it (no problem with \r\n sequence); the following routines work very well altough no so elegant:
ReadLines seems to be the better routine for high performance data exchange:
Cheers,
Pier Andrea.
Last edit: Anonymous 2016-01-02
Hi Pier,
my solution has not the best performance. It should be implemented like this:
Cheers,
Stefan Zieker