CAN Bus example▲
Sélectionnez
/**
**************************************************************************
**
** Copyright (C) 2017 Andre Hartmann <aha_1980@gmx.de>
** Contact: https://www.qt.io/licensing/
**
** This file is part of the examples of the QtSerialBus module.
**
** $QT_BEGIN_LICENSE:BSD$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** BSD License Usage
** Alternatively, you may use this file under the terms of the BSD license
** as follows:
**
** "Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions are
** met:
** * Redistributions of source code must retain the above copyright
** notice, this list of conditions and the following disclaimer.
** * Redistributions in binary form must reproduce the above copyright
** notice, this list of conditions and the following disclaimer in
** the documentation and/or other materials provided with the
** distribution.
** * Neither the name of The Qt Company Ltd nor the names of its
** contributors may be used to endorse or promote products derived
** from this software without specific prior written permission.
**
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
**
** $QT_END_LICENSE$
**
***************************************************************************
*/
#include
"sendframebox.h"
#include
"ui_sendframebox.h"
enum
{
MaxStandardId =
0x7FF
,
MaxExtendedId =
0x10000000
}
;
enum
{
MaxPayload =
8
,
MaxPayloadFd =
64
}
;
HexIntegerValidator::
HexIntegerValidator(QObject *
parent) :
QValidator(parent),
m_maximum(MaxStandardId)
{
}
QValidator::
State HexIntegerValidator::
validate(QString &
amp;input, int
&
amp;) const
{
bool
ok;
uint value =
input.toUInt(&
amp;ok, 16
);
if
(input.isEmpty())
return
Intermediate;
if
(!
ok ||
value &
gt; m_maximum)
return
Invalid;
return
Acceptable;
}
void
HexIntegerValidator::
setMaximum(uint maximum)
{
m_maximum =
maximum;
}
HexStringValidator::
HexStringValidator(QObject *
parent) :
QValidator(parent),
m_maxLength(MaxPayload)
{
}
QValidator::
State HexStringValidator::
validate(QString &
amp;input, int
&
amp;pos) const
{
const
int
maxSize =
2
*
m_maxLength;
const
QChar space =
QLatin1Char(' '
);
QString data =
input;
data.remove(space);
if
(data.isEmpty())
return
Intermediate;
// limit maximum size and forbid trailing spaces
if
((data.size() &
gt; maxSize) ||
(data.size() ==
maxSize &
amp;&
amp; input.endsWith(space)))
return
Invalid;
// check if all input is valid
const
QRegularExpression re(QStringLiteral("^[[:xdigit:]]*$"
));
if
(!
re.match(data).hasMatch())
return
Invalid;
// insert a space after every two hex nibbles
const
QRegularExpression insertSpace(QStringLiteral("(?:[[:xdigit:]]{2} )*[[:xdigit:]]{3}"
));
if
(insertSpace.match(input).hasMatch()) {
input.insert(input.size() -
1
, space);
pos =
input.size();
}
return
Acceptable;
}
void
HexStringValidator::
setMaxLength(int
maxLength)
{
m_maxLength =
maxLength;
}
SendFrameBox::
SendFrameBox(QWidget *
parent) :
QGroupBox(parent),
m_ui(new
Ui::
SendFrameBox)
{
m_ui-&
gt;setupUi(this
);
m_hexIntegerValidator =
new
HexIntegerValidator(this
);
m_ui-&
gt;frameIdEdit-&
gt;setValidator(m_hexIntegerValidator);
m_hexStringValidator =
new
HexStringValidator(this
);
m_ui-&
gt;payloadEdit-&
gt;setValidator(m_hexStringValidator);
connect(m_ui-&
gt;dataFrame, &
amp;QRadioButton::
toggled, [this
](bool
set) {
if
(set)
m_ui-&
gt;flexibleDataRateBox-&
gt;setEnabled(true
);
}
);
connect(m_ui-&
gt;remoteFrame, &
amp;QRadioButton::
toggled, [this
](bool
set) {
if
(set) {
m_ui-&
gt;flexibleDataRateBox-&
gt;setEnabled(false
);
m_ui-&
gt;flexibleDataRateBox-&
gt;setChecked(false
);
}
}
);
connect(m_ui-&
gt;errorFrame, &
amp;QRadioButton::
toggled, [this
](bool
set) {
if
(set) {
m_ui-&
gt;flexibleDataRateBox-&
gt;setEnabled(false
);
m_ui-&
gt;flexibleDataRateBox-&
gt;setChecked(false
);
}
}
);
connect(m_ui-&
gt;extendedFormatBox, &
amp;QCheckBox::
toggled, [this
](bool
set) {
m_hexIntegerValidator-&
gt;setMaximum(set ? MaxExtendedId : MaxStandardId);
}
);
connect(m_ui-&
gt;flexibleDataRateBox, &
amp;QCheckBox::
toggled, [this
](bool
set) {
m_hexStringValidator-&
gt;setMaxLength(set ? MaxPayloadFd : MaxPayload);
m_ui-&
gt;bitrateSwitchBox-&
gt;setEnabled(set);
if
(!
set)
m_ui-&
gt;bitrateSwitchBox-&
gt;setChecked(false
);
}
);
auto
frameIdTextChanged =
[this
]() {
const
bool
hasFrameId =
!
m_ui-&
gt;frameIdEdit-&
gt;text().isEmpty();
m_ui-&
gt;sendButton-&
gt;setEnabled(hasFrameId);
m_ui-&
gt;sendButton-&
gt;setToolTip(hasFrameId
? QString() : tr("Cannot send because no Frame ID was given."
));
}
;
connect(m_ui-&
gt;frameIdEdit, &
amp;QLineEdit::
textChanged, frameIdTextChanged);
frameIdTextChanged();
connect(m_ui-&
gt;sendButton, &
amp;QPushButton::
clicked, [this
]() {
const
uint frameId =
m_ui-&
gt;frameIdEdit-&
gt;text().toUInt(nullptr
, 16
);
QString data =
m_ui-&
gt;payloadEdit-&
gt;text();
const
QByteArray payload =
QByteArray::
fromHex(data.remove(QLatin1Char(' '
)).toLatin1());
QCanBusFrame frame =
QCanBusFrame(frameId, payload);
frame.setExtendedFrameFormat(m_ui-&
gt;extendedFormatBox-&
gt;isChecked());
frame.setFlexibleDataRateFormat(m_ui-&
gt;flexibleDataRateBox-&
gt;isChecked());
frame.setBitrateSwitch(m_ui-&
gt;bitrateSwitchBox-&
gt;isChecked());
if
(m_ui-&
gt;errorFrame-&
gt;isChecked())
frame.setFrameType(QCanBusFrame::
ErrorFrame);
else
if
(m_ui-&
gt;remoteFrame-&
gt;isChecked())
frame.setFrameType(QCanBusFrame::
RemoteRequestFrame);
emit sendFrame(frame);
}
);
}
SendFrameBox::
~
SendFrameBox()
{
delete
m_ui;
}