mirror of
https://github.com/Serial-Studio/Serial-Studio.git
synced 2025-01-31 17:42:55 +08:00
Make console output more efficient, work on possible causes for issue #3 & fix maximized behavior
This commit is contained in:
parent
764adee850
commit
61137b25cb
@ -41,7 +41,7 @@ Window {
|
|||||||
maximumWidth: column.implicitWidth + 4 * app.spacing
|
maximumWidth: column.implicitWidth + 4 * app.spacing
|
||||||
minimumHeight: column.implicitHeight + 4 * app.spacing
|
minimumHeight: column.implicitHeight + 4 * app.spacing
|
||||||
maximumHeight: column.implicitHeight + 4 * app.spacing
|
maximumHeight: column.implicitHeight + 4 * app.spacing
|
||||||
flags: Qt.Dialog | Qt.WindowStaysOnTopHint | Qt.WindowCloseButtonHint | Qt.WindowTitleHint
|
flags: Qt.Dialog | Qt.WindowCloseButtonHint | Qt.WindowTitleHint
|
||||||
|
|
||||||
//
|
//
|
||||||
// Use page item to set application palette
|
// Use page item to set application palette
|
||||||
|
@ -36,14 +36,17 @@ Control {
|
|||||||
// Console text color
|
// Console text color
|
||||||
//
|
//
|
||||||
property alias text: _console.text
|
property alias text: _console.text
|
||||||
property alias autoscroll: _autoscr.checked
|
|
||||||
readonly property color consoleColor: Qt.rgba(142/255, 205/255, 157/255, 1)
|
readonly property color consoleColor: Qt.rgba(142/255, 205/255, 157/255, 1)
|
||||||
|
|
||||||
//
|
//
|
||||||
// Set the CppSerialManager's text document pointer so that the console
|
// Connections with serial manager
|
||||||
// ouput is handled automatically by the CppSerialManager
|
|
||||||
//
|
//
|
||||||
Component.onCompleted: CppSerialManager.setTextDocument(_console.textDocument)
|
Connections {
|
||||||
|
target: CppSerialManager
|
||||||
|
function onRx(rxData) {
|
||||||
|
_console.text += rxData
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// Controls
|
// Controls
|
||||||
@ -79,9 +82,10 @@ Control {
|
|||||||
font.family: app.monoFont
|
font.family: app.monoFont
|
||||||
width: _scrollView.contentWidth
|
width: _scrollView.contentWidth
|
||||||
placeholderText: qsTr("No data received so far...") + CppTranslator.dummy
|
placeholderText: qsTr("No data received so far...") + CppTranslator.dummy
|
||||||
|
Component.onCompleted: CppSerialManager.configureTextDocument(textDocument)
|
||||||
|
|
||||||
onTextChanged: {
|
onTextChanged: {
|
||||||
if (root.autoscroll && _scrollView.contentHeight > _scrollView.height)
|
if (_scrollView.contentHeight > _scrollView.height)
|
||||||
_console.cursorPosition = _console.length - 1
|
_console.cursorPosition = _console.length - 1
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -94,12 +98,6 @@ Control {
|
|||||||
RowLayout {
|
RowLayout {
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
|
|
||||||
CheckBox {
|
|
||||||
id: _autoscr
|
|
||||||
checked: true
|
|
||||||
text: qsTr("Autoscroll") + CppTranslator.dummy
|
|
||||||
}
|
|
||||||
|
|
||||||
TextField {
|
TextField {
|
||||||
id: _tf
|
id: _tf
|
||||||
height: 24
|
height: 24
|
||||||
@ -112,6 +110,11 @@ Control {
|
|||||||
placeholderText: qsTr("Send data to device") + "..." + CppTranslator.dummy
|
placeholderText: qsTr("Send data to device") + "..." + CppTranslator.dummy
|
||||||
Keys.onReturnPressed: {
|
Keys.onReturnPressed: {
|
||||||
CppSerialManager.sendData(_tf.text)
|
CppSerialManager.sendData(_tf.text)
|
||||||
|
|
||||||
|
_console.text += "\n\n"
|
||||||
|
_console.text += _tf.text
|
||||||
|
_console.text += "\n\n"
|
||||||
|
|
||||||
_tf.clear()
|
_tf.clear()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -57,6 +57,31 @@ ApplicationWindow {
|
|||||||
property int appLaunchStatus: 0
|
property int appLaunchStatus: 0
|
||||||
property bool automaticUpdates: false
|
property bool automaticUpdates: false
|
||||||
|
|
||||||
|
//
|
||||||
|
// Hacks to fix window maximized behavior
|
||||||
|
//
|
||||||
|
property bool firstChange: true
|
||||||
|
property bool windowMaximized: false
|
||||||
|
onVisibilityChanged: {
|
||||||
|
if (visibility == Window.Maximized) {
|
||||||
|
if (!windowMaximized)
|
||||||
|
firstChange = false
|
||||||
|
|
||||||
|
windowMaximized = true
|
||||||
|
}
|
||||||
|
|
||||||
|
else if (visibility !== Window.Hidden) {
|
||||||
|
if (windowMaximized && firstChange) {
|
||||||
|
app.x = 100
|
||||||
|
app.y = 100
|
||||||
|
app.width = app.minimumWidth
|
||||||
|
app.height = app.minimumHeight
|
||||||
|
}
|
||||||
|
|
||||||
|
windowMaximized = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// Window geometry
|
// Window geometry
|
||||||
//
|
//
|
||||||
@ -129,8 +154,11 @@ ApplicationWindow {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Show app window
|
// Show app window
|
||||||
app.visible = true
|
|
||||||
app.showWelcomeGuide()
|
app.showWelcomeGuide()
|
||||||
|
if (app.windowMaximized)
|
||||||
|
app.showMaximized()
|
||||||
|
else
|
||||||
|
app.showNormal()
|
||||||
|
|
||||||
// Increment app launch count until 3:
|
// Increment app launch count until 3:
|
||||||
// Value & meaning:
|
// Value & meaning:
|
||||||
@ -191,6 +219,7 @@ ApplicationWindow {
|
|||||||
property alias appH: app.height
|
property alias appH: app.height
|
||||||
property alias appStatus: app.appLaunchStatus
|
property alias appStatus: app.appLaunchStatus
|
||||||
property alias autoUpdater: app.automaticUpdates
|
property alias autoUpdater: app.automaticUpdates
|
||||||
|
property alias appMaximized: app.windowMaximized
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
|
@ -439,42 +439,30 @@
|
|||||||
<source>Received: %1 %2</source>
|
<source>Received: %1 %2</source>
|
||||||
<translation></translation>
|
<translation></translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
|
||||||
<source>Even Parity</source>
|
|
||||||
<translation></translation>
|
|
||||||
</message>
|
|
||||||
<message>
|
|
||||||
<source>Odd Parity</source>
|
|
||||||
<translation></translation>
|
|
||||||
</message>
|
|
||||||
<message>
|
|
||||||
<source>Space Parity</source>
|
|
||||||
<translation></translation>
|
|
||||||
</message>
|
|
||||||
<message>
|
|
||||||
<source>Mark Parity</source>
|
|
||||||
<translation></translation>
|
|
||||||
</message>
|
|
||||||
<message>
|
|
||||||
<source>One and Half</source>
|
|
||||||
<translation></translation>
|
|
||||||
</message>
|
|
||||||
<message>
|
|
||||||
<source>Two</source>
|
|
||||||
<translation></translation>
|
|
||||||
</message>
|
|
||||||
<message>
|
|
||||||
<source>Hardware Control</source>
|
|
||||||
<translation></translation>
|
|
||||||
</message>
|
|
||||||
<message>
|
|
||||||
<source>Software Control</source>
|
|
||||||
<translation></translation>
|
|
||||||
</message>
|
|
||||||
<message>
|
<message>
|
||||||
<source>Select Port</source>
|
<source>Select Port</source>
|
||||||
<translation></translation>
|
<translation></translation>
|
||||||
</message>
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>None</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Even</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Odd</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Space</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Mark</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
<context>
|
||||||
<name>Toolbar</name>
|
<name>Toolbar</name>
|
||||||
|
@ -480,40 +480,60 @@
|
|||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>Even Parity</source>
|
<source>Even Parity</source>
|
||||||
<translation>Par</translation>
|
<translation type="vanished">Par</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>Odd Parity</source>
|
<source>Odd Parity</source>
|
||||||
<translation>Inpar</translation>
|
<translation type="vanished">Inpar</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>Space Parity</source>
|
<source>Space Parity</source>
|
||||||
<translation>Espacio</translation>
|
<translation type="vanished">Espacio</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>Mark Parity</source>
|
<source>Mark Parity</source>
|
||||||
<translation>Marca</translation>
|
<translation type="vanished">Marca</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>One and Half</source>
|
<source>One and Half</source>
|
||||||
<translation>Uno y Medio</translation>
|
<translation type="vanished">Uno y Medio</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>Two</source>
|
<source>Two</source>
|
||||||
<translation>Dos</translation>
|
<translation type="vanished">Dos</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>Hardware Control</source>
|
<source>Hardware Control</source>
|
||||||
<translation>Controlado por hardware</translation>
|
<translation type="vanished">Controlado por hardware</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>Software Control</source>
|
<source>Software Control</source>
|
||||||
<translation>Controlado por software</translation>
|
<translation type="vanished">Controlado por software</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>Select Port</source>
|
<source>Select Port</source>
|
||||||
<translation>Seleccionar Puerto</translation>
|
<translation>Seleccionar Puerto</translation>
|
||||||
</message>
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>None</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Even</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Odd</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Space</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Mark</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
<context>
|
||||||
<name>Toolbar</name>
|
<name>Toolbar</name>
|
||||||
|
@ -353,17 +353,19 @@ void JsonGenerator::readData(const QByteArray &data)
|
|||||||
// info from the microcontroller).
|
// info from the microcontroller).
|
||||||
if (!ok)
|
if (!ok)
|
||||||
{
|
{
|
||||||
|
// Increment error counter
|
||||||
|
++m_dataFormatErrors;
|
||||||
|
|
||||||
// Avoid nagging the user too much (only display once, and only
|
// Avoid nagging the user too much (only display once, and only
|
||||||
// after two continous errors have been detected)
|
// after two continous errors have been detected)
|
||||||
if (m_dataFormatErrors == 1)
|
if (m_dataFormatErrors == 2)
|
||||||
{
|
{
|
||||||
NiceMessageBox(tr("JSON/serial data format mismatch"),
|
NiceMessageBox(tr("JSON/serial data format mismatch"),
|
||||||
tr("The format of the received data does not "
|
tr("The format of the received data does not "
|
||||||
"correspond to the selected JSON map file."));
|
"correspond to the selected JSON map file."));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Increase format error counter
|
// Stop executing function
|
||||||
++m_dataFormatErrors;
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -38,16 +38,14 @@ SerialManager::SerialManager()
|
|||||||
// Ensure that pointers are NULL
|
// Ensure that pointers are NULL
|
||||||
m_port = nullptr;
|
m_port = nullptr;
|
||||||
m_receivedBytes = 0;
|
m_receivedBytes = 0;
|
||||||
m_textCursor = nullptr;
|
|
||||||
m_textDocument = nullptr;
|
|
||||||
|
|
||||||
// Init serial port configuration variables
|
// Init serial port configuration variables
|
||||||
setPort(0);
|
setPort(0);
|
||||||
setParity(parityList().indexOf(tr("No Parity")));
|
setParity(parityList().indexOf(tr("None")));
|
||||||
setBaudRate(baudRateList().indexOf("9600"));
|
setBaudRate(baudRateList().indexOf("9600"));
|
||||||
setDataBits(dataBitsList().indexOf("8"));
|
setDataBits(dataBitsList().indexOf("8"));
|
||||||
setStopBits(stopBitsList().indexOf(tr("One")));
|
setStopBits(stopBitsList().indexOf("1"));
|
||||||
setFlowControl(flowControlList().indexOf(tr("No Flow Control")));
|
setFlowControl(flowControlList().indexOf(tr("None")));
|
||||||
|
|
||||||
// Init start/finish sequence strings
|
// Init start/finish sequence strings
|
||||||
setStartSequence("/*");
|
setStartSequence("/*");
|
||||||
@ -56,6 +54,9 @@ SerialManager::SerialManager()
|
|||||||
|
|
||||||
// Build serial devices list
|
// Build serial devices list
|
||||||
refreshSerialDevices();
|
refreshSerialDevices();
|
||||||
|
|
||||||
|
// Start frame interpretation loop (~60 Hz)
|
||||||
|
readFrames();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -271,12 +272,11 @@ QStringList SerialManager::portList() const
|
|||||||
QStringList SerialManager::parityList() const
|
QStringList SerialManager::parityList() const
|
||||||
{
|
{
|
||||||
QStringList list;
|
QStringList list;
|
||||||
list.append(tr("No Parity"));
|
list.append(tr("None"));
|
||||||
list.append(tr("Even Parity"));
|
list.append(tr("Even"));
|
||||||
list.append(tr("Odd Parity"));
|
list.append(tr("Odd"));
|
||||||
list.append(tr("Space Parity"));
|
list.append(tr("Space"));
|
||||||
list.append(tr("Mark Parity"));
|
list.append(tr("Mark"));
|
||||||
|
|
||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -287,7 +287,7 @@ QStringList SerialManager::parityList() const
|
|||||||
QStringList SerialManager::baudRateList() const
|
QStringList SerialManager::baudRateList() const
|
||||||
{
|
{
|
||||||
return QStringList { "1200", "2400", "4800", "9600",
|
return QStringList { "1200", "2400", "4800", "9600",
|
||||||
"19200", "38400", "57600", "115200" };
|
"19200", "38400", "57600", "115200" };
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -305,11 +305,7 @@ QStringList SerialManager::dataBitsList() const
|
|||||||
*/
|
*/
|
||||||
QStringList SerialManager::stopBitsList() const
|
QStringList SerialManager::stopBitsList() const
|
||||||
{
|
{
|
||||||
QStringList list;
|
return QStringList { "1", "1.5", "2" };
|
||||||
list.append(tr("One"));
|
|
||||||
list.append(tr("One and Half"));
|
|
||||||
list.append(tr("Two"));
|
|
||||||
return list;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -319,9 +315,9 @@ QStringList SerialManager::stopBitsList() const
|
|||||||
QStringList SerialManager::flowControlList() const
|
QStringList SerialManager::flowControlList() const
|
||||||
{
|
{
|
||||||
QStringList list;
|
QStringList list;
|
||||||
list.append(tr("No Flow Control"));
|
list.append(tr("None"));
|
||||||
list.append(tr("Hardware Control"));
|
list.append("RTS/CTS");
|
||||||
list.append(tr("Software Control"));
|
list.append("XON/XOFF");
|
||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -371,12 +367,14 @@ QSerialPort::FlowControl SerialManager::flowControl() const
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the pointer to the text document object, which is used by the
|
* Configures the text document to make it fit for logging purposes
|
||||||
* class to add RX/TX data and handle document size automatically.
|
|
||||||
*/
|
*/
|
||||||
QQuickTextDocument *SerialManager::textDocument() const
|
void SerialManager::configureTextDocument(QQuickTextDocument* doc)
|
||||||
{
|
{
|
||||||
return m_textDocument;
|
if (doc) {
|
||||||
|
doc->textDocument()->setUndoRedoEnabled(false);
|
||||||
|
doc->textDocument()->setMaximumBlockCount(100);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -386,6 +384,7 @@ QQuickTextDocument *SerialManager::textDocument() const
|
|||||||
*/
|
*/
|
||||||
void SerialManager::clearTempBuffer()
|
void SerialManager::clearTempBuffer()
|
||||||
{
|
{
|
||||||
|
LOG_INFO() << "Deleting temp. buffer to avoid excesive memory usage..";
|
||||||
m_tempBuffer.clear();
|
m_tempBuffer.clear();
|
||||||
LOG_INFO() << "Temporary data buffer cleared";
|
LOG_INFO() << "Temporary data buffer cleared";
|
||||||
}
|
}
|
||||||
@ -450,21 +449,16 @@ void SerialManager::sendData(const QString &data)
|
|||||||
// Get sent byte array
|
// Get sent byte array
|
||||||
auto sent = bin;
|
auto sent = bin;
|
||||||
sent.chop(bin.length() - bytes);
|
sent.chop(bin.length() - bytes);
|
||||||
emit tx(sent, bytes);
|
|
||||||
LOG_INFO() << "Written" << bytes << "bytes to serial port";
|
LOG_INFO() << "Written" << bytes << "bytes to serial port";
|
||||||
|
|
||||||
// Update text document
|
|
||||||
if (m_textCursor)
|
|
||||||
{
|
|
||||||
auto text = QString::fromUtf8(sent);
|
|
||||||
m_textCursor->insertHtml("<br><font color=#f08>" + text
|
|
||||||
+ "</font><br>");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Bytes not equal to data length
|
// Bytes not equal to data length
|
||||||
if (bytes != bin.length())
|
if (bytes != bin.length())
|
||||||
LOG_WARNING()
|
LOG_WARNING()
|
||||||
<< "Written data length not equal to request data length";
|
<< "Written data length not equal to request data length";
|
||||||
|
|
||||||
|
// Emit signals
|
||||||
|
else
|
||||||
|
emit tx(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Write error
|
// Write error
|
||||||
@ -570,24 +564,24 @@ void SerialManager::setParity(const quint8 parityIndex)
|
|||||||
// Set parity based on current index
|
// Set parity based on current index
|
||||||
switch (parityIndex)
|
switch (parityIndex)
|
||||||
{
|
{
|
||||||
case 0:
|
case 0:
|
||||||
m_parity = QSerialPort::NoParity;
|
m_parity = QSerialPort::NoParity;
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
m_parity = QSerialPort::EvenParity;
|
m_parity = QSerialPort::EvenParity;
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
m_parity = QSerialPort::OddParity;
|
m_parity = QSerialPort::OddParity;
|
||||||
break;
|
break;
|
||||||
case 3:
|
case 3:
|
||||||
m_parity = QSerialPort::SpaceParity;
|
m_parity = QSerialPort::SpaceParity;
|
||||||
break;
|
break;
|
||||||
case 4:
|
case 4:
|
||||||
m_parity = QSerialPort::MarkParity;
|
m_parity = QSerialPort::MarkParity;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
m_parity = QSerialPort::UnknownParity;
|
m_parity = QSerialPort::UnknownParity;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update serial port config.
|
// Update serial port config.
|
||||||
@ -618,33 +612,33 @@ void SerialManager::setBaudRate(const quint8 baudRateIndex)
|
|||||||
// Obtain baud rate value from current index
|
// Obtain baud rate value from current index
|
||||||
switch (baudRateIndex)
|
switch (baudRateIndex)
|
||||||
{
|
{
|
||||||
case 0:
|
case 0:
|
||||||
m_baudRate = QSerialPort::Baud1200;
|
m_baudRate = QSerialPort::Baud1200;
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
m_baudRate = QSerialPort::Baud2400;
|
m_baudRate = QSerialPort::Baud2400;
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
m_baudRate = QSerialPort::Baud4800;
|
m_baudRate = QSerialPort::Baud4800;
|
||||||
break;
|
break;
|
||||||
case 3:
|
case 3:
|
||||||
m_baudRate = QSerialPort::Baud9600;
|
m_baudRate = QSerialPort::Baud9600;
|
||||||
break;
|
break;
|
||||||
case 4:
|
case 4:
|
||||||
m_baudRate = QSerialPort::Baud19200;
|
m_baudRate = QSerialPort::Baud19200;
|
||||||
break;
|
break;
|
||||||
case 5:
|
case 5:
|
||||||
m_baudRate = QSerialPort::Baud38400;
|
m_baudRate = QSerialPort::Baud38400;
|
||||||
break;
|
break;
|
||||||
case 6:
|
case 6:
|
||||||
m_baudRate = QSerialPort::Baud57600;
|
m_baudRate = QSerialPort::Baud57600;
|
||||||
break;
|
break;
|
||||||
case 7:
|
case 7:
|
||||||
m_baudRate = QSerialPort::Baud115200;
|
m_baudRate = QSerialPort::Baud115200;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
m_baudRate = QSerialPort::UnknownBaud;
|
m_baudRate = QSerialPort::UnknownBaud;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update serial port config
|
// Update serial port config
|
||||||
@ -675,21 +669,21 @@ void SerialManager::setDataBits(const quint8 dataBitsIndex)
|
|||||||
// Obtain data bits value from current index
|
// Obtain data bits value from current index
|
||||||
switch (dataBitsIndex)
|
switch (dataBitsIndex)
|
||||||
{
|
{
|
||||||
case 0:
|
case 0:
|
||||||
m_dataBits = QSerialPort::Data5;
|
m_dataBits = QSerialPort::Data5;
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
m_dataBits = QSerialPort::Data6;
|
m_dataBits = QSerialPort::Data6;
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
m_dataBits = QSerialPort::Data7;
|
m_dataBits = QSerialPort::Data7;
|
||||||
break;
|
break;
|
||||||
case 3:
|
case 3:
|
||||||
m_dataBits = QSerialPort::Data8;
|
m_dataBits = QSerialPort::Data8;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
m_dataBits = QSerialPort::UnknownDataBits;
|
m_dataBits = QSerialPort::UnknownDataBits;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update serial port configuration
|
// Update serial port configuration
|
||||||
@ -720,18 +714,18 @@ void SerialManager::setStopBits(const quint8 stopBitsIndex)
|
|||||||
// Obtain stop bits value from current index
|
// Obtain stop bits value from current index
|
||||||
switch (stopBitsIndex)
|
switch (stopBitsIndex)
|
||||||
{
|
{
|
||||||
case 0:
|
case 0:
|
||||||
m_stopBits = QSerialPort::OneStop;
|
m_stopBits = QSerialPort::OneStop;
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
m_stopBits = QSerialPort::OneAndHalfStop;
|
m_stopBits = QSerialPort::OneAndHalfStop;
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
m_stopBits = QSerialPort::TwoStop;
|
m_stopBits = QSerialPort::TwoStop;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
m_stopBits = QSerialPort::UnknownStopBits;
|
m_stopBits = QSerialPort::UnknownStopBits;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update serial port configuration
|
// Update serial port configuration
|
||||||
@ -836,18 +830,18 @@ void SerialManager::setFlowControl(const quint8 flowControlIndex)
|
|||||||
// Obtain flow control value from current index
|
// Obtain flow control value from current index
|
||||||
switch (flowControlIndex)
|
switch (flowControlIndex)
|
||||||
{
|
{
|
||||||
case 0:
|
case 0:
|
||||||
m_flowControl = QSerialPort::NoFlowControl;
|
m_flowControl = QSerialPort::NoFlowControl;
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
m_flowControl = QSerialPort::HardwareControl;
|
m_flowControl = QSerialPort::HardwareControl;
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
m_flowControl = QSerialPort::SoftwareControl;
|
m_flowControl = QSerialPort::SoftwareControl;
|
||||||
break;
|
break;
|
||||||
case 3:
|
case 3:
|
||||||
m_flowControl = QSerialPort::UnknownFlowControl;
|
m_flowControl = QSerialPort::UnknownFlowControl;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update serial port configuration
|
// Update serial port configuration
|
||||||
@ -861,35 +855,6 @@ void SerialManager::setFlowControl(const quint8 flowControlIndex)
|
|||||||
LOG_INFO() << "Flow control set to" << flowControl();
|
LOG_INFO() << "Flow control set to" << flowControl();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets the text document object to be used as a serial console printout.
|
|
||||||
* We need to do this from C++ so that we have greater control over
|
|
||||||
* the memory consumption of the text console.
|
|
||||||
*/
|
|
||||||
void SerialManager::setTextDocument(QQuickTextDocument *textDocument)
|
|
||||||
{
|
|
||||||
// Delete previous text cursor
|
|
||||||
if (m_textCursor)
|
|
||||||
delete m_textCursor;
|
|
||||||
|
|
||||||
// Disconnect previous signals/slots
|
|
||||||
if (m_textDocument)
|
|
||||||
m_textDocument->textDocument()->disconnect(this,
|
|
||||||
SLOT(reduceDocumentSize()));
|
|
||||||
|
|
||||||
// Re-assign pointer & register text cursor
|
|
||||||
m_textDocument = textDocument;
|
|
||||||
m_textCursor = new QTextCursor(m_textDocument->textDocument());
|
|
||||||
m_textCursor->movePosition(QTextCursor::End);
|
|
||||||
|
|
||||||
// Connect signals/slots
|
|
||||||
connect(m_textDocument->textDocument(), SIGNAL(contentsChanged()), this,
|
|
||||||
SLOT(reduceDocumentSize()));
|
|
||||||
|
|
||||||
// Update UI
|
|
||||||
emit textDocumentChanged();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Reads incoming data from the serial device, updates the serial console
|
* Reads incoming data from the serial device, updates the serial console
|
||||||
* object, registers incoming data to temporary buffer & extracts valid data
|
* object, registers incoming data to temporary buffer & extracts valid data
|
||||||
@ -898,71 +863,24 @@ void SerialManager::setTextDocument(QQuickTextDocument *textDocument)
|
|||||||
void SerialManager::onDataReceived()
|
void SerialManager::onDataReceived()
|
||||||
{
|
{
|
||||||
// Verify that port is still alive
|
// Verify that port is still alive
|
||||||
if (port() != nullptr)
|
if (port() == nullptr)
|
||||||
{
|
return;
|
||||||
// Get data & calculate received bytes
|
|
||||||
auto data = port()->readAll();
|
|
||||||
auto bytes = data.length();
|
|
||||||
|
|
||||||
// Update received bytes indicator
|
// Get data & calculate received bytes
|
||||||
m_receivedBytes += bytes;
|
auto data = port()->readAll();
|
||||||
if (m_receivedBytes >= UINT64_MAX)
|
auto bytes = data.length();
|
||||||
m_receivedBytes = 0;
|
|
||||||
|
|
||||||
// Notify user interface
|
// Add data to temp. buffer
|
||||||
emit rx(data, bytes);
|
m_tempBuffer.append(data);
|
||||||
emit receivedBytesChanged();
|
|
||||||
|
|
||||||
// Update text document
|
// Update received bytes indicator
|
||||||
if (m_textCursor)
|
m_receivedBytes += bytes;
|
||||||
{
|
if (m_receivedBytes >= UINT64_MAX)
|
||||||
auto text = QString::fromUtf8(data);
|
m_receivedBytes = 0;
|
||||||
m_textCursor->insertHtml("<font color=#0f8>" + text + "</font>");
|
|
||||||
if (text.contains('\n'))
|
|
||||||
m_textCursor->insertHtml("<br>");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add data to temp. buffer
|
// Notify user interface
|
||||||
m_tempBuffer.append(data);
|
emit receivedBytesChanged();
|
||||||
|
emit rx(QString::fromUtf8(data));
|
||||||
// Check if data contains start sequence
|
|
||||||
auto start = startSequence().toUtf8();
|
|
||||||
auto finish = finishSequence().toUtf8();
|
|
||||||
while (m_tempBuffer.contains(start))
|
|
||||||
{
|
|
||||||
// Begin reading from start sequence index
|
|
||||||
auto buffer = m_tempBuffer;
|
|
||||||
auto sIndex = m_tempBuffer.indexOf(start);
|
|
||||||
buffer.remove(0, sIndex + start.length());
|
|
||||||
|
|
||||||
// Check that new buffer contains finish sequence
|
|
||||||
if (!buffer.contains(finish))
|
|
||||||
return;
|
|
||||||
|
|
||||||
// Remove bytes outside start/end sequence range
|
|
||||||
auto fIndex = buffer.indexOf(finish);
|
|
||||||
buffer.remove(fIndex, buffer.length() - fIndex);
|
|
||||||
|
|
||||||
// Buffer is not empty, notify app & remove read data from buffer
|
|
||||||
if (!buffer.isEmpty())
|
|
||||||
{
|
|
||||||
emit packetReceived(buffer);
|
|
||||||
m_tempBuffer.remove(0, sIndex + fIndex + finish.length());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Clears data from the serial console object if log length exceeds 10 KB.
|
|
||||||
*/
|
|
||||||
void SerialManager::reduceDocumentSize()
|
|
||||||
{
|
|
||||||
if (m_textDocument && m_textCursor)
|
|
||||||
{
|
|
||||||
if (m_textCursor->position() > 10 * (1024))
|
|
||||||
m_textDocument->textDocument()->clear();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -993,3 +911,47 @@ void SerialManager::refreshSerialDevices()
|
|||||||
// Call this function again in one second
|
// Call this function again in one second
|
||||||
QTimer::singleShot(100, this, SLOT(refreshSerialDevices()));
|
QTimer::singleShot(100, this, SLOT(refreshSerialDevices()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Read frames from temporary buffer, every frame that contains the appropiate
|
||||||
|
* start/end sequence is removed from the buffer as soon as its read.
|
||||||
|
*
|
||||||
|
* This function also checks that the buffer size does not exceed specified
|
||||||
|
* size limitations.
|
||||||
|
*/
|
||||||
|
void SerialManager::readFrames() {
|
||||||
|
// Only execute code if we are connected to a serial device
|
||||||
|
if (connected()) {
|
||||||
|
auto start = startSequence().toUtf8();
|
||||||
|
auto finish = finishSequence().toUtf8();
|
||||||
|
while (m_tempBuffer.contains(start) && m_tempBuffer.contains(finish))
|
||||||
|
{
|
||||||
|
// Begin reading from start sequence index
|
||||||
|
auto buffer = m_tempBuffer;
|
||||||
|
auto sIndex = m_tempBuffer.indexOf(start);
|
||||||
|
buffer.remove(0, sIndex + start.length());
|
||||||
|
|
||||||
|
// Check that new buffer contains finish sequence
|
||||||
|
if (!buffer.contains(finish))
|
||||||
|
break;
|
||||||
|
|
||||||
|
// Remove bytes outside start/end sequence range
|
||||||
|
auto fIndex = buffer.indexOf(finish);
|
||||||
|
buffer.remove(fIndex, buffer.length() - fIndex);
|
||||||
|
|
||||||
|
// Buffer is not empty, notify app & remove read data from buffer
|
||||||
|
if (!buffer.isEmpty())
|
||||||
|
{
|
||||||
|
emit packetReceived(buffer);
|
||||||
|
m_tempBuffer.remove(0, sIndex + fIndex + finish.length());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Clear temp. buffer
|
||||||
|
if (m_tempBuffer.size() > maxBufferSize())
|
||||||
|
clearTempBuffer();
|
||||||
|
|
||||||
|
// Execute this function at about 100 Hz
|
||||||
|
QTimer::singleShot(10, Qt::PreciseTimer, this, SLOT(readFrames()));
|
||||||
|
}
|
||||||
|
@ -121,10 +121,10 @@ signals:
|
|||||||
void receivedBytesChanged();
|
void receivedBytesChanged();
|
||||||
void finishSequenceChanged();
|
void finishSequenceChanged();
|
||||||
void availablePortsChanged();
|
void availablePortsChanged();
|
||||||
|
void rx(const QString& rxData);
|
||||||
|
void tx(const QString& txData);
|
||||||
void connectionError(const QString &name);
|
void connectionError(const QString &name);
|
||||||
void packetReceived(const QByteArray &packet);
|
void packetReceived(const QByteArray &packet);
|
||||||
void rx(const QByteArray &data, const quint64 bytes);
|
|
||||||
void tx(const QByteArray &data, const quint64 bytes);
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static SerialManager *getInstance();
|
static SerialManager *getInstance();
|
||||||
@ -160,7 +160,7 @@ public:
|
|||||||
QSerialPort::StopBits stopBits() const;
|
QSerialPort::StopBits stopBits() const;
|
||||||
QSerialPort::FlowControl flowControl() const;
|
QSerialPort::FlowControl flowControl() const;
|
||||||
|
|
||||||
QQuickTextDocument *textDocument() const;
|
Q_INVOKABLE void configureTextDocument(QQuickTextDocument* doc);
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void clearTempBuffer();
|
void clearTempBuffer();
|
||||||
@ -175,11 +175,10 @@ public slots:
|
|||||||
void setStartSequence(const QString &sequence);
|
void setStartSequence(const QString &sequence);
|
||||||
void setFinishSequence(const QString &sequence);
|
void setFinishSequence(const QString &sequence);
|
||||||
void setFlowControl(const quint8 flowControlIndex);
|
void setFlowControl(const quint8 flowControlIndex);
|
||||||
void setTextDocument(QQuickTextDocument *textDocument);
|
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
|
void readFrames();
|
||||||
void onDataReceived();
|
void onDataReceived();
|
||||||
void reduceDocumentSize();
|
|
||||||
void refreshSerialDevices();
|
void refreshSerialDevices();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@ -194,9 +193,6 @@ private:
|
|||||||
QSerialPort::StopBits m_stopBits;
|
QSerialPort::StopBits m_stopBits;
|
||||||
QSerialPort::FlowControl m_flowControl;
|
QSerialPort::FlowControl m_flowControl;
|
||||||
|
|
||||||
QTextCursor *m_textCursor;
|
|
||||||
QQuickTextDocument *m_textDocument;
|
|
||||||
|
|
||||||
quint8 m_portIndex;
|
quint8 m_portIndex;
|
||||||
quint8 m_parityIndex;
|
quint8 m_parityIndex;
|
||||||
quint8 m_baudRateIndex;
|
quint8 m_baudRateIndex;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user