Плагин: SCADA (АСУТП) подобные элементы
1. Назначение
Плагин демонстрирует реализованные в LGraph2 SCADA (АСУТП) подобные визуальные элементы.
2. Исходный текст плагина
/*
Плагин, реализующий 8-ми канальный мультиметр, работающий в реальном времени.
Среда разработки LabWindows CVI 9.0.
*/
#include
#include
#include
#include
#include "..\\include\\plugin.h"
static struct PluginDataInfoStr DataInfo; // структура с настройками АЦП
static int device_index=0; // работаем с первым модулем АЦП
// *********************************************************************************************************
// главная функция
void __stdcall PluginDataExchange(struct PluginDataStr *data_str)
{
int i, j, adc_channel, index;
double val;
for(i=0; i < DataInfo.adc_nch; i++) // цикл по числу входных каналов
{
adc_channel=DataInfo.adc_channels[i]; // получим индекс канала АЦП
index=DataInfo.chan_kadr_offset[device_index][adc_channel]; // выясним для него смещение в кадре
val=data_str->data_to_plugin[index]; // вытащим значение отсчета АЦП
data_str->slow_data[i]=val; // переложим значение в выходной массив
}
}
//*********************************************************************************************************
// информационная функция
void __stdcall PluginInfo(struct PluginInfoStr *p_info)
{
int i, j;
char *names[]={"Число", "Термометр", "Бак", "Вертикальный слайдер", "Горизонтальный слайдер", "Циферблат", "Стрелка"};
// установим общие переменные
strcpy(p_info->name, "VisualGauges"); // название плагина
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=8; // восемь параметров
for(i=0; i < 8; i++)
{
sprintf(p_info->parameters_names[i], "Внешний вид канала %u", i+1); // название параметра
p_info->parameters_type[i]=L_TYPE_RING; // тип - список
p_info->default_parameters_int[i]=i % 6; // по умолчанию зададим разные типы элементов
for(j=0; j < 7; j++) strncpy(p_info->ring_names[i][j], names[j], 63); // заполним названия
}
}
// *********************************************************************************************************
// обработка данных о параметрах модулей АЦП от 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; }
d_info->input_kadrs_min=1; // получаем данные по одному кадру, лишние отбрасываем
DataInfo=*d_info; // запомним параметры АЦП
}
//*********************************************************************************************************
// настройка визуальных элементов
void __stdcall PluginVisualSetting(struct PluginVisualMainStr *main_visual_settings, struct PluginVisualStr p_visual[])
{
int i, horizontal_step;
int type_codes[]={L_VISUAL_NUMERIC, L_VISUAL_THERMOMETR, L_VISUAL_TANK, L_VISUAL_SLIDE_V, L_VISUAL_SLIDE_H,
L_VISUAL_GAUGE, L_VISUAL_METER};
main_visual_settings->n=DataInfo.adc_nch; // число визуальных элементов равно числу входных каналов
main_visual_settings->plugin_height=450; // по высоте для плагина вполне хватит 450 пикселей
horizontal_step=(main_visual_settings->width-60) / 4; // в одной строке размещаем 4 элемента
for(i=0; i < DataInfo.adc_nch; i++) // цикл по числу входных каналов
{
p_visual[i].type=type_codes[DataInfo.parameters_int[i]]; // тип визуального элемента определяет пользователь
sprintf(p_visual[i].label_text, "Канал %u (АЦП %u)", i+1, DataInfo.adc_channels[i]+1);
// настроим графические координаты
p_visual[i].top=(i < 4) ? 30 : (main_visual_settings->plugin_height-30)/2+20; // координата по вертикали
p_visual[i].left=(i % 4)*horizontal_step+60; // координата по горизонтали
p_visual[i].min_value=-10.0; // предполагаем, что все элементы имеют 10 вольтовую щшкалу
p_visual[i].max_value=10.0;
}
}
// Функция сообщает плагину, что начался/закончился сбор данных (в данном плагине не используем)
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 (!CVIRTEHasBeenDetached ()) CloseCVIRTE ();
break;
}
return 1;
}



