Форум: Техническая поддержка

Тема: Подружить L-Card 14-440 c Qt C++

Вы не вошли.

 Поиск | Регистрация | Вход 

20.07.2017 20:18:01
#1

Участник
Здесь с 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'

- подскажите как исправить. На форуме подымался вопрос, но подробного решения так и нет. Пожалуйста если возможно развёрнуто.

21.07.2017 18:18:24
#2

Сотрудник "Л Кард"
Здесь с 24.04.2014
Сообщений: 1,478

Re: Подружить L-Card 14-440 c Qt C++

1.

...использую компилятор WinGW...

Надеюсь это опечатка и имеется в виду MinGW.

2. Попробуйте в своём проекте задействовать .lib файл из архива lusbapi_mingw.zip

25.07.2017 12:56:37
#3

Участник
Здесь с 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;
  // пока откытого файла нет sad
  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 не срабатывает.

25.07.2017 19:11:34
#4

Сотрудник "Л Кард"
Здесь с 24.04.2014
Сообщений: 1,478

Re: Подружить L-Card 14-440 c Qt C++

1.

отклика нет, - не if не else не срабатывает

Вот это место совсем непонятно. Получается, что программа зависла на выполнении CreateLInstance и не дошла до строчки  с проверкой if(!pModule)?
2. По хорошему, перед вызовом CreateLInstance() следует проверить версию используемой Lusbapi.dll (как это делается в штатном примере, откуда Вы взяли исходный код). Было бы полезно узнать, как отрабатывается вызов функции GetDllVersion().

26.07.2017 07:16:59
#5

Участник
Здесь с 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++.

26.07.2017 07:21:49
#6

Участник
Здесь с 20.07.2017
Сообщений: 15

Re: Подружить L-Card 14-440 c Qt C++

Что бы не быть голословным, по поводу драйверов. Запущенный проект с Вашего сайта.
http://images.vfl.ru/ii/1501042573/517c … 035626.jpg

26.07.2017 07:22:43
#7

Участник
Здесь с 20.07.2017
Сообщений: 15

Re: Подружить L-Card 14-440 c Qt C++

Просто запущен модуль без датчиков.

26.07.2017 16:56:37
#8

Сотрудник "Л Кард"
Здесь с 24.04.2014
Сообщений: 1,478

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

31.07.2017 14:23:34
#9

Участник
Здесь с 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
- и всё запускается.....

26.04.2018 11:32:57
#10

Участник
Здесь с 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++
где может быть ошибка?

26.04.2018 12:48:17
#11

Участник
Здесь с 20.07.2017
Сообщений: 15

Re: Подружить L-Card 14-440 c Qt C++

- решил проблему, вот таким способом, сразу  скажу что система 64бит windows 10 компилятор WinGW 32bit.
добавляем инклуд:

#include <qstring.h>

и делаем путь через 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");
26.04.2018 13:10:20
#12

Участник
Здесь с 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 можно же пропустить кусок сбора данных, у Вас получается наполняется буфер - выгружается он, и ожидания его записи, после ждёте следующего куска, но вот в момент ожидания можно пропустить порцию данных...

26.04.2018 16:39:23
#13

Сотрудник "Л Кард"
Здесь с 24.04.2014
Сообщений: 1,478

Re: Подружить L-Card 14-440 c Qt C++

1. Для начала давайте прикинем сколько времени занимает сбор одного ReadData() при Ваших параметрах. И как это время соотносится с используемыми Sleep'ами.
2. Использование именно WaitForSingleObject() бывает иногда не очень удобным.  Поскольку эта функция не возвращает управление ровно до тех пор пока не насобирает заданное кол-во данных или не произойдёт таймаут.

01.06.2018 11:12:58
#14

Участник
Здесь с 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++. У вас не могу найти примера чтения готового файла и отправки данных в массив.

01.06.2018 11:21:24
#15

Участник
Здесь с 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()

- очень большая избыточность. Буду очень благодарен если объясните механизм сохранения особенно с привязкой к кодингу.

Контакты

Адрес: 117105, Москва, Варшавское шоссе, д. 5, корп. 4, стр. 2

Многоканальный телефон:
+7 (495) 785-95-25
Факс: +7 (495) 785-95-14

Отдел продаж: sale@lcard.ru
Техническая поддержка: support@lcard.ru

Время работы: с 9-00 до 19-00 мск