Российский производитель и разработчик сертифицированного измерительного оборудования с 1987 года

оконный дискриминатор

 

1. Назначение

Плагин осуществляет создание трех расчетных каналов на базе двух каналов АЦП. Плагин создает три расчетных канала: один содержит сумму двух входных каналов, а два других - производные входных каналов.
  • Суммирование каналов.
  • Дифференцирование каналов.
  • Работает в реальном масштабе времени.

2. Исходный текст плагина

/* Плагин, создающий три рассчетных канала: 1. сумму двух каналов 2. производную по каналу A 2. производную по каналу B На вход плагину поступают два входных канала. Среда разработки LabWindows CVI 9.0. */ #include #include #include #include #include "..\\include\\plugin.h" static struct PluginDataInfoStr DataInfo; // структура с настройками АЦП static int device_index=0; // работаем с первым модулем АЦП static int first=1; // признак начала поступления данных (когда еще нет предистории) double *buffer; // временный буфер для расчетов double dt; // дельта по времени оцифровки АЦП double last_points[2][2]; // последние два отсчета по обоим каналам АЦП // ********************************************************************************************************* // собственно главная функция с рассчетом void __stdcall PluginDataExchange(struct PluginDataStr *data_str) { int i, j, adc_channel, index1, index2, nch, n, ch; double *ptr, *ptr1, *ptr2; // сгенерируем рассчетный канал, равный сумме двух каналов АЦП index1=DataInfo.chan_kadr_offset[device_index][DataInfo.adc_channels[0]]; // смещение в кадре первого канала index2=DataInfo.chan_kadr_offset[device_index][DataInfo.adc_channels[1]]; // смещение в кадре второго канала ptr1=&data_str->data_to_plugin[index1]; ptr2=&data_str->data_to_plugin[index2]; ptr=&data_str->data_from_plugin[device_index]; // куда складываем результат for(i=0, nch=DataInfo.nch[device_index], n=data_str->n; i < n; i++, ptr+=3, ptr1+=nch, ptr2+=nch) *ptr=*ptr1+*ptr2; // комментарий к строке выше: ptr+=3, цифра 3 поскольку плагин генерирует три канала, которые образуют // кадровую структуру // сгенерируем производные по двум каналам for(ch=0; ch < 2; ch++) { // переложим данные с текущего канала n=data_str->n; // сколько кадров пришло index1=DataInfo.chan_kadr_offset[0][DataInfo.adc_channels[ch]]; // смещение в кадре обрабатываемого канала ptr1=&data_str->data_to_plugin[index1]; if(first) // если функций вызвана первый раз с момента пуска АЦП { ptr=buffer+1; // учитываем специфику функции Difference() for(i=0; i < n; i++, ptr1 += nch) *ptr++=*ptr1; buffer[0]=buffer[1]; // производная по первой точке всегда будет ноль (не знаем, что было перед) last_points[ch][0]=buffer[n-1]; // сохраним последние два отсчета АЦП last_points[ch][1]=buffer[n]; n--; // пока что нет предистории (прошлых двух точек) } else { // предистория уже есть, поэтому первые две точки будут взяты из прошлого вызова ptr=buffer+2; for(i=0; i < n; i++, ptr1 += nch) *ptr++=*ptr1; for(i=0; i < 2; i++) buffer[i]=last_points[ch][i]; last_points[ch][0]=buffer[n]; // сохраним последние два отсчета АЦП last_points[ch][1]=buffer[1+n]; } Difference (buffer+1, n, dt, buffer[0], buffer[n+1], buffer+1); // расчет производной ptr=&data_str->data_from_plugin[1+ch]; // куда положим результат for(i=0, ptr1=buffer+1; i < n; i++, ptr+=3) *ptr=*ptr1++; // перенесем результат } data_str->n_from_plugin=n; // сколько создали кадров данных first=0; // сбросим флаг первого вызова } //********************************************************************************************************* // информационная функция void __stdcall PluginInfo(struct PluginInfoStr *p_info) { int i; // установим общие переменные strcpy(p_info->name, "Sumderiv"); // название плагина p_info->version=0x00010000; // версия 1.0 p_info->lgraph_version=0x221; // плагин разработан для версии 2.33 p_info->max_nch=2; // максимальное число входных каналов 2 p_info->min_nch=2; // минимальное число входных каналов 2 // установим названия входных каналов for(i=0; i < 2; i++) sprintf(p_info->channel_names[i], "Канал %u", i+1); p_info->parameters=0; // параметры отсутствуют } // ********************************************************************************************************* // обработка данных о параметрах модулей АЦП от LGraph void __stdcall PluginDataInfo(struct PluginDataInfoStr *d_info) { if(!d_info->devices) { strcpy(d_info->error, "Нет модуля АЦП"); return; } if(!d_info->nch[device_index]) { strcpy(d_info->error, "Не выбраны каналы АЦП"); return; } DataInfo=*d_info; dt=2000.0/DataInfo.rate[device_index]; // рассчитаем интервал между отсчетами в секундах d_info->input_kadrs_min=100; // обрабатываем за один раз не менее 100 кадров d_info->input_kadrs_max=1000000; // и не более 1e6 кадров d_info->plugin_nch=3; // число рассчетных каналов, порождаемые плагином strncpy(d_info->plugin_channel_names[0], "Сумма двух каналов", 23); // названия каналов, порождаемые плагином strncpy(d_info->plugin_channel_names[1], "Производная канала 1", 23); // названия каналов, порождаемые плагином strncpy(d_info->plugin_channel_names[2], "Производная канала 2", 23); // названия каналов, порождаемые плагином if(buffer == NULL) buffer=malloc(sizeof(double)*1000002); // выделим память под временный буфер if(buffer == NULL) { strcpy(d_info->error, "Не хватает памяти"); return; } } // визуальные элементы у плагина отсутствуют void __stdcall PluginVisualSetting(struct PluginVisualMainStr *main_visual_settings, struct PluginVisualStr p_visual[]){} /* Функция сообщает плагину, что начался сбор данных */ void __stdcall PluginStartInput(struct PluginDataStr *data_str) { first=1; // установим признак начала сбора данных } /* Функция сообщает плагину, что закончился сбор данных */ void __stdcall PluginStopInput(struct PluginDataStr *data_str) { } //********************************************************************************************************* // Функция вызываемая при загрузке - выгрузке DLL плагина int __stdcall DllMain (HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) { switch (fdwReason) { case DLL_PROCESS_ATTACH: if (InitCVIRTE (hinstDLL, 0, 0) == 0) return 0; break; case DLL_PROCESS_DETACH: if(buffer != NULL) free(buffer); if (!CVIRTEHasBeenDetached ()) CloseCVIRTE (); break; } return 1; }

Контакты

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

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

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

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