Serial communication
-
@Christian-Ehrlicher so how to fix it?
@Damian7546
Remove only what is used for a message from the buffer, leaving any further unused bytes there might be for appending to create next "message". -
@Damian7546 Something like this. But better don't use c-style casts:
m_responseStatus = static_cast<Response::Status>(m_request.mid(2,1).toInt(nullptr, 16));
@jsulm
This conversion doesn't work.class Response { public: enum class Status : quint8{ DISABLE = 0x1A, }; Response(); };
In
m_responseStatus
variable I have0x1A
value, but below statement is not equal:m_responseStatus = static_cast<Response::Status>(m_request.mid(2,1).toInt(nullptr, 16)); qDebug() << "m_responseStatus: " << m_request.mid(2,1); if(Response::Status::DISABLE == m_responseStatus) qDebug() << "ok convert"; else qDebug() << "bad convert";
Problem is in
toInt
conversion:qDebug() << "m_responseStatus: " << m_request.mid(2,1); qDebug() << "m_responseStatus: " << m_request.mid(2,1).toInt(nullptr, 16);
result:
m_responseStatus: "\x1A"
m_responseStatus: 0
-
@jsulm
This conversion doesn't work.class Response { public: enum class Status : quint8{ DISABLE = 0x1A, }; Response(); };
In
m_responseStatus
variable I have0x1A
value, but below statement is not equal:m_responseStatus = static_cast<Response::Status>(m_request.mid(2,1).toInt(nullptr, 16)); qDebug() << "m_responseStatus: " << m_request.mid(2,1); if(Response::Status::DISABLE == m_responseStatus) qDebug() << "ok convert"; else qDebug() << "bad convert";
Problem is in
toInt
conversion:qDebug() << "m_responseStatus: " << m_request.mid(2,1); qDebug() << "m_responseStatus: " << m_request.mid(2,1).toInt(nullptr, 16);
result:
m_responseStatus: "\x1A"
m_responseStatus: 0
@Damian7546 said in Serial communication:
In m_responseStatus variable I have 0x1A value, but below statement is not equal:
Sorry, I don't believe that. Start with:
qDebug() << int(m_responseStatus) << int(Response::Status::DISABLE) << 0x1A;
[I assume
int()
is good enough here to test. You can gostatic_cast<int>(...)
if necessary.] -
@Damian7546 said in Serial communication:
In m_responseStatus variable I have 0x1A value, but below statement is not equal:
Sorry, I don't believe that. Start with:
qDebug() << int(m_responseStatus) << int(Response::Status::DISABLE) << 0x1A;
[I assume
int()
is good enough here to test. You can gostatic_cast<int>(...)
if necessary.]@JonB said in Serial communication:
Sorry, I don't believe that. Start with:
qDebug() << int(m_responseStatus) << int(Response::Status::DISABLE) << 0x1A;Result:
0 26 26
-
@JonB said in Serial communication:
Sorry, I don't believe that. Start with:
qDebug() << int(m_responseStatus) << int(Response::Status::DISABLE) << 0x1A;Result:
0 26 26
@Damian7546
So you have your answer from the first 2 outputs.0 != 26
, the two values being compared are indeed not equal/the same.Behaviour is quite correct given your
m_request.mid(2,1).toInt(nullptr, 16);
, which (QByteArray::toInt()) is quite incorrect to use on your byte array containing a byte with value\x16
(26).toInt()
is not for use in your case, as you do not have a string representation of an integer to convert. -
@Damian7546
So you have your answer from the first 2 outputs.0 != 26
, the two values being compared are indeed not equal/the same.Behaviour is quite correct given your
m_request.mid(2,1).toInt(nullptr, 16);
, which (QByteArray::toInt()) is quite incorrect to use on your byte array containing a byte with value\x16
(26).toInt()
is not for use in your case, as you do not have a string representation of an integer to convert.@JonB So ho to compare
Response::Status::DISABLE
to byte in QByteArraym_request[2]
? -
@JonB So ho to compare
Response::Status::DISABLE
to byte in QByteArraym_request[2]
?@Damian7546
Exactly as you have just written it!qDebug() << Response::Status::DISABLE << m_request[2];
[You may have to do casting.] Sightly better is to use
m_request.at(2)
in place ofm_request[2]
here, but that is a detail and not related to your issue. You want to inspect the actual bytes in theQByteArray
, not callQByteArray::toInt()
. -
@Damian7546
Exactly as you have just written it!qDebug() << Response::Status::DISABLE << m_request[2];
[You may have to do casting.] Sightly better is to use
m_request.at(2)
in place ofm_request[2]
here, but that is a detail and not related to your issue. You want to inspect the actual bytes in theQByteArray
, not callQByteArray::toInt()
. -
@JonB casting is highly suggested, as
Response::Status
is an uint_8t and at() returns a char, aka int8_t@J-Hilk
Yes, but what I meant is I don't have anything available to test what compiler says as I write answers. So that detail is left to OP :) Since the OP asks about comparing (with==
) one should be able to compare aunit_8t
against achar
/int8_t
, I think, using C++ automatic expression promotion without bothering to cast/convert, I think? But maybe not/warning forenum
value against integer?The important thing is no
QByteArray::toInt()
here! -
@J-Hilk
Yes, but what I meant is I don't have anything available to test what compiler says as I write answers. So that detail is left to OP :) Since the OP asks about comparing (with==
) one should be able to compare aunit_8t
against achar
/int8_t
, I think, using C++ automatic expression promotion without bothering to cast/convert, I think? But maybe not/warning forenum
value against integer?The important thing is no
QByteArray::toInt()
here!@JonB It doesn't work:
qDebug() << static_cast<int>(Response::Status::DISABLE) << m_request.at(2);
Result:
ASSERT: "uint(i) < uint(size())" in file C:/Qt/5.15.2/mingw81_32/include/QtCore/qbytearray.h, line 500
And this way:
qDebug() << static_cast<int>(Response::Status::DISABLE) << m_request[2];
Result:
Where :
m_request response: "\xFC\x05\x1A\xF4\xE8"
-
@JonB It doesn't work:
qDebug() << static_cast<int>(Response::Status::DISABLE) << m_request.at(2);
Result:
ASSERT: "uint(i) < uint(size())" in file C:/Qt/5.15.2/mingw81_32/include/QtCore/qbytearray.h, line 500
And this way:
qDebug() << static_cast<int>(Response::Status::DISABLE) << m_request[2];
Result:
Where :
m_request response: "\xFC\x05\x1A\xF4\xE8"
@Damian7546
How difficult to try:qDebug() << static_cast<int>(Response::Status::DISABLE) << static_cast<int>(m_request[2]); // or qDebug() << static_cast<int>(Response::Status::DISABLE) << static_cast<int>(m_request.at(2));
? I leave you to resolve the C++ to your satisfaction.
-
@J-Hilk
Yes, but what I meant is I don't have anything available to test what compiler says as I write answers. So that detail is left to OP :) Since the OP asks about comparing (with==
) one should be able to compare aunit_8t
against achar
/int8_t
, I think, using C++ automatic expression promotion without bothering to cast/convert, I think? But maybe not/warning forenum
value against integer?The important thing is no
QByteArray::toInt()
here!@JonB said in Serial communication:
one should be able to compare a unit_8t against a char/int8_t, I think, using C++ automatic expression promotion without bothering to cast/convert, I think?
nono, comparing different types via == or != will never promote any side "automatically"
you can get something like that fi you wrap it in a function call or something but.
But comparing uint8_t and int_8 will only work correctly if both values are between 0 and 128.
-
@Damian7546
How difficult to try:qDebug() << static_cast<int>(Response::Status::DISABLE) << static_cast<int>(m_request[2]); // or qDebug() << static_cast<int>(Response::Status::DISABLE) << static_cast<int>(m_request.at(2));
? I leave you to resolve the C++ to your satisfaction.
@JonB Sill of topic.
I have variable:Response::Status m_responseStatus
.
How properly assign byte form QByteArray to m_responseStatus? -
@JonB Sill of topic.
I have variable:Response::Status m_responseStatus
.
How properly assign byte form QByteArray to m_responseStatus?@Damian7546 you were originally pretty spot on:
static_cast<Response::Status>(m_request.at(0));
-
@JonB said in Serial communication:
one should be able to compare a unit_8t against a char/int8_t, I think, using C++ automatic expression promotion without bothering to cast/convert, I think?
nono, comparing different types via == or != will never promote any side "automatically"
you can get something like that fi you wrap it in a function call or something but.
But comparing uint8_t and int_8 will only work correctly if both values are between 0 and 128.
@J-Hilk said in Serial communication:
nono, comparing different types via == or != will never promote any side "automatically"
Umm, C or C++
char c('A'); if (c == 65) {} example.cpp Compiler returned: 0
From Godbolt. That's "automatically promoting"
char c
toint 65
, per C/C++ expression rules. Has done since K&R... ?
https://en.cppreference.com/w/cpp/language/implicit_conversion, e.g. Integral conversions topic. -
@Damian7546 you were originally pretty spot on:
static_cast<Response::Status>(m_request.at(0));
@J-Hilk said in Serial communication:
static_cast<Response::Status>(m_request.at(0));
I trust healthy disagreement in polite spirit is allowed. Personally, for style, I would not cast an arbitrary integer value to an enumeration, where it might fall outside the range of values. I would prefer
if (static_cast<int>(Response::Status::DISABLE) == static_cast<int>(m_request.at(2))
which is what I wrote earlier, so doing the casting to
int
. -
@J-Hilk said in Serial communication:
static_cast<Response::Status>(m_request.at(0));
I trust healthy disagreement in polite spirit is allowed. Personally, for style, I would not cast an arbitrary integer value to an enumeration, where it might fall outside the range of values. I would prefer
if (static_cast<int>(Response::Status::DISABLE) == static_cast<int>(m_request.at(2))
which is what I wrote earlier, so doing the casting to
int
.@JonB said in Serial communication:
which is what I wrote earlier, so doing the casting to int.
yes I agree, but not what the op asked.
From Godbolt. That's "automatically promoting" char c to int 65, per C/C++ expression rules. Has done since K&R... ?
fair! Not what I had in mind when I wrote my answer and not the pitfall I fell into numerous times :D
-
@Damian7546 you were originally pretty spot on:
static_cast<Response::Status>(m_request.at(0));
@J-Hilk It still doesn't work:
m_responseStatus = static_cast<Response::Status>(m_request.at(2));
Result:
ASSERT: "uint(i) < uint(size())" in file C:/Qt/5.15.2/mingw81_32/include/QtCore/qbytearray.h, line 500
-
@J-Hilk It still doesn't work:
m_responseStatus = static_cast<Response::Status>(m_request.at(2));
Result:
ASSERT: "uint(i) < uint(size())" in file C:/Qt/5.15.2/mingw81_32/include/QtCore/qbytearray.h, line 500
@Damian7546 yes, but not the cast or assignment fails, but the access of your QByteArray, it doesn't have 3 Bytes in it and you try to access it outside of the range
-
@Damian7546 yes, but not the cast or assignment fails, but the access of your QByteArray, it doesn't have 3 Bytes in it and you try to access it outside of the range
@J-Hilk You're right