Советы по программированию на LabVIEW

Простейшие вопросы в области инженерной разработки
Borjomy_1

Activity Professionalism Silver
doctor
doctor
Сообщения: 2210
Зарегистрирован: 28 июн 2012, 09:32
Награды: 3
Версия LabVIEW: 2009..2020
Откуда: город семи холмов
Благодарил (а): 27 раз
Поблагодарили: 26 раз

Re: Советы по программированию на LabVIEW

Сообщение Borjomy_1 »

Рекомендовал бы избавиться от двухмерного результирующего массива, заменить его одномерным. И скдадывать в сдвиговый регистр.
Убрать обмен байтами из приема.
После приёма полного фрейма последующую обработку проводить в отдельном цикле, куда передавать принятый буфер. Там уже делать и обмен байтами и перевод в двухмерный массив.
Проблема с двухмерными массивами в том, что скорость заполнения по строкам и столбцам разная.
Аватара пользователя
nae
user
user
Сообщения: 79
Зарегистрирован: 20 мар 2014, 14:21
Версия LabVIEW: 15
Откуда: Новосибирск
Благодарил (а): 5 раз
Контактная информация:

Re: Советы по программированию на LabVIEW

Сообщение nae »

Поиск совсем не лимитирует производительность.
Переворачивать и объединять "потом" - не получается - нужно искать по слову (из двух байт), а как это экономично сделать без перепаковки страницы из U8 в U16 - я пока не понял.
Продолжаю копать...
Похоже я много времени провожу в функциях FTDI READ в ожидании данных. Т.е. я прошу следующую страницу, а чип ещё не закончил её передачу и CLFN ждёт пока библиотека получит требуемое количество и отдаст управление.
Можно ли с помощью функции Wait или wait untill скажем с дискретой в 1..5мс отдавать управление другим процессам? Скажем спросить есть ли в буфере нужное количество, если пока нет, подождать 1мс (отдав управление куда-то), потом снова спросить?

UPD:
Вроде передача управления по Wait работает.
Сейчас на том же стареньком ноуте при 25фпс вообще нет проблем - успеваю даже перевести показания в температуру через полином третей степени и нарисовать в Intecity chart (в отдельном timed loop).
А на 50ФПС пока что успеваю только читать в кадровый буфер U16 с загрузкой 5% по данным винды. А вот с температурой и визуализацией опять идёт упор в ядро, но при этом общая загрузка не поднимается выше 50% - есть куда копать...
Аватара пользователя
IvanLis

Activity Professionalism Tutorials Gold Man of the year 2012
Автор
guru
guru
Сообщения: 5462
Зарегистрирован: 02 дек 2009, 17:44
Награды: 7
Версия LabVIEW: 2015, 2016
Откуда: СССР
Благодарил (а): 28 раз
Поблагодарили: 86 раз

Re: Советы по программированию на LabVIEW

Сообщение IvanLis »

Вам нужно раскидать задачи по нескольким процессам (циклам).
Первый цикл (квази реального времени) занимается только общением с железкой, получив пакет данных отправляет (очередь - queue) его во второй цикл и снова становится в ожидание.
Второй цикл (асинхронно работает с первым), принимает от первого данные и выполняет их обработку.
На этом можно остановиться.

Но я бы рекомендовал все процессы работы с UI вынести в третий цикл, который получает данные от второго цикла через уведомления (notifier) и занимается только отображением информации. Причем если он не успевает за первыми двумя, то отображает последние - актуальные данные.

Важно! первые два цикла не должны иметь никаких связей с UI, в том числе и Reference. Если нужны какие-то данные, типа как у Вас FTDI-Handle, то все данные из UI считываем за пределами цикла.

---------------
p.s. Иногда специально раскидываю по разным циклам одну задачу, если необходимо обеспечить требуемое быстродействие.
Такой прием и в FPGA используется - типа псевдо распараллеливание, но там через сдвиговые регистры гоняют данные между итерациями.
Аватара пользователя
nae
user
user
Сообщения: 79
Зарегистрирован: 20 мар 2014, 14:21
Версия LabVIEW: 15
Откуда: Новосибирск
Благодарил (а): 5 раз
Контактная информация:

Re: Советы по программированию на LabVIEW

Сообщение nae »

IvanLis писал(а): 11 июл 2022, 17:15 Вам нужно раскидать задачи по нескольким процессам (циклам).
Первый цикл (квази реального времени) занимается только общением с железкой, получив пакет данных отправляет (очередь - queue) его во второй цикл и снова становится в ожидание.
Второй цикл (асинхронно работает с первым), принимает от первого данные и выполняет их обработку.
На этом можно остановиться.

Но я бы рекомендовал все процессы работы с UI вынести в третий цикл, который получает данные от второго цикла через уведомления (notifier) и занимается только отображением информации. Причем если он не успевает за первыми двумя, то отображает последние - актуальные данные.

Важно! первые два цикла не должны иметь никаких связей с UI, в том числе и Reference. Если нужны какие-то данные, типа как у Вас FTDI-Handle, то все данные из UI считываем за пределами цикла.

---------------
p.s. Иногда специально раскидываю по разным циклам одну задачу, если необходимо обеспечить требуемое быстродействие.
Такой прием и в FPGA используется - типа псевдо распараллеливание, но там через сдвиговые регистры гоняют данные между итерациями.
Залетали бы у меня эти данные в sb9637 - я бы не раздумывая спихнул всё в плис - истинный параллелизм во всей красе - если проект синтезировался, то кривизна кода там уже не так страшна :) (гуев снизу нет - нет простора для рукожопства)

Минивопрос:
Очереди - это файфо, нотифаеры - это прерывания, а кто такие семафоры и рандеву и окьюренсы(на языке... МК или FPGA)???
Аватара пользователя
nae
user
user
Сообщения: 79
Зарегистрирован: 20 мар 2014, 14:21
Версия LabVIEW: 15
Откуда: Новосибирск
Благодарил (а): 5 раз
Контактная информация:

Re: Советы по программированию на LabVIEW

Сообщение nae »

Подскажите пожалуйста правильно ли я применил очереди и нотифаеры? (я использую их впервые...) Индикатор заполнения очереди показывает, что она пуста, т.е. элементы в ней не скапливаются.
Картинка от 50фпс бегает (но видно, что примерно каждый третий кадр не успевает). Нагрузка процесса возросла до 40% а общая нагрузка по монитору примерно вдвое выше.
На 25фпс пропусков нет, попоытки подергать окошки не приводят к потере кадров.
Нужно ли отслеживать то, что очередь пуста/нотифаер не установлен и не выполнять операции в этом случае или это само происходит? В том смысле, что установить нулевой таймаут и если пусто, то ни чего не делать и перейти к wait.
Нужно ли заменить это timed loop ы чтобы что-то улучшить?

UPD: Вставил нулевые таймауты в выборки, настроил приоритеты таймедлупов, вроде особо ни чего не изменилось. Статистика показывает, что ошибок в вычитке кадров нет даже на 50Гц, но на отрисовке по нотифаеру счетчик кадров показывает, что он через один пропускает кадры. Пока он рисует новый нотифаер успевает затереть предыдущий ещё не отрисованый.
UPD2: А если закрыть браузер, монитор активности и вообще всё что можно выключить и не шуметь в комнате, то времени начинает хватать! Вываливается из отрисовки всего примерно один кадр за 20 секунд. Наверное это уже хороший результат, по крайней мере не очень уступающий похожей программе коллеги на дельфи... :drink:
Вложения
Первый вариант
Первый вариант
Крайний вариант
Крайний вариант
Аватара пользователя
IvanLis

Activity Professionalism Tutorials Gold Man of the year 2012
Автор
guru
guru
Сообщения: 5462
Зарегистрирован: 02 дек 2009, 17:44
Награды: 7
Версия LabVIEW: 2015, 2016
Откуда: СССР
Благодарил (а): 28 раз
Поблагодарили: 86 раз

Re: Советы по программированию на LabVIEW

Сообщение IvanLis »

1. в цикле Collect loop: Чтение из локальной переменной (stop loop), убирайте локалку и оставляйте только остановку по ошибке.

2. в цикле Process Data loop: stop loop - аналогично 1. timeout queue = -1 (в холостую не крутим, так время реакции на реальные данные повышаем). И убираем все обращения к GUI (Вы продолжаете писать в TimeConsum.... и дергать локалки), в том числе локалки. Локальная переменная не так тормозит как Ref, но тоже тормозит. Вот наглядный пример.
Снимок экрана от 2022-07-12 14-41-36.png
по этому, все операции с GUI переносим в цикл Plot loop.
Если нужно что-то отображать, то шлите туда и там отображайте.
А в рабочих циклах все храним в сдвиговых регистрах и считаем там же.

3. Длину очереди ограничивать не стоит, иначе можно потерять данные. Ну и контролировать особо смысла нет, разве что на этапе отладки.

4. Кнопку stop loop кидаем в цикл Plot loop, а по ее нажатии и выхода из цикла, уничтожаем Queue и Notifier, что вызовет ошибку в остальных циклах и они остановятся.

И нужны ли Вам RT циклы? Разве только для Collect loop, остальные точно не нужны, они по поступлении данных должны работать, а не по времени.
И почему Вы в Intensity Graph через указатель пишите данные, если можно напрямую пихать, сразу в контрол?

Может еще что есть, но постарался все учесть....
Аватара пользователя
nae
user
user
Сообщения: 79
Зарегистрирован: 20 мар 2014, 14:21
Версия LabVIEW: 15
Откуда: Новосибирск
Благодарил (а): 5 раз
Контактная информация:

Re: Советы по программированию на LabVIEW

Сообщение nae »

IvanLis писал(а): 12 июл 2022, 14:52 ...
И почему Вы в Intensity Graph через указатель пишите данные, если можно напрямую пихать, сразу в контрол?
Intencity graph в отдельном VI размещен - вот и пишу по указателю )
Запись в локальный intencity chart не меняет загрузку потока, но улучшает синхронизацию - не получилось увидеть пропуск отрисовки перемещением окна.
ujin1
adviser
adviser
Сообщения: 231
Зарегистрирован: 06 ноя 2020, 15:37
Версия LabVIEW: 19
Благодарил (а): 18 раз
Поблагодарили: 37 раз
Контактная информация:

Re: Советы по программированию на LabVIEW

Сообщение ujin1 »

IvanLis писал(а): 12 июл 2022, 14:52 2. в цикле Process Data loop: stop loop - аналогично 1. timeout queue = -1 (в холостую не крутим, так время реакции на реальные данные повышаем).
Цикл Plot loop так же зависит от данных из цикла Process Data loop, следовательно timeout notifier так же лучше сделать -1
Цикл Plot loop и Process Data loop имеют одинаковый период 1 мс. Следовательно при выполнении цикла Plot loop больше чем 1 мс он пропускает данные.
Чтобы не пропускал, этот цикл можно заменить на while loop и не ставить задержки по времени в цикле.
IvanLis писал(а): 12 июл 2022, 14:52 И нужны ли Вам RT циклы? Разве только для Collect loop, остальные точно не нужны, они по поступлении данных должны работать, а не по времени.
Согласен, только добавлю небольшое пояснение. RT циклы предназначены для RT систем (NILinuxRT и др). Хоть в Windows приоритеты выполняются и разбивка по процессорам выполняется,
однако время цикла все равно плавает в широких пределах. Без пропусков в последнем цикле не получится. В данном случае RT циклы не помогут.
И в обычных while loop время цикла так же будет плавать в широких пределах, так как LabVIEW для Windows не самая приоритетная задача.
Приоритеты диаграмма.png
Приоритеты.png
Изображение
Аватара пользователя
nae
user
user
Сообщения: 79
Зарегистрирован: 20 мар 2014, 14:21
Версия LabVIEW: 15
Откуда: Новосибирск
Благодарил (а): 5 раз
Контактная информация:

Re: Советы по программированию на LabVIEW

Сообщение nae »

Подчистил лишнее. Выглядит как-то слишком просто и компактно в сравнении с тем с чего начинал... Работает отлично.
Вложения
lzv_v3.jpg
Аватара пользователя
IvanLis

Activity Professionalism Tutorials Gold Man of the year 2012
Автор
guru
guru
Сообщения: 5462
Зарегистрирован: 02 дек 2009, 17:44
Награды: 7
Версия LabVIEW: 2015, 2016
Откуда: СССР
Благодарил (а): 28 раз
Поблагодарили: 86 раз

Re: Советы по программированию на LabVIEW

Сообщение IvanLis »

nae писал(а): 13 июл 2022, 09:05 Подчистил лишнее. Выглядит как-то слишком просто и компактно в сравнении с тем с чего начинал... Работает отлично.
Можно указатель Queue не тянуть через верхний цикл, а очередность уничтожения задать "проводом" ошибки.
lzv_v3.jpg
Ну а что касается простоты, так это наоборот хорошо :wink:
Аватара пользователя
nae
user
user
Сообщения: 79
Зарегистрирован: 20 мар 2014, 14:21
Версия LabVIEW: 15
Откуда: Новосибирск
Благодарил (а): 5 раз
Контактная информация:

Re: Советы по программированию на LabVIEW

Сообщение nae »

Очередной чайниковопрос. Имеем USB3 камеру E3CMOS02300KMC. 120fps fullhd.
Нашел какие-то дрова от похожей камеры toup и там даже есть какая-то папка с dll для labview!
внутри две dll для х86 и х64 и h файл со странным содержимым
"
#ifndef __toupcam_labview_h__
#define __toupcam_labview_h__

#include "extcode.h"

#ifdef TOUPCAM_LABVIEW_EXPORTS
#define TOUPCAM_LABVIEW_API(x) __declspec(dllexport) x __cdecl
#else
#define TOUPCAM_LABVIEW_API(x) __declspec(dllimport) x __cdecl
#include "toupcam.h"
#endif

#ifdef __cplusplus
extern "C" {
#endif

TOUPCAM_LABVIEW_API(HRESULT) Start(HToupcam h, LVUserEventRef *rwer);

#ifdef __cplusplus
}
#endif

#endif
"
Импортер библиотек labview резонно ругается на это дело, говорит, что в заголовке описаны две функции, а в длл их нет - на этом его полномочия всё.
Может кто-то сталкивался с захватом изображений с usb камер - как это можно сделать через dll? Или нужно обязательно ставить какой-то тулкит?
Аватара пользователя
dadreamer

Activity Professionalism Автор
professor
professor
Сообщения: 3926
Зарегистрирован: 17 фев 2013, 16:33
Награды: 4
Версия LabVIEW: 2.5 — 2022
Благодарил (а): 11 раз
Поблагодарили: 126 раз
Контактная информация:

Re: Советы по программированию на LabVIEW

Сообщение dadreamer »

nae писал(а): 31 авг 2022, 18:53говорит, что в заголовке описаны две функции, а в длл их нет
В хэдере явно видна только одна функция - Start (по логике должна быть ещё Stop хотя бы, либо же Start может и стопить, если передать NULL в качестве rwer, например). А из самой DLL какие функции экспортируются? Поглядите через Dependency Walker или TC (Lister). Если DLL специально была разработана для связки с :labview: и с этой камерой, то логично именно её использовать. Если камера поддерживает дрова IMAQdx, то можно попытаться увидеть её через MAX и при успехе дальше использовать VDM. Если не поддерживает, то остаются только сторонние библиотеки. Это на вопрос о том, как работать с USB-камерами.

Ещё, общая рекомендация - настраивать CLFN "вручную", не используя мастер импорта, т.к. он часто не может корректно распарсить типы данных и вложенные конструкции.
Аватара пользователя
nae
user
user
Сообщения: 79
Зарегистрирован: 20 мар 2014, 14:21
Версия LabVIEW: 15
Откуда: Новосибирск
Благодарил (а): 5 раз
Контактная информация:

Re: Советы по программированию на LabVIEW

Сообщение nae »

dadreamer писал(а): 01 сен 2022, 11:07
nae писал(а): 31 авг 2022, 18:53говорит, что в заголовке описаны две функции, а в длл их нет
В хэдере явно видна только одна функция - Start (по логике должна быть ещё Stop хотя бы, либо же Start может и стопить, если передать NULL в качестве rwer, например). А из самой DLL какие функции экспортируются? Поглядите через Dependency Walker или TC (Lister). Если DLL специально была разработана для связки с :labview: и с этой камерой, то логично именно её использовать. Если камера поддерживает дрова IMAQdx, то можно попытаться увидеть её через MAX и при успехе дальше использовать VDM. Если не поддерживает, то остаются только сторонние библиотеки. Это на вопрос о том, как работать с USB-камерами.

Ещё, общая рекомендация - настраивать CLFN "вручную", не используя мастер импорта, т.к. он часто не может корректно распарсить типы данных и вложенные конструкции.
Т.е. очевидно, что этот хидер для этих dll не подходит и надо искать какой-то другой...
Аватара пользователя
dadreamer

Activity Professionalism Автор
professor
professor
Сообщения: 3926
Зарегистрирован: 17 фев 2013, 16:33
Награды: 4
Версия LabVIEW: 2.5 — 2022
Благодарил (а): 11 раз
Поблагодарили: 126 раз
Контактная информация:

Re: Советы по программированию на LabVIEW

Сообщение dadreamer »

nae писал(а): 01 сен 2022, 11:31Т.е. очевидно, что этот хидер для этих dll не подходит и надо искать какой-то другой...
Нужно внятное описание функций внутри библиотеки. Хэдер по большому счёту и не нужен. Если функций там немного, быстрее будет настроить CLF Nodes, чем обучать встроенный мастер :labview: . Судя по тому, что функция Start принимает LVUserEventRef, используется примерно вот такая архитектура: либа принимает данные от API камеры и пересылает в :labview: с помощью PostLVUserEvent, в :labview: нужно принимать UE (кадры) внутри Event-структуры. Как минимум важно знать тип UE, чтобы разобрать полученные данные.
Аватара пользователя
nae
user
user
Сообщения: 79
Зарегистрирован: 20 мар 2014, 14:21
Версия LabVIEW: 15
Откуда: Новосибирск
Благодарил (а): 5 раз
Контактная информация:

Re: Советы по программированию на LabVIEW

Сообщение nae »

dadreamer писал(а): 01 сен 2022, 13:28
nae писал(а): 01 сен 2022, 11:31Т.е. очевидно, что этот хидер для этих dll не подходит и надо искать какой-то другой...
Нужно внятное описание функций внутри библиотеки. Хэдер по большому счёту и не нужен. Если функций там немного, быстрее будет настроить CLF Nodes, чем обучать встроенный мастер :labview: . Судя по тому, что функция Start принимает LVUserEventRef, используется примерно вот такая архитектура: либа принимает данные от API камеры и пересылает в :labview: с помощью PostLVUserEvent, в :labview: нужно принимать UE (кадры) внутри Event-структуры. Как минимум важно знать тип UE, чтобы разобрать полученные данные.
В ридми на диске с дровами написано такое
"
For Windows Developer

1.Please check files in the SDK directory.

2.MIIDshowSetup.exe is the DirectShow SDK installation file. Running it will install the driver, DirectShow files, sample application and its source code.

3.MIITwainSetup.exe is the TWAIN SDK installation file. Running it will install the driver, TWAIN files, sample application and its source code.

4.nncamsdk.zip is a Native C/C++ SDK for developer, including the demo application and documents for reference.

5.UvcHamSetup.exe is Dshow and Twain for 4K camera and uvchamsdk is SDK for 4K camera.

6.UvcSamSetup.exe is Dshow and Twain for C2CMOS cameras and uvcsamsdk is SDK for C2CMOS cameras.
"

Файлы для LV я нашел в пункте 5. Выбор этой dll в окне настройки CLFN дает посмотреть, что в ней всего две функции: Start и SetLVRTModule. Первая описана в h-файле, а вторая где? (...тяжело узнавать новое...)

Файлы для си выглядят так:
inc.7z
Dll видимо для си шарп
(316.44 КБ) 56 скачиваний
можно ли по ним понять структуру данных? Это же для Си?
Ответить
  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение

Вернуться в «Для чайников»