|
- Участник
- Здесь с 20.07.2017
- Сообщений: 15
|
Подружить L-Card 14-440 c Qt C++
День добрый, пытаюсь выдернуть данные из АЦП, для теста создаю в QT c++ проект консольный - и прикручиваю: #include <stdio.h> #include <stdarg.h> #include <conio.h> #include <ctype.h> #include "Lusbapi.h" как полагается кидаю в проект: Lusbapi.h LusbapiTypes.h и использую компилятор WinGW и выскакивает ошибка при сборке: D:\L-card\untitled2\main.cpp:37: ошибка: undefined reference to `GetDllVersion@0' D:\L-card\untitled2\main.cpp:44: ошибка: undefined reference to `CreateLInstance@4' - подскажите как исправить. На форуме подымался вопрос, но подробного решения так и нет. Пожалуйста если возможно развёрнуто.
|
|
- Сотрудник "Л Кард"
- Здесь с 24.04.2014
- Сообщений: 1,488
|
Re: Подружить L-Card 14-440 c Qt C++
1. ...использую компилятор WinGW...
Надеюсь это опечатка и имеется в виду MinGW. 2. Попробуйте в своём проекте задействовать .lib файл из архива lusbapi_mingw.zip
|
|
- Участник
- Здесь с 20.07.2017
- Сообщений: 15
|
Re: Подружить L-Card 14-440 c Qt C++
Да, там была опечатка. Попробовал задействовать, задействовал следующим образом. В untitled2.pro добавил код: QT += core QT -= gui CONFIG += c++11 TARGET = untitled2 CONFIG += console CONFIG -= app_bundle TEMPLATE = app SOURCES += main.cpp LIBS += "D:/Lesoons/2.8/untitled2/lusbapi.lib" добавлена в конце, тем самым ушла ошибка. Но вот, есть пример реализации: e14_metr скачал с Вашего ресурса, работает - там уже готовое решение, скомпилированное, что показывает - что модуль работает. Но вот вернёмся к тексту программы. Пробую просто посмотреть отклик модуля: #include <stdio.h> #include <conio.h> #include "Lusbapi.h" #include <iostream> // идентификатор файла HANDLE hFile; // идентификатор потока сбора данных HANDLE hReadThread; DWORD ReadTid; // версия библиотеки DWORD DllVersion; // указатель на интерфейс модуля ILE440 *pModule; // дескриптор устройства HANDLE ModuleHandle; // название модуля char ModuleName[7]; // скорость работы шины USB BYTE UsbSpeed; // структура с полной информацией о модуле MODULE_DESCRIPTION_E440 ModuleDescription; DWORD DataStep = 256*1024; const WORD NDataBlock = 80; // буфер данных SHORT *ReadBuffer; // флажок завершения работы потока сбора данных bool IsReadThreadComplete; // номер ошибки при выполнении сбора данных WORD ReadThreadErrorNumber; // экранный счетчик-индикатор DWORD Counter = 0x0, OldCounter = 0xFFFFFFFF; int main() { //--------------------------------------------------------------------------------- WORD i; // сбросим флажок завершения потока ввода данных IsReadThreadComplete = false; // пока ничего не выделено под буфер данных ReadBuffer = NULL; // пока не создан поток ввода данных hReadThread = NULL; // пока откытого файла нет hFile = INVALID_HANDLE_VALUE; // сбросим флаг ошибок потока ввода данных ReadThreadErrorNumber = 0x0; std::cout<<"*******************************"<<"\n"; std::cout<<"Module E14-440 "<<"\n"; std::cout<<"Console example for ADC Stream "<<"\n"; std::cout<<"*******************************"<<"\n"; // попробуем получить указатель на интерфейс pModule = static_cast<ILE440 *>(CreateLInstance("e440")); if(!pModule){ std::cout<<" Module Interface --> Bad"<<"\n"; }else{ std::cout<<" Module Interface --> OK"<<"\n"; } //--------------------------------------------------------------------------------- return 0; } отклика нет, - не if не else не срабатывает.
|
|
- Сотрудник "Л Кард"
- Здесь с 24.04.2014
- Сообщений: 1,488
|
Re: Подружить L-Card 14-440 c Qt C++
1. отклика нет, - не if не else не срабатывает
Вот это место совсем непонятно. Получается, что программа зависла на выполнении CreateLInstance и не дошла до строчки с проверкой if(!pModule)? 2. По хорошему, перед вызовом CreateLInstance() следует проверить версию используемой Lusbapi.dll (как это делается в штатном примере, откуда Вы взяли исходный код). Было бы полезно узнать, как отрабатывается вызов функции GetDllVersion().
|
|
- Участник
- Здесь с 20.07.2017
- Сообщений: 15
|
Re: Подружить L-Card 14-440 c Qt C++
Я сам понять не могу, по какой причине – нет отклика. С другой стороны, может у Вас есть возможность выложить пример реализации на Qt в эту ветку. Если вы создаёте консольный проект, он состоит из двух частей .pro файла с настройками, и .cpp где происходит работа. Теперь, - скажите всё же, как вы подключаете библиотеку lusbapi.lib – я так понять и не могу. Есть два способа: 1. Вый способ – на проекте-> добавить библиотеку. Тут можно выбирать, я же иду как «Внешняя», галочки на Windows – и указываем файл библиотеки. Суффикс для отладки оставляем. Пытаемся стартонуть: :-1: ошибка: cannot find -llusbapid collect2.exe:-1: ошибка: error: ld returned 1 exit status - и вот что получаем. 2. Способ – пишем ручками, LIBS += "D:/Lesoons/2.8/untitled2/lusbapi.lib" как я вам и показывал. И тогда ошибка исчезает, но отклика нет вообще от приложения. Поэтому я Вас и прошу выложить как всё же ВЫ подключаете библиотеку? Или .pro файл где происходит подключение. Далее, что криво стоят драйвера – отваливается проблема, т.к приложение e14_metr работает. Едем дальше, что я использую, т.к QT c++ то нам нужны как я понял 3 файла: lusbapi.lib Lusbapi.h LusbapiTypes.h - по крайне мере, на них ругается – приложение, точнее на их отсутствие. Далее реализация примера из архива: E14-440 В архиве текстовый файл: Описание директорий текущего каталога. DOC\ - документация на модуль E14-440. DSP\ - исходные тексты драйвера DSP на языке ассемблера ADSP-218x для модуля E14-440. Examples\ - директория с примерами программирования модуля E14-440 в различных средах разработки. ======================== !!!!!! Информацию о всех найденных ошибках просьба присылать по адресу !!!!!! !!!!!! tikhomir@lcard.ru ==================================================================== Так что думаю – я не с примером не пролетел. Что заметил, при реализации примеров у Вас не лежит с примерами с++ Lusbapi.h, LusbapiTypes.h – что очень странно, ведь это же примеры, в тексте примеров ссылка на эти файлы, а файлов нет в примере . Но всё же давайте попробуем отыскать эти два файла: качаем e140-console-test.zip - попробуем запустить, и реализовать пример из архива get_info.cpp, Ругается D:\Lesoons\2.9\untitled2\main.cpp:37: ошибка: undefined reference to `GetDllVersion@0' - но вот как будем подключать библиотеку, попробуем как раньше: LIBS += "D://Lesoons//2.9//untitled2//lusbapi.lib" - вот теперь ошибки нет, но само приложение молчит. Оно запускается, но реакции никакой нет. Вот часть проверки dll. /* Проверка версии Lusbapi.dll */ DWORD DLL_Ver = GetDllVersion(); if (DLL_Ver != CURRENT_VERSION_LUSBAPI) AbortProgram("Lusbapi.dll version mismatch (found %lu.%lu, need %u.%u)\n", DLL_Ver >> 16, DLL_Ver & 0xFFFF, CURRENT_VERSION_LUSBAPI >> 16, CURRENT_VERSION_LUSBAPI & 0xFFFF); Так вот, у меня предложение – что бы снять часть вопросов, давайте определимся с файлами, которые как я понял и Вы используете – так же. lusbapi.lib Lusbapi.h LusbapiTypes.h - конкретно для QT c++ какие Вы используете. После как вы подключаете lusbapi.lib – можете выложить .pro файл, там всё бкдет видно как идёт подключение при компиляторе MinGW. А в теле программы там изменений нет, что под C++ Builder или Visual Studio c++.
|
|
- Участник
- Здесь с 20.07.2017
- Сообщений: 15
|
Re: Подружить L-Card 14-440 c Qt C++
Что бы не быть голословным, по поводу драйверов. Запущенный проект с Вашего сайта. http://images.vfl.ru/ii/1501042573/517c … 035626.jpg
|
|
- Участник
- Здесь с 20.07.2017
- Сообщений: 15
|
Re: Подружить L-Card 14-440 c Qt C++
Просто запущен модуль без датчиков.
|
|
- Сотрудник "Л Кард"
- Здесь с 24.04.2014
- Сообщений: 1,488
|
Re: Подружить L-Card 14-440 c Qt C++
1. у Вас не лежит с примерами Lusbapi.lib, Lusbapi.h, LusbapiTypes.h
Эти файлы лежат в строго назначенных местах и проекты примеров знают предопределённые пути к этим файлам. 2. Консольный пример, собранный с помощью компилятора MinGW, можно скачать здесь: ftp.lcard.ru/pub/users/e440/e440demo_mingw.zip
|
|
- Участник
- Здесь с 20.07.2017
- Сообщений: 15
|
Re: Подружить L-Card 14-440 c Qt C++
Спасибо всё получилось: Опишу решение: - создаём консольный проект, кте сам код лежит кидаем: Lusbapi.dll Lusbapi.h lusbapi.lib LusbapiTypes.h далее в созданом проекте, нужно подключить lusbapi.lib, для этого в project.pro пишем: LIBS += "D:/Lesoons/3.1/untitled2/lusbapi.lib" - тут у вас, ваш путь до неё. Далее сам код, к примеру данный с 4 каналов: #include <stdio.h>
#include <conio.h>
#include <iostream>
#include "Lusbapi.h"
#include <cstring>
#include <iomanip>
#define CHANNELS_QUANTITY (0x4)
// аварийный выход из программы
void AbortProgram(char *ErrorString, bool AbortionFlag = true);
// версия библиотеки
DWORD DllVersion;
// указатель на интерфейс модуля
ILE440 *pModule;
// дескриптор устройства
HANDLE ModuleHandle;
// название модуля
char ModuleName[7];
// скорость работы шины USB
BYTE UsbSpeed;
// структура с полной информацией о модуле
MODULE_DESCRIPTION_E440 ModuleDescription;
// структура параметров работы АЦП модуля
ADC_PARS_E440 ap;
// отсчёты АЦП
SHORT AdcSample1, AdcSample2, AdcSample3, AdcSample4;
// индекс входного диапазона напряжения
const WORD InputRangeIndex = ADC_INPUT_RANGE_2500mV_E440;
//------------------------------------------------------------------------
// основная программа
//------------------------------------------------------------------------
int main()
{
//------------------------------------------------------------------------
WORD i;
// зачистим экран монитора
printf(" *********************************\n");
printf(" Module E14-440 \n");
printf(" Console example AdcSample stream \n");
printf(" *********************************\n\n");
// проверим версию используемой библиотеки Lusbapi.dll
if((DllVersion = GetDllVersion()) != CURRENT_VERSION_LUSBAPI)
{
char String[128];
sprintf(String, " Lusbapi.dll Version Error!!!\n Current: %1u.%1u. Required: %1u.%1u",
DllVersion >> 0x10, DllVersion & 0xFFFF,
CURRENT_VERSION_LUSBAPI >> 0x10, CURRENT_VERSION_LUSBAPI & 0xFFFF);
AbortProgram(String);
}
else printf(" Lusbapi.dll Version --> OK\n");
// попробуем получить указатель на интерфейс
pModule = static_cast<ILE440 *>(CreateLInstance("e440"));
if(!pModule) AbortProgram(" Module Interface --> Bad\n");
else printf(" Module Interface --> OK\n");
// попробуем обнаружить модуль E14-440 в первых MAX_VIRTUAL_SLOTS_QUANTITY_LUSBAPI виртуальных слотах
for(i = 0x0; i < MAX_VIRTUAL_SLOTS_QUANTITY_LUSBAPI; i++) if(pModule->OpenLDevice(i)) break;
// что-нибудь обнаружили?
if(i == MAX_VIRTUAL_SLOTS_QUANTITY_LUSBAPI) AbortProgram(" Can't find any module E14-440 in first 127 virtual slots!\n");
else printf(" OpenLDevice(%u) --> OK\n", i);
// попробуем прочитать дескриптор устройства
ModuleHandle = pModule->GetModuleHandle();
if(ModuleHandle == INVALID_HANDLE_VALUE) AbortProgram(" GetModuleHandle() --> Bad\n");
else printf(" GetModuleHandle() --> OK\n");
// прочитаем название модуля в обнаруженном виртуальном слоте
if(!pModule->GetModuleName(ModuleName)) AbortProgram(" GetModuleName() --> Bad\n");
else printf(" GetModuleName() --> OK\n");
// проверим, что это 'E14-440'
if(strcmp(ModuleName, "E440")) AbortProgram(" The module is not 'E14-440'\n");
else printf(" The module is 'E14-440'\n");
// попробуем получить скорость работы шины USB
if(!pModule->GetUsbSpeed(&UsbSpeed)) AbortProgram(" GetUsbSpeed() --> Bad\n");
else printf(" GetUsbSpeed() --> OK\n");
// теперь отобразим скорость работы шины USB
printf(" USB is in %s\n", UsbSpeed ? "High-Speed Mode (480 Mbit/s)" : "Full-Speed Mode (12 Mbit/s)");
// код LBIOS'а возьмём из соответствующего ресурса штатной DLL библиотеки
if(!pModule->LOAD_MODULE()) AbortProgram(" LOAD_MODULE() --> Bad\n");
else printf(" LOAD_MODULE() --> OK\n");
// проверим загрузку модуля
if(!pModule->TEST_MODULE()) AbortProgram(" TEST_MODULE() --> Bad\n");
else printf(" TEST_MODULE() --> OK\n");
// получим информацию из ППЗУ модуля
if(!pModule->GET_MODULE_DESCRIPTION(&ModuleDescription)) AbortProgram(" GET_MODULE_DESCRIPTION() --> Bad\n");
else printf(" GET_MODULE_DESCRIPTION() --> OK\n");
// получим текущие параметры работы АЦП
if(!pModule->GET_ADC_PARS(&ap)) AbortProgram(" GET_ADC_PARS() --> Bad\n");
else printf(" GET_ADC_PARS() --> OK\n");
// установим желаемые параметры работы АЦП
ap.IsCorrectionEnabled = true; // разрешим корректировку данных на уровне драйвера DSP
ap.InputMode = NO_SYNC_E440; // обычный сбор данных безо всякой синхронизации ввода
ap.ChannelsQuantity = CHANNELS_QUANTITY;// четыре активных канала
// формируем управляющую таблицу
for(i = 0x0; i < ap.ChannelsQuantity; i++)
ap.ControlTable[i] = (WORD)(i | (InputRangeIndex << 0x6));
ap.AdcRate = 100.0; // частота работы АЦП в кГц
ap.InterKadrDelay = 0.0; // межкадровая задержка в мс
ap.AdcFifoBaseAddress = 0x0; // базовый адрес FIFO буфера АЦП в DSP модуля
ap.AdcFifoLength = MAX_ADC_FIFO_SIZE_E440; // длина FIFO буфера АЦП в DSP модуля
// будем использовать фирменные калибровочные коэффициенты, которые храняться в ППЗУ модуля
for(i = 0x0; i < ADC_CALIBR_COEFS_QUANTITY_E440; i++)
{
ap.AdcOffsetCoefs[i] = ModuleDescription.Adc.OffsetCalibration[i];
ap.AdcScaleCoefs[i] = ModuleDescription.Adc.ScaleCalibration[i];
}
// передадим требуемые параметры работы АЦП в модуль
if(!pModule->SET_ADC_PARS(&ap)) AbortProgram(" SET_ADC_PARS() --> Bad\n");
else printf(" SET_ADC_PARS() --> OK\n");
// отобразим параметры модуля на экране монитора
printf(" \n\n");
printf(" Module E14-440 (S/N %s) is ready ... \n", ModuleDescription.Module.SerialNumber);
printf(" Module Info:\n");
printf(" Module Revision is '%c'\n", ModuleDescription.Module.Revision);
printf(" AVR Driver Version is %s (%s)\n", ModuleDescription.Mcu.Version.Version, ModuleDescription.Mcu.Version.Date);
printf(" LBIOS Version is %s (%s)\n", ModuleDescription.Dsp.Version.Version, ModuleDescription.Dsp.Version.Date);
printf(" Adc parameters:\n");
printf(" Data Correction is %s\n", ap.IsCorrectionEnabled ? "enabled" : "disabled");
printf(" Input Range = %6.2f Volt\n", ADC_INPUT_RANGES_E440[InputRangeIndex]);
printf("\n Press any key if you want to terminate this program...\n");
// цикл перманентного выполнения функции ADC_SAMPLE и
// отображения полученных данных на экране диплея
printf("\n\n");
printf(" ADC Channel: 1 2 3 4\n");
while(!kbhit())
{
if(!pModule->ADC_SAMPLE(&AdcSample1, (WORD)(0x00 | (InputRangeIndex << 6))))
{
printf("\n\n ADC_SAMPLE(, 0) --> Bad\n");
break;
}
else if(!pModule->ADC_SAMPLE(&AdcSample2, (WORD)(0x01 | (InputRangeIndex << 6))))
{
printf("\n\n ADC_SAMPLE(, 1) --> Bad\n");
break;
}
else if(!pModule->ADC_SAMPLE(&AdcSample3, (WORD)(0x02 | (InputRangeIndex << 6))))
{
printf("\n\n ADC_SAMPLE(, 2) --> Bad\n");
break;
}
else if(!pModule->ADC_SAMPLE(&AdcSample4, (WORD)(0x03 | (InputRangeIndex << 6))))
{
printf("\n\n ADC_SAMPLE(, 3) --> Bad\n");
break;
}
printf(" AdcSample Data (ADC code): %5d %5d %5d %5d\r", AdcSample1, AdcSample2,AdcSample3,AdcSample4);
}
// освободим интерфейс модуля
printf("\n\n");
AbortProgram(" The program was completed successfully!!!\n", false);
//------------------------------------------------------------------------
return 0;
}
//------------------------------------------------------------------------
// аварийное завершение программы
//------------------------------------------------------------------------
void AbortProgram(char *ErrorString, bool AbortionFlag)
{
// подчищаем интерфейс модуля
if(pModule)
{
// освободим интерфейс модуля
if(!pModule->ReleaseLInstance()) printf(" ReleaseLInstance() --> Bad\n");
else printf(" ReleaseLInstance() --> OK\n");
// обнулим указатель на интерфейс модуля
pModule = NULL;
}
// выводим текст сообщения
if(ErrorString) printf(ErrorString);
// прочистим очередь клавиатуры
if(kbhit()) { while(kbhit()) getch(); }
// если нужно - аварийно завершаем программу
if(AbortionFlag) exit(0x1);
// или спокойно выходим из функции
else return;
}
- теперь в папку debug - при отладке кидаем эти же файлы: Lusbapi.dll Lusbapi.h lusbapi.lib LusbapiTypes.h - и всё запускается.....
|
|
- Участник
- Здесь с 20.07.2017
- Сообщений: 15
|
Re: Подружить L-Card 14-440 c Qt C++
Добрый день в продолжении - возникла проблема, при сохранении данных: // откроем файл для записи получаемых с модуля данных
hFile = CreateFile("D:/L-CARD E14-440/Test 26.04.2018/untitled18/Test.dat", GENERIC_WRITE, 0, NULL, CREATE_ALWAYS,
FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN | FILE_FLAG_WRITE_THROUGH, NULL);
if(hFile == INVALID_HANDLE_VALUE) AbortProgram("\n Can't create file 'Test.dat'!\n");
вот этот кусок кода, вылетает ошибка: D:\L-CARD E14-440\Test 26.04.2018\untitled18\main.cpp:159: ошибка: cannot convert 'const char*' to 'LPCWSTR {aka const wchar_t*}' for argument '1' to 'void* CreateFileW(LPCWSTR, DWORD, DWORD, LPSECURITY_ATTRIBUTES, DWORD, DWORD, HANDLE)'
FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN | FILE_FLAG_WRITE_THROUGH, NULL); ^
но если вставлю (LPCWSTR) и сделаю такой код: hFile = CreateFile((LPCWSTR)"D:/L-CARD E14-440/Test 26.04.2018/untitled18/Test.dat", GENERIC_WRITE, 0, NULL, CREATE_ALWAYS,
FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN | FILE_FLAG_WRITE_THROUGH, NULL);
то всё работает но файл куда заливаются данные: 㩄䰯䌭剁⁄ㅅⴴ㐴⼰敔瑳㈠⸶㐰㈮⼸湵楴汴摥㠱启獥慤t
вот это пишет, среда QT 4.4.0 C++ где может быть ошибка?
|
|
- Участник
- Здесь с 20.07.2017
- Сообщений: 15
|
Re: Подружить L-Card 14-440 c Qt C++
- решил проблему, вот таким способом, сразу скажу что система 64бит windows 10 компилятор WinGW 32bit. добавляем инклуд: и делаем путь через QString а параметры CreateFile меняем: QString filePath = "D:\\L-CARD E14-440\\Test 26.04.2018\\untitled18\\Test.dat";
hFile = CreateFile(filePath.toStdWString().c_str(), GENERIC_READ|GENERIC_WRITE,
FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);
if(hFile == INVALID_HANDLE_VALUE) AbortProgram("\n Can't create file 'Test.dat'!\n");
|
|
- Участник
- Здесь с 20.07.2017
- Сообщений: 15
|
Re: Подружить L-Card 14-440 c Qt C++
Можно ещё вопрос по блокам сохранения данных - вот куски: // Создаём и запускаем поток сбора данных
printf(" \n");
hReadThread = CreateThread(0, 0x2000, ServiceReadThread, 0, 0, &ReadTid);
- тут сам поток и его пускаем... теперь рассмотрим сам поток: // запустим АЦП
if(pModule->START_ADC())
{
// цикл сбора данных
for(i = 0x1; i < NDataBlock; i++)
{
// сделаем запрос на очередную порцию данных
RequestNumber ^= 0x1;
if(!pModule->ReadData(&IoReq[RequestNumber])) { ReadThreadErrorNumber = 0x2; break; }
if(ReadThreadErrorNumber) break;
// ждём завершения операции сбора предыдущей порции данных
if(WaitForSingleObject(ReadOv[RequestNumber^0x1].hEvent, IoReq[RequestNumber^0x1].TimeOut) == WAIT_TIMEOUT) { ReadThreadErrorNumber = 0x3; break; }
if(ReadThreadErrorNumber) break;
// запишем полученную порцию данных в файл
if(!WriteFile( hFile, // handle to file to write to
IoReq[RequestNumber^0x1].Buffer, // pointer to data to write to file
2*DataStep, // number of bytes to write
&FileBytesWritten, // pointer to number of bytes written
NULL // pointer to structure needed for overlapped I/O
)) { ReadThreadErrorNumber = 0x4; break; }
if(ReadThreadErrorNumber) break;
else if(kbhit()) { ReadThreadErrorNumber = 0x5; break; }
else Sleep(10);
Counter++;
}
после того как в потоке выполнены все действия у Вас в коде в самом конце потока: // остановим работу АЦП
if(!pModule->STOP_ADC()) ReadThreadErrorNumber = 0x1;
// прервём возможно незавершённый асинхронный запрос на приём данных
if(!CancelIo(ModuleHandle)) { ReadThreadErrorNumber = 0x7; }
// освободим все идентификаторы событий
for(i = 0x0; i < 0x2; i++) CloseHandle(ReadOv[i].hEvent);
// небольшая задержка
Sleep(50);
// установим флажок завершения работы потока сбора данных
IsReadThreadComplete = true;
// теперь можно спокойно выходить из потока
return 0x0;
так вот - поясните зачем нужны Sleep(x) - если это поток, если он выделяется в отдельную линию инструкций выполнения и после вы в блоке main() ожидаете его окончания: // ждём окончания работы потока ввода данных
WaitForSingleObject(hReadThread, INFINITE);
// проверим была ли ошибка выполнения потока сбора данных
printf("\n\n");
if(ReadThreadErrorNumber) { AbortProgram(NULL, false); ShowThreadErrorMessage(); }
else AbortProgram(" The program was completed successfully!!!\n", false);
- в случае использования sleep можно же пропустить кусок сбора данных, у Вас получается наполняется буфер - выгружается он, и ожидания его записи, после ждёте следующего куска, но вот в момент ожидания можно пропустить порцию данных...
|
|
- Сотрудник "Л Кард"
- Здесь с 24.04.2014
- Сообщений: 1,488
|
Re: Подружить L-Card 14-440 c Qt C++
1. Для начала давайте прикинем сколько времени занимает сбор одного ReadData() при Ваших параметрах. И как это время соотносится с используемыми Sleep'ами. 2. Использование именно WaitForSingleObject() бывает иногда не очень удобным. Поскольку эта функция не возвращает управление ровно до тех пор пока не насобирает заданное кол-во данных или не произойдёт таймаут.
|
|
- Участник
- Здесь с 20.07.2017
- Сообщений: 15
|
Re: Подружить L-Card 14-440 c Qt C++
Тихомиров Сергей пишет:1. Для начала давайте прикинем сколько времени занимает сбор одного ReadData() при Ваших параметрах. И как это время соотносится с используемыми Sleep'ами. 2. Использование именно WaitForSingleObject() бывает иногда не очень удобным. Поскольку эта функция не возвращает управление ровно до тех пор пока не насобирает заданное кол-во данных или не произойдёт таймаут.
Я собираю данные по вибрации. Данные приходят пока с двух датчиков вибрации. Я собираю данные по такому пути. Создаётся два потока в программе, технический поток которому присваивается высший приоритет, он должен собирать данные и сохранять их - при этом параллельно выкидывать полученную порцию в единицу времени в массив, к второму есть доступ другим потокам. Проще говоря этот поток сохранения и передачи данных для последующей обработки. Данные собираю по вибрации, эти данные раскладываются в спектр диапазоном от 0 до 8кГц то есть нужно 2*8=16кГц частотой опрашивать, для надёжности я хочу делать с частотой 4*8=32кГц на каждый канал (пока их два и есть свобода). С массивом работает поток визуализации, по заданным параметрам в нём происходит быстрое преобразование Фурье. И сейчас начал изучать Ваши исходники и понимаю, что их довольно сложно понять - я не понимаю зачем там некоторые строки вообще. Так же проблема с куском, из инструкции: Структура файла параметров программы L-Graph I 23.04.2008 г. в нём описывается *.dat. Допустим я делаю запись согласно вашим примерам, у меня пишет всё. Я открываю программой осцилоскоп если не ошибаюсь с названием, и вижу что там всё нормально. А как открыть, скажем вогнать в массив не могу понять - среда Qt c++. У вас не могу найти примера чтения готового файла и отправки данных в массив.
|
|
- Участник
- Здесь с 20.07.2017
- Сообщений: 15
|
Re: Подружить L-Card 14-440 c Qt C++
Тихомиров Сергей пишет:1. Для начала давайте прикинем сколько времени занимает сбор одного ReadData() при Ваших параметрах. И как это время соотносится с используемыми Sleep'ами. 2. Использование именно WaitForSingleObject() бывает иногда не очень удобным. Поскольку эта функция не возвращает управление ровно до тех пор пока не насобирает заданное кол-во данных или не произойдёт таймаут.
Так же объясните механизм сохранения данных, думаю так будет да же проще. Сейчас анализирую: // новый тип восьмибайтового целого беззнакового числа
typedef unsigned __int64 QWORD;
#pragma pack(1)
// старая структура параметров записанного файла
struct OLD_PARS_OF_WRITE_FILE
{
char CodeString[20]; // 20 байт – ключ структуры "2571090,1618190"
char DeviceName[17]; // 17 байт – название изделия
char TimeString[26]; // 26 байт – число и время завершения ввода данных
WORD ChannelsMax; // 2 байта – общее число каналов для выбранной платы
WORD RealChannelsQuantity; // 2 байта – число активных (используемых) каналов
DWORD RealKadrsQuantity; // 4 байта – число собранных кадров
DWORD RealSamplesQuantity; // 4 байта – число собранных отсчетов
double TotalTime; // 8 байта – время ввода в cекундах
float AdcRate; // 4 байта – частота работы АЦП в кГц
float InterkadrDelay; // 4 байта – межкадровая задержка в млс
float ChannelRate; // 4 байта – частота сбора кадра данных в кГц
bool ActiveAdcChannelArray[32]; // 4байт * 32 – массив, каждый элемент которого
// равен нулю или единице, единичное значение
// соответствует тому, что данный вход активен
BYTE AdcChannelArray[32]; // 1байт * 32 – массив, каждый элемент которого равен
// номеру канала АЦП для соответствующего входа
BYTE AdcGainArray[32]; // 1байт * 32 – массив, каждый элемент которого
// равен индексу коэффициенту усиления (0,1,2 или 3)
BYTE IsSignalArray[32]; // 1байт * 32 – массив, каждый элемент которого равен
// нулю или единице, единичное значение соответст-
// вует тому, что данный канал был заземлен на плате
};
// новая структура параметров записанного файла
struct NEW_PARS_OF_WRITE_FILE
{
char CodeString[20]; // 20 байт – ключ структуры "2571090,1618190 A"
char DeviceName[17]; // 17 байт – название изделия
char TimeString[26]; // 26 байт – число и время завершения ввода данных
WORD ChannelsMax; // 2 байта – общее число каналов для выбранной платы
WORD RealChannelsQuantity; // 2 байта – число активных (используемых) каналов
QWORD RealKadrsQuantity; // 8 байт – число собранных кадров
QWORD RealSamplesQuantity; // 8 байт – число собранных отсчетов
long double TotalTime; // 10 байт – время ввода в cекундах
double AdcRate; // 8 байт – частота работы АЦП в кГц
double InterkadrDelay; // 8 байт – межкадровая задержка в млс
double ChannelRate; // 8 байт – частота сбора кадра данных в кГцBOOL ActiveAdcChannelArray[32]; // 4байт * 32 – массив, каждый элемент которого
// равен нулю или единице, единичное значение
// соответствует тому, что данный вход активен
BYTE AdcChannelArray[32]; // 1байт * 32 – массив, каждый элемент которого равен
// номеру канала АЦП для соответствующего входа
BYTE AdcGainArray[32]; // 1байт * 32 – массив, каждый элемент которого
// равен индексу коэффициенту усиления (0,1,2 или 3)
BYTE IsSignalArray[32]; // 1байт * 32 – массив, каждый элемент которого равен
// нулю или единице, единичное значение соответст-
// вует тому, что данный канал был заземлен на плате
};
#pragma pack()
- очень большая избыточность. Буду очень благодарен если объясните механизм сохранения особенно с привязкой к кодингу.
|