многоканальный мультиметр

 

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

Плагин реализует функцию многоканального мультиметра, работающего в реальном масштабе времени.
  • Расчет среднего, дисперсии, AC/DC значений, частоты.
  • Одновременная обработка до 8-ми каналов.
  • Работа в реальном масштабе времени и в режиме просмотра файла.
  • Устанавливаемые пользователем параметры: число обрабатываемых точек, разрядность чисел при отображении (число разрядов после запятой).

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

/* Плагин, реализующий 8-ми канальный мультиметр, работающий в реальном времени. Среда разработки LabWindows CVI 9.0. */ #include #include #include #include #include "..\\include\\plugin.h" static struct PluginDataInfoStr DataInfo; // структура с настройками АЦП static int device_index=0; // работаем с первым модулем АЦП double *buffer; // временный буфер для расчетов double *Yout; // временный буфер для расчетов double FindFRQ(double *TEMP,int N,double DFRQ); // расчет частоты // ********************************************************************************************************* // главная функция обмена данными с LGraph2 void __stdcall PluginDataExchange(struct PluginDataStr *data_str) { int i, j, adc_channel, index, ch, adc_nch, n; double mx, dx, ac, dc, f, *ptr1, *ptr; for(ch=0, adc_nch=DataInfo.nch[device_index]; ch < DataInfo.adc_nch; ch++) // цикл по числу каналов { // переложим данные с обрабатываемого канала в буфер n=data_str->n; // сколько кадров пришло index=DataInfo.chan_kadr_offset[0][DataInfo.adc_channels[ch]]; // смещение в кадре обрабатываемого канала ptr1=&data_str->data_to_plugin[index]; // указател на первый отсчет с канала for(i=0, ptr=buffer; i < n; i++, ptr1 += adc_nch) *ptr++=*ptr1; // переложим данные в x_buffer StdDev (buffer, n, &mx, &dx); // расчет среднего и дисперсии ACDCEstimator (buffer, n, &ac, &dc); // расчет AC,DC значений f=FindFRQ(buffer, n, DataInfo.rate[0]); // расчет частоты index=ch*6+1; // индекс данных текущего канала data_str->slow_data[index++]=mx; // сохраним среднее data_str->slow_data[index++]=dx; // сохраним дисперсию data_str->slow_data[index++]=ac; // сохраним AC data_str->slow_data[index++]=dc; // сохраним DC data_str->slow_data[index++]=f; // сохраним частоту в герцах } } // функция, расчитывающая частоту в герцах double FindFRQ(double *TEMP, int N, double DFRQ) { double value,d,wt,max,min,dt,mx; int imax,imin,jj; WindowConst wc={0,0}; MaxMin1D (TEMP, N, &max, &imax, &min, &imin); d= (max + min) / 2.0; for(jj= 0; jj< N; jj++) TEMP[jj]-=d; ScaledWindow (TEMP, N, 7, &wc); dt=1.0/DFRQ; AutoPowerSpectrum (TEMP, N, dt, Yout, &wt); MaxMin1D (Yout, N/2, &max, &imax, &min, &imin); Mean (Yout, N/2, &mx); if(mx == 0) return 0.0; if(max < mx*40) return 0.0; jj=PowerFrequencyEstimate (Yout, N/2, -1.0 , wc, wt, 11, &value, &d); return(value); } //********************************************************************************************************* // информационная функция void __stdcall PluginInfo(struct PluginInfoStr *p_info) { int i; // установим общие переменные strcpy(p_info->name, "Multimetr"); // название плагина p_info->version=0x00010000; // версия 1.0 p_info->lgraph_version=0x221; // плагин разработан для версии 2.33 p_info->max_nch=8; // максимальное число входных каналов, которые может обработать данный плагин 8 p_info->min_nch=1; // минимальное число входных каналов 1 // установим параметры каналов, запрашиваемые при первой инициализации плагина for(i=0; i < 8; i++) sprintf(p_info->channel_names[i], "Канал %u", i+1); p_info->parameters=2; // два параметра strcpy(p_info->parameters_names[0], "Число отсчетов для усреднения."); p_info->parameters_type[0]=L_TYPE_INT; p_info->default_parameters_int[0]=1000; p_info->min_parameters_int[0]=20; p_info->max_parameters_int[0]=10000; strcpy(p_info->parameters_names[1], "Число знаков после запятой."); p_info->parameters_type[1]=L_TYPE_INT; p_info->default_parameters_int[1]=4; p_info->min_parameters_int[1]=1; p_info->max_parameters_int[1]=10; } // ********************************************************************************************************* // обработка данных о параметрах модулей АЦП от 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; } // проверим на допустимые значения параметров if(d_info->parameters_int[0] < 20) d_info->parameters_int[0]=20; // усредняем не менее чем по 20 точек if(d_info->parameters_int[0] > 10000) d_info->parameters_int[0]=10000; // и не более чем по 10000 if(d_info->parameters_int[1] < 1) d_info->parameters_int[1]=1; if(d_info->parameters_int[1] > 10) d_info->parameters_int[1]=10; DataInfo=*d_info; // запомним параметры АЦП d_info->input_kadrs_min=d_info->input_kadrs_max=d_info->parameters_int[0]; // получаем данные по одному кадру, лишние отбрасываем if(buffer == NULL) buffer=malloc(sizeof(double)*10000); // выделим память под временный буфер if(buffer == NULL) { strcpy(d_info->error, "Не хватает памяти"); return; } if(Yout == NULL) Yout=malloc(sizeof(double)*10000); // выделим память под временный буфер if(Yout == NULL) { strcpy(d_info->error, "Не хватает памяти"); return; } } //********************************************************************************************************* // настройка визуальных элементов void __stdcall PluginVisualSetting(struct PluginVisualMainStr *main_visual_settings, struct PluginVisualStr p_visual[]) { int i, j, index; char *names[]={"MX", "DX", "AC", "DC", "F, Hz"}; // названия визуальных элементов main_visual_settings->n=DataInfo.adc_nch*6; // число визуальных элементов равно числу входных каналов main_visual_settings->plugin_height=main_visual_settings->height/2; // по высоте для плагина вполне хватит половины экрана for(i=0; i < DataInfo.adc_nch; i++) // цикл по числу входных каналов { for(j=0; j < 6; j++) { if(!j) // нарисуем номер канала { index=i*6; p_visual[index].type=L_VISUAL_TEXT; sprintf(p_visual[index].label_text, "Канал %c:", 'A'+i); // настроим графические координаты p_visual[index].top=36+30*i; // координата по вертикали p_visual[index].left=40; // координата по горизонтали continue; } // создадим элемент для вывода числа index=i*6+j; p_visual[index].type=L_VISUAL_NUMERIC; if(!i) sprintf(p_visual[index].label_text, names[j-1]); // подписываем только элементы первой строки // настроим графические координаты p_visual[index].top=30+30*i; // координата по вертикали p_visual[index].left=95+(j-1)*155; // координата по горизонтали p_visual[index].width=150; // ширина 150 пикселей p_visual[index].text_size=22; // шрифт сделаем большим p_visual[index].text_bold=1; // и жирным p_visual[index].y_precision=DataInfo.parameters_int[1]; // число знаков после запятой возьмем из параметра } } } // Функция сообщает плагину, что начался/закончился сбор данных (в данном плагине не используем) void __stdcall PluginStartInput(struct PluginDataStr *data_str) {} 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(Yout != NULL) free(Yout); if (!CVIRTEHasBeenDetached ()) CloseCVIRTE (); break; } return 1; }

Контакты

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

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

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

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