Как использовать Qt QSerialPort для отправки гекса 0x00
Я новичок в кодировании. Пожалуйста, потерпите меня. Я узнал из примера терминала Qt и попытался отправить необработанные шестнадцатеричные байты. Сначала я мог без проблем отправить 0x57, 0x04, 0x02. Как это
void MainWindow::writeData(const QByteArray &data)
{
serial->write(data);
}
void MainWindow::myFunction1()
{
QByteArray ba("\x57\x04\x02");
writeData(ba);
}
Затем, по мере продвижения, мне нужно было отправить несколько выбираемых строк данных с 0x00s. Приведенный выше код не будет отправлять \x00 и будет стереть что-нибудь за ним, поэтому я использовал 'fromRawData', чтобы остановить преобразование специального символа.
void MainWindow::myFunction2(int option)
{
QByteArray hexString;
switch (option){
case 1:
hexString.append(QByteArray::fromRawData("\x00\x01\x02",3);
break;
case 2:
hexString.append(QByteArray::fromRawData("\xFF\x00",2));
break;
}
writeData(hexString);
}
Приведенный выше код был в порядке, чтобы отправить обе строки константных символов. Но теперь я сталкиваюсь с реальной проблемой, мне нужно отправлять непостоянные шестнадцатеричные байты. Я создал массив без знака для хранения шестнадцатеричной строки, а затем изменил ее значение. Затем привел его к массиву const char. Но этот кастинг дал неправильный размер.
void MainWindow::myFunction3(int option)
{
unsigned char Diff[] = {0x45, 0x00, 0x01, 0x02};
...
Diff[2] = 0x08; // runtime change
const char *cDiff = (const char*)Diff; // casting
int size_Diff = sizeof(Diff); // qDebug shows 4
int size_cDiff = sizeof(cDiff); // qDebug shows 8 !!???
QByteArray hexString;
switch (option){
case 1:
hexString.append(QByteArray::fromRawData("\x00\x01\x02",3);
break;
case 2:
hexString.append(QByteArray::fromRawData("\xFF\x00",2));
break;
case 3:
hexString = QByteArray::fromRawData(cDiff, sizeof(cDiff));
break;
}
writeData(hexString);
}
В случае 3 я получил 0x45 0x00, 0x08, 0x02, 0x01, 0x00, 0x00, 0x00, всего 8 байтов на моей плате MCU! Затем я изменил размер Diff[] на 10, и снова sizeof(cDiff) = 8 тоже. Последние два байта были усечены.
Мой первый вопрос: есть ли лучший способ отправить беззнаковый символ другого размера массива и значения в диапазоне от 0x00 до 0xFF, определенные во время выполнения с использованием QSerialPort? Второй вопрос: почему приведение дало мне неправильный размер массива?
Большое спасибо за ваше внимание к этому DLIU
3 ответа
Вам не нужно делать все это, вы можете вводить "двоичные" данные в QByteArray напрямую, я использую это все время для отправки данных через последовательные интерфейсы во встроенных системах.
Вот пример:
QByteArray data;
// Add some data
data.append((char) 0xFF);
data.append((char) 0x00);
data.append((char) 0x55);
data.append((char) 0x99);
// Modify some data
data[0] = (char) 0x23;
data[2] = (char) 0x02;
Там нет возиться с приведением и использованием различных типов данных для хранения данных. Все это в QByteArray, который использует QSerialPort. (IMHO) всегда лучше стараться сохранять одинаковые типы данных, если при использовании Qt это обычно означает основанный на Qt тип, такой как QByteArray.
И вы можете использовать data.size()
чтобы получить длину.
редактировать
Еще одна вещь, на которую следует обратить внимание (возможно, именно в этом вы и ошибаетесь), я думаю, вы думаете о QByteArray как о строковом контейнере, но он также предназначен для хранения байтов (включая \0). Уже ваша переменная QByteArray hexString;
вид неправильно назван - я думаю, hexData
или просто serialData
более описательный. Дело в том, что вы пытаетесь использовать строки, где вы действительно можете использовать байты и биты.
Кроме того, вам даже не нужно приводить к типу char (как я это сделал), я начал делать это по привычке, потому что я делал такие вещи, как:
// Serialising uint16 into bytes...
uint16_t val;
:
msg.append((char) ((val >> 0) & 0xFF));
msg.append((char) ((val >> 8) & 0xFF));
Опять же, все байты и биты, а не строки.
sizeof
указатель никогда не является тем, что вам нужно, потому что он говорит вам об архитектуре компьютера (насколько велик указатель) и ничего о данных, на которые указывает указатель.
Также, strlen
не будет надежным, если ваша строка может содержать встроенные NUL-символы. Вам нужно будет отслеживать длину вручную другим способом.
Используйте std:: экстент, чтобы получить размеры статического массива:
unsigned char Diff[] = {0x45, 0x00, 0x01, 0x02};
const char *cDiff = (const char*)Diff;
int diffSize = std::extent<decltype(Diff)>::value;
QByteArray ba = QByteArray(cDiff,diffSize);
примечание: требуется C++11