Russian Qt Forum
Ноябрь 01, 2024, 15:17 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1]   Вниз
  Печать  
Автор Тема: Приложение для аппаратной системы  (Прочитано 3146 раз)
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;}
И там-же лежат все слоты-сигналы, которые меняют параметр в экземпляре при изменение его в поле настроек.

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




« Последнее редактирование: Сентябрь 28, 2015, 23:18 от Restorator » Записан
Old
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4350



Просмотр профиля
« Ответ #1 : Сентябрь 28, 2015, 20:00 »

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

Сообщений: 451


Просмотр профиля
« Ответ #2 : Сентябрь 28, 2015, 20:00 »

Это что за COM-порт, позволяющий обмениваться со скоростью ~ 3200000 бит/сек?
Само название порта - последовательный, как-бы намекает, что данные будут получены именно в том порядке, как и отправлены.
Как можно пропустить посылку при обмене порт-порт, кроме как физическое отваливание порта?
Короче, для начала было-бы неплохо разобраться с предметной областью, а не городить огород из чудо-классов.
Записан
Old
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4350



Просмотр профиля
« Ответ #3 : Сентябрь 28, 2015, 20:03 »

Это что за COM-порт...
Скорее всего это RS-485.
Записан
Hellraiser
Бывалый
*****
Offline Offline

Сообщений: 451


Просмотр профиля
« Ответ #4 : Сентябрь 28, 2015, 20:20 »

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

Сообщений: 4350



Просмотр профиля
« Ответ #5 : Сентябрь 28, 2015, 20:26 »

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

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

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

П.С. Понял, что не одно и то же, потому сразу вопрос:
Как всё-таки правильно реализовать в этом случает работу с потоками?
Нужно наследовать QThread и в нём переопределять run() или же создавать отдельный экземпляр класса и перекидывать его в поток через moveToThread?
« Последнее редактирование: Сентябрь 28, 2015, 23:59 от Restorator » Записан
Old
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4350



Просмотр профиля
« Ответ #7 : Сентябрь 29, 2015, 03:40 »

В отдельном процессе это значит отдельная программа. Эта программа читает данные из железа и сохраняет их в БД. А другие программы работают с данными из базы, обрабатывают их, и они уже не о каком железе не думают.

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


Страница сгенерирована за 0.087 секунд. Запросов: 23.