Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
Форум программистов > С/С++: Кроссплатформенное программирование, Qt/Gtk+/wxWidgets > QCustomPlot и QByteArray |
Автор: 7BON 26.11.2015, 10:51 | ||||
Доброго дня! Произвожу передачу данных по COM порту(передача и прием осуществляется нормально) это через консоль. Ввожу таймер передача идет 8 байт, делаю остановку счетчика и снова запускаю, уже передача идет 16 байт и так каждый раз увеличивается на 8. В чем может быть проблема?
и второй вопрос, когда принимаю данные нужно отображать их на графике(использую библиотеку QCustomPlot). Вот код:
Добавлено через 1 минуту и 33 секунды Данные не отображаются. В чем может быть проблема? раньше с этой билиотекой не работал |
Автор: baldman88 26.11.2015, 11:42 |
По первому пункту ничего не понял. А вот по второму -- после обновления данных для отрисовки, нужно вызывать метод replot(). Допишите его в конец метода MainWindow::setupQuadraticDemo и будет Вам счастье. Этот ответ добавлен с нового Винграда - http://ru.vingrad.com/QCustomPlot-i-QByteArray-id5656ba9aae2015a2268b4567#findElement_E7045_5656c5f8ae2015f44a44f815_0 |
Автор: baldman88 26.11.2015, 11:57 |
И еще, по первому пункту. Зачем каждый раз создавать новый таймер? Создайте его в конструкторе. Плюс на один сигнал от таймера повешенно два слота. То, в какой очередности они выполнятся, будет зависеть от положения звезд на небе. Скорее всего из-за этого и происходит то, что вы описали. Этот ответ добавлен с нового Винграда - http://ru.vingrad.com/QCustomPlot-i-QByteArray-id5656ba9aae2015a2268b4567#findElement_E7045_5656c973ae2015a15044f84e_0 |
Автор: 7BON 26.11.2015, 13:15 |
в первом пункте пробывал прописать, не сработало, а по второму у меня replot() прописан в конструкторе, прописал так как вы сказали не сработало |
Автор: math64 26.11.2015, 13:29 | ||
Всегда нужно проверять число принятых байт. Например, у меня сделано так:
Данные могут приходить по одному байту, а могут приходить сразу много. processData() ждет когда накопится нужное количество байт (у тебя 8) и обрабатывает их. Возвращает число обработанных байт, которые потом удаляются из буфера. |
Автор: 7BON 18.12.2015, 08:55 | ||||
math64 возможно я не правильно задаю свою посылку Посылка по UART от компьютера(8 байт, скорость 115200 бод, один стоповый, без паритета) имеет следующую структуру: 1 - шапка - 0xA5; 2 - 0x01; 3 - старший байт адреса, по которому хранятся данные по току*; 4 - младший байт адреса, по которому хранятся данные по току*; 5 -7 - 0x00(резерв); 8 - кс; Ответная посылка имеет следующую структуру: 1 - шапка - 0xA5; 2 - 0x03; 3 - остаточная ёмкость в процентах; 4 - старший байт адреса, по которому хранятся данные по току; 5 - младший байт адреса, по которому хранятся данные по току; 6 - старший байт тока по запрашиваемому адресу; 7 - младший байт тока по запрашиваемому адресу; 8- кс; * - Первое измеренное значение начинается с адреса 0x0004, все последующие адреса рассчитываются добавлением 0x0002. это запись
это чтение
и вот значение I мне надо вывести подскажи как это сделать?? преобразование из шестнадцатиричной системы через функцию fromHex вроде бы |
Автор: math64 18.12.2015, 10:23 | ||
Наиболее удобный способ преобразования числа в строку-
Для отображения в виде графика - пройдись по массивам x и y чтобы найти минимум и максимум для setRange(); |
Автор: kuzulis 18.12.2015, 11:57 | ||||||||
1) В принципе, неправильно. Никто не гарантирует что readAll() вернет полный фрейм. 2) Парсить фреймы (также как и генерить) лучше используя QDataStream, а не
Например:
|
Автор: 7BON 22.12.2015, 13:55 | ||||||
kuzulis можете мне сказать: 1. в этой строке
value1 переменнная? и еще контрольную сумму создать как отдельную переменную к примеру вот так
в read тоже самое получается? 2.
выдает ошибку 1 и 3 строки D:\program ZUAA\terminal QCustomPlot\mainwindow.cpp:249: ошибка: 'expectedFrameLength' was not declared in this scope if (serial->bytesAvailable() < expectedFrameLength) где лучше всего объявить эту функцию? ^ |
Автор: math64 23.12.2015, 08:09 | ||
expectedFrameLength - в Вашем случае конствнта, = 8. Но если уж пользуемся QDataStream, то и задавать надо не числом, а примерно так:
Но: для правильного вычисления expectedFrameLength нужно, чтобы структура была упакована, а #pragma pack не гарантирует этого (хотя в большинстве компиляторов работает) |
Автор: kuzulis 23.12.2015, 11:57 |
Если структура упакована, то и QDataStream не нужен. ![]() Но, ИМХО, все-таки лучше и гибче QDataStream - меньше ошибок будет. ТС, посмотри примеры из /network/fortuneclient&&fortuneserver, погугли, и все будет нормуль. ![]() PS: И не надо бездумно копипастить куски кода, нужно думать что там и для чего! |
Автор: math64 23.12.2015, 13:53 |
В данном случае нужен, чтобы поменять порядок байтов в address (у ТС сначала идёт старший байт). |
Автор: 7BON 24.12.2015, 10:14 | ||||||
math64 у меня несколько вопросов: 1. Правильно ли я прописал это в файле.h
2. чтение осуществляю таким образом
ошибка в последней строке. если использоваться будет QDataStream чтение по другому будет осуществляться или таким образом? и если можно показать напримере 3.
Адрес таким образом можно менять или другим способом лучше? Этот ответ добавлен с нового Винграда - http://ru.vingrad.com/QCustomPlot-i-QByteArray-id5656ba9aae2015a2268b4567#findElement_E7045_567b9b6bae20150e3315077e_0 |
Автор: math64 25.12.2015, 08:07 | ||||||||||||||
1. Нет operator << для записи массива. Поэтому вместо
которое запишет строку нужно
Поскольку
порядок байт по умолчанию при записи address - тот, который нужен. Но при подсчете контрольной суммы нужно
Этого делать не нужно:
Вы уже все прочитали:
но результат нужно было записать в QByteArray или массив:
|
Автор: 7BON 29.12.2015, 14:34 | ||||||
math64 прописал вот так запись
чтение
посылку которую получаю совершенно другая (14 40 СЕ 6В 01 00 00 00), а нужно A5 01 00 04 00 00 00 CB к примеру, в чем может быть ошибка, что такая посылка идет? если прописать просто через QByteArray все получается. На рисунке, если видно Simple terminal в консоли не понятные символы кодировку я пробывал прописывать, но ничего не вышло прописал я так
как можно это исправить? Этот ответ добавлен с нового Винграда - http://ru.vingrad.com/QCustomPlot-i-QByteArray-id5656ba9aae2015a2268b4567#findElement_E7045_56826faaae20154d44d2a15e_0 |
Автор: 7BON 29.12.2015, 14:36 |
вот картинка Этот ответ добавлен с нового Винграда - http://ru.vingrad.com/QCustomPlot-i-QByteArray-id5656ba9aae2015a2268b4567#findElement_E7045_56827054ae2015b84cd29be5_0 |
Автор: math64 30.12.2015, 08:44 | ||||||||
Запись: 1. Зачем сначала передаёшь буфер, а затем заполняешь данными? Нужно наоборот. 2. Так у тебя все данные запишутся 3 раза:
В цикле должно быть только out << frame.reserved[i]; Чтение: Здесь должно быть не заполнение frameread, а проверка, что прочитано правильно (и, естественно, после того, как прочитано):
При чтении можешь ингорировать все до получения 0xA5, и только после этого читать фрейм. В принципе, можно не пользоваться QDataStream, а читать писать непосредственно в QByteArray |
Автор: 7BON 30.12.2015, 15:32 | ||||
можете скинуть пример, как проверить заполнение в QByteArray ![]()
я делал, но походу это не то. да и спасибо вам ![]() ![]() |
Автор: math64 30.12.2015, 16:24 |
Я на предудущей странице этой темы показывал фрагмент моего SerialHelper. В processData() ищется синхробайт (0xA5 в твоём случае), убеждаюсь что сообщение принято полностью (у меня в протоколе - второй байт - длина сообщения), проверяю контрольную сумму, если она совпадает, делаю messageReceived(char* buf, int len); и уже основная программа его обрабатывает. |
Автор: 7BON 4.1.2016, 10:53 | ||||||||
math64 можете объяснить: 1. что за переменная unprocessedData и для чего она? 2.
в этой строке создается массив и считывается с него байты, я понял так? 3.в этой строке
это наподибии вот этого?
4.
в этой строке прописать заместо byte 0xA5 для проверки я так понял? |
Автор: math64 11.1.2016, 09:02 |
1. unprocessedData - массив необработанных байтов. 2. ba - новые прочитанный байты. Добавляются к unprocessedData. 3. received - счетчик принятых байтов. Выводится в статус-строке. Необязательно. 4. processData выделяет в unprocessedData целое сообщение, т.е. ищет синхробайт 0xA5, проверяет что все данные считаны и контрольная сумма правильна, и делает emit messageReceived(buf, len); Если отсутствует синхробайт или контрльная сумма неправильна можешь делать emit garbageReceived(buf, len); - если хочешь обрабатывать мусор. Возвращает число обработанных байт, которые удаляются из unprocessedData. В слоте onMessageReceived(buf, len) разбираешь тело сообщения - можешь использовать QDataStream, можешь накладывать структуру или разбирать вручную (не забывай поменять порядок байт в слове). |