Russian Qt Forum

Qt => Вопросы новичков => Тема начата: Restorator от Сентябрь 28, 2015, 19:26



Название: Приложение для аппаратной системы
Отправлено: Restorator от Сентябрь 28, 2015, 19:26
По долгу службы необходимо разработать приложение, которое является неотъемлемой частью аппаратной системы.
Вкратце она представляет собой набор датчиков, которые подключены к последовательному порту. Из СОМ-порта постоянно летит поток данных с высокой (относительно) частотой - чуть больше 4000 посылок в секунду. Посылка около 100 байт бит. Задача состоит в:
    Первоочередно:
  • принять ВСЕ данные в той последовательности, в какой они пришли.
  • записать данные в поточном виде в файл для последующей обработки
    Вторично:
  • на ходу расшифровать посылки с упором не на качество, а на производительность (допускается пропускать посылки)
  • представить расшифрованные данные в виде графиков в реальном времени (сейчас 4 графика, до 1000 значений в секунду, окно просмотра ~5 секунд)

Поскольку я этим занимаюсь некоторое время, уже есть несколько пробных версий программы сбора данных и их обработки, но я ещё совсем учусь и решил всё переделать почтиСНуля, поэтому и прошу совета по архитектуре программы.
Пока я для себя нарисовал такую схему работы и уже частично её реализовал:
Есть класс Background, который запускается из main нужен лишь для того, чтобы сделать эклемпляры остальных рабочих классов.
Он запускает mainWindow, serialTranciever, messageRecognizer, dataFile и, самый важный, controlSet.
Принимает поток serialTranciever, вычленяет из потока посылки и кидает дальше сигналом, messageRecognizer принимает эти сигналы и проверяет посылки на размер и контрольную сумму, распихивает в структуру-контейнер и отправляет сигналом. Кроме того messageRecognizer на ходу находит посылки, которые можно вывести в графики и отправляет их простым сигналом с адресом и значением.
Посылки с контейнером приходят в dataFile, где он их пихает в буффер, сжимает qкомпрессом и записывает в файл по приходу определенной посылки.
Сигналы со значениями ловят виджеты QCustomPlot на mainWindow и рисуют графики.
Всем этим руководит controlSet, в котором лежат все переменные и реализованы методы для их изменения и получения. Все переменные он получает из QSettings при запуске программы и выгружает туда же при закрытии.
[/list][/list]
Код:
inline void setPortBaudRate(int value) {if (value>0) portBaudRate = value;}
inline int getPortBaudRate() {return portBaudRate;}
И там-же лежат все слоты-сигналы, которые меняют параметр в экземпляре при изменение его в поле настроек.

Я хотел бы услышать конструктивную критику, может я что-то делаю не так или можно сделать проще?






Название: Re: Приложение для аппаратной системы
Отправлено: Old от Сентябрь 28, 2015, 20:00
Много раз обсуждали эту тему, пытались придумать новые подходы...
Но все заканчивается практически одинаково: один процесс читает данные из порта и пачками их записывает в базу данных. Остальные процссы работают с данными из БД.


Название: Re: Приложение для аппаратной системы
Отправлено: Hellraiser от Сентябрь 28, 2015, 20:00
Это что за COM-порт, позволяющий обмениваться со скоростью ~ 3200000 бит/сек?
Само название порта - последовательный, как-бы намекает, что данные будут получены именно в том порядке, как и отправлены.
Как можно пропустить посылку при обмене порт-порт, кроме как физическое отваливание порта?
Короче, для начала было-бы неплохо разобраться с предметной областью, а не городить огород из чудо-классов.


Название: Re: Приложение для аппаратной системы
Отправлено: Old от Сентябрь 28, 2015, 20:03
Это что за COM-порт...
Скорее всего это RS-485.


Название: Re: Приложение для аппаратной системы
Отправлено: Hellraiser от Сентябрь 28, 2015, 20:20
По собственной практике, хотя для RS-485 и допустимы более высокие скорости (но, если не изменяет память, до 2000000 бит/сек.), никто в здравом уме их не использует. У RS-485 основная фишка - расстояние, но оно очень сильно зависит от скорости. Реальная скорость в длинной линии - от 9600 до 57600 бит/ сек.
P.S. И таки да, это был сарказм...


Название: Re: Приложение для аппаратной системы
Отправлено: Old от Сентябрь 28, 2015, 20:26
По собственной практике, хотя для RS-485 и допустимы более высокие скорости (но, если не изменяет память, до 2000000 бит/сек.), никто в здравом уме их не использует. У RS-485 основная фишка - расстояние, но оно очень сильно зависит от скорости. Реальная скорость в длинной линии - от 9600 до 57600 бит/ сек.
P.S. И таки да, это был сарказм...
Вообще, по стандарту там до 10 Мбит/с, здесь 3. Давайте подождем ТС, пусть расскажет.


Название: Re: Приложение для аппаратной системы
Отправлено: Restorator от Сентябрь 28, 2015, 23:17
Это что за COM-порт, позволяющий обмениваться со скоростью ~ 3200000 бит/сек?
Само название порта - последовательный, как-бы намекает, что данные будут получены именно в том порядке, как и отправлены.
Прошу прощения, у меня ошибочка. Не 100 байт, а 100 БИТ.  ::)
Шина CAN, через конвертер в виртуальный com, скорость передачи 921600 вполне хватает.
Но в перспективе масштабирование, так что вопрос с высокими скоростями актуален.
Как можно пропустить посылку при обмене порт-порт, кроме как физическое отваливание порта?
В предыдущих реализациях у меня сильно загружался процессор при отрисовке и почему-то терялись данные.
Короче, для начала было-бы неплохо разобраться с предметной областью, а не городить огород из чудо-классов.
С предметной областью всё в порядке, но я потому и спрашиваю, что только учусь.

Но все заканчивается практически одинаково: один процесс читает данные из порта и пачками их записывает в базу данных. Остальные процссы работают с данными из БД.
По поводу процессов, я правильно вас понял, что надо делать приём данных в отдельном потоке, или достаточно просто чтобы он был в отдельном классе?
Или это одно и то-же?

П.С. Понял, что не одно и то же, потому сразу вопрос:
Как всё-таки правильно реализовать в этом случает работу с потоками?
Нужно наследовать QThread и в нём переопределять run() или же создавать отдельный экземпляр класса и перекидывать его в поток через moveToThread?


Название: Re: Приложение для аппаратной системы
Отправлено: Old от Сентябрь 29, 2015, 03:40
В отдельном процессе это значит отдельная программа. Эта программа читает данные из железа и сохраняет их в БД. А другие программы работают с данными из базы, обрабатывают их, и они уже не о каком железе не думают.

По реализации программы-получателя: данные сохраняются в прдварительный буфер в памяти, а раз в какое-то время просыпается нить, которя пачкой сохраняет данные в базу. Одной транзакцией получается быстрей, чем если писать каждую запись отдельно.