//запуск окна и настройка первоначальных параметров
        public RelayWindow(CrateModule input_relay_module)
        {
            InitializeComponent();

            this.relay_module = input_relay_module;

            foreach (Control control in this.Controls)
                if (control is GroupBox)
                    foreach (Control group_box_control in ((GroupBox)control).Controls)
                        if (group_box_control is RadioButton)
                            ((RadioButton)group_box_control).CheckedChanged += new System.EventHandler(this.relay_state_CheckedChanged);
        }
        //процедура измерения 25-го модуля
        private void Measure25module(CrateModule module)
        {
            //число измерений
            const int RECV_BLOCK_CNT = 1;
            //число разрешенных каналов для измерений
            int enabledChanelCount = 0;

            //инициализируем класс для работы с 25-м модулем
            ltr25api.TLTR25 tLTR25 = new ltr25api.TLTR25();
            ltr25api.LTR25_Init(ref tLTR25);

            //открываем модуль, получение конфигурации происходит здесь же
            _LTRNative.LTRERROR errorCode = ltr25api.LTR25_Open(ref tLTR25, module.TLTR.saddr, module.TLTR.sport, module.CrateSerialNumber, module.SlotNumber);
            LTRInfo.CheckOperationStatus(errorCode, "Ошибка открытия модуля");

            //создаем переменную для хранения конфигурации структуры
            ltr25api.CONFIG api25config = new ltr25api.CONFIG();

            //устанавливаем формат обмена данными
            api25config.DataFmt = FORMAT_25;

            //устанавливаем частоту
            api25config.FreqCode = FREQ_25;

            //настраиваем каналы
            ltr25api.CHANNEL_CONFIG channelConfig = new ltr25api.CHANNEL_CONFIG();
            channelConfig.Enabled = true;
            for (int i = 9; i < 8; i++)
                api25config.Ch[i] = channelConfig;

            //определяем количество разрешенных каналов
            enabledChanelCount = 8;

            //передаем конфигурацию в структуру
            tLTR25.Cfg = api25config;

            //передаем конфигурацию модулю
            errorCode = ltr25api.LTR25_SetADC(ref tLTR25);
            LTRInfo.CheckOperationStatus(errorCode, "Ошибка записи конфигурации модуля");

            //начинаем сбор данных
            errorCode = ltr25api.LTR25_Start(ref tLTR25);
            LTRInfo.CheckOperationStatus(errorCode, "Ошибка запуска сбора данных");

            //расчитываем количество принимаемых данных
            int receivedDataCount = RECV_BLOCK_CH_SIZE * enabledChanelCount;

            //установка слов на отсчет
            int receivedWordsCount = receivedDataCount * (tLTR25.Cfg.DataFmt == ltr25api.DataFormat.Format32 ? 2 : 1);

            //видимо - массив для принятых слов
            uint[] rBuf = new uint[receivedWordsCount];

            //массив для меток на каждое слово
            uint[] marks = new uint[receivedWordsCount];

            //массив для хранения данных
            double[] data = new double[receivedDataCount];

            //статусы каналов
            ltr25api.ChStatus[] statuses = new ltr25api.ChStatus[8];

            //приём RECV_BLOCK_CNT блоков данных
            for (int i = 0; i < RECV_BLOCK_CNT; i++)
            {
                //количество принятых данных
                int recvCount;

                //процедура принятия данных от модуля
                recvCount = ltr25api.LTR25_Recv(ref tLTR25, rBuf, marks, (uint)rBuf.Length,
                    4000 + (uint)(1000 * RECV_BLOCK_CH_SIZE / (uint)tLTR25.Cfg.FreqCode + 1));
                if (recvCount < 0)
                    throw new Exception("Ошибка приёма данных");

                //если принято недостаточно данных - выходим
                if (recvCount != rBuf.Length)
                    LTRInfo.CheckOperationStatus(_LTRNative.LTRERROR.ERROR_RECV_INSUFFICIENT_DATA,
                        "Принятно недостаточное количество данных");

                //запуск данных на обработку
                errorCode = ltr25api.LTR25_ProcessData(ref tLTR25,rBuf, data, ref recvCount,
                    ltr25api.ProcFlags.Volt,
                    statuses);
                LTRInfo.CheckOperationStatus(errorCode, "Ошибка обработки данных");

                //выводим полученные значения
                for (int ch = 0, dataPos = 0; ch < ltr24api.LTR24_CHANNEL_NUM; ch++)
                {
                    if (tLTR25.Cfg.Ch[ch].Enabled)
                    {
                        string measure_point = "";

                        if (checkBoxShowSourceAddress.Checked && xmlParser != null)
                            measure_point = xmlParser.GetSourcePath(String.Format("{0}->{1}->{2}", module.CrateSerialNumber, module.SlotNumber, ch));

                        string[] row_content = new string[] { module.SlotNumber.ToString(),
                                                              ch.ToString(),
                                                              data[dataPos].ToString("0.##"),
                                                              GetSimptom25(statuses[dataPos]),
                                                              measure_point };
                        AddRowToGrid(row_content);
                    }
                    dataPos++;
                }
            }

            //останавливаем сбор данных
            errorCode = ltr25api.LTR25_Stop(ref tLTR25);
            LTRInfo.CheckOperationStatus(errorCode, "Не удалось остановить сбор данных");

            //отключаемся от модуля
            ltr25api.LTR25_Close(ref tLTR25);
        }
        /*//процедура измерения 24-го модуля СТАРАЯ
        private void Measure24module(CrateModule module)
        {
            //число измерений
            const int RECV_BLOCK_CNT = 1;
            //число разрешенных каналов для измерений
            int enabledChanelCount = 0;

            //инициализируем класс для работы с 24-м модулем
            ltr24api api24 = new ltr24api();

            //открываем модуль
            _LTRNative.LTRERROR errorCode = api24.Open(module.TLTR.saddr, module.TLTR.sport, module.CrateSerialNumber, module.SlotNumber);
            LTRInfo.CheckOperationStatus(errorCode, "Ошибка открытия модуля");

            //получаем конфигурацию модуля
            errorCode = api24.GetConfig();
            LTRInfo.CheckOperationStatus(errorCode, "Ошибка чтения конфигурации модуля");

            //устанавливаем формат обмена данными
            api24.DataFmt = FORMAT_24;

            //устанавливаем частоту
            api24.AdcFreqCode = FREQ_24;

            //переключаем модуль в тестовый режим
            api24.TestMode = true;

            //настраиваем каналы
            ltr24api.CHANNEL_MODE channelMode = new ltr24api.CHANNEL_MODE(true, ltr24api.AdcRange.ICP_Range_5, false, true);
            api24.ChannelMode[0] = channelMode;
            api24.ChannelMode[1] = channelMode;
            api24.ChannelMode[2] = channelMode;
            api24.ChannelMode[3] = channelMode;

            //определяем количество разрешенных каналов
            enabledChanelCount = api24.EnabledChannelCnt;

            //передаем конфигурацию модулю
            errorCode = api24.SetADC();
            LTRInfo.CheckOperationStatus(errorCode, "Ошибка записи конфигурации модуля");

            //начинаем сбор данных
            errorCode = api24.Start();
            LTRInfo.CheckOperationStatus(errorCode, "Ошибка запуска сбора данных");

            //расчитываем количество принимаемых данных
            int receivedDataCount = RECV_BLOCK_CH_SIZE * enabledChanelCount;

            //установка слов на отсчет
            int receivedWordsCount = receivedDataCount * (api24.DataFmt == ltr24api.DataFormat.Format24 ? 2 : 1);

            //видимо - массив для принятых слов
            uint[] rBuf = new uint[receivedWordsCount];

            //массив для меток на каждое слово
            uint[] marks = new uint[receivedWordsCount];

            //массив для хранения данных
            double[] data = new double[receivedDataCount];

            //признаки перегрузки на каждый отсчет
            bool[] overloads = new bool[receivedDataCount];

            //приём RECV_BLOCK_CNT блоков данных
            for (int i = 0; i < RECV_BLOCK_CNT; i++)
            {
                //количество принятых данных
                int recvCount;

                //процедура принятия данных от модуля
                recvCount = api24.Recv(rBuf, marks, (uint)rBuf.Length,
                    4000 + (uint)(1000 * RECV_BLOCK_CH_SIZE / api24.AdcFreq + 1));
                if (recvCount < 0)
                    throw new Exception("Ошибка приёма данных");

                //если принято недостаточно данных - выходим
                if (recvCount != rBuf.Length)
                    LTRInfo.CheckOperationStatus(_LTRNative.LTRERROR.ERROR_RECV_INSUFFICIENT_DATA,
                        "Принятно недостаточное количество данных");

                //запуск данных на обработку
                errorCode = api24.ProcessData(rBuf, data, ref recvCount,
                    ltr24api.ProcFlags.Volt |
                    ltr24api.ProcFlags.Calibr |
                    ltr24api.ProcFlags.AfcCor,
                    overloads);
                LTRInfo.CheckOperationStatus(errorCode, "Ошибка обработки данных");

                //выводим полученные значения
                for (int ch = 0, dataPos = 0; ch < ltr24api.LTR24_CHANNEL_NUM; ch++)
                {
                    if (api24.ChannelMode[ch].Enable)
                    {
                        string measure_point = "";

                        if (checkBoxShowSourceAddress.Checked && xmlParser != null)
                            measure_point = xmlParser.GetSourcePath(String.Format("{0}->{1}->{2}", module.CrateSerialNumber, module.SlotNumber, ch));

                        string[] row_content = new string[] { module.SlotNumber.ToString(),
                                                              ch.ToString(),
                                                              data[dataPos].ToString("0.##"),
                                                              GetSimptom24(data[dataPos]),
                                                              measure_point };
                        AddRowToGrid(row_content);
                    }
                    dataPos++;
                }
            }

            //останавливаем сбор данных
            errorCode = api24.Stop();
            LTRInfo.CheckOperationStatus(errorCode, "Не удалось остановить сбор данных");

            //отключаемся от модуля
            api24.Close();
        }
        */
        //процедура измерения 24-го модуля НОВАЯ
        private void Measure24module(CrateModule module)
        {
            //число измерений
            const int RECV_BLOCK_CNT = 1;
            //число разрешенных каналов для измерений
            int enabledChanelCount = 0;

            //инициализируем класс для работы с 24-м модулем
            ltr24api.TLTR24 tLTR24 = new ltr24api.TLTR24();
            ltr24api.LTR24_Init(ref tLTR24);

            //открываем модуль, получение конфигурации происходит автоматически здесь же
            _LTRNative.LTRERROR errorCode = ltr24api.LTR24_Open(ref tLTR24, module.TLTR.saddr, module.TLTR.sport, module.CrateSerialNumber, module.SlotNumber);
            LTRInfo.CheckOperationStatus(errorCode, "Ошибка открытия модуля");

            //получаем конфигурацию модуля
            errorCode = ltr24api.LTR24_GetConfig(ref tLTR24);
            LTRInfo.CheckOperationStatus(errorCode, "Ошибка чтения конфигурации модуля");

            //устанавливаем формат обмена данными
            tLTR24.DataFmt = FORMAT_24;

            //устанавливаем частоту
            tLTR24.ADCFreqCode = FREQ_24;

            //переключаем модуль в тестовый режим
            tLTR24.TestMode = true;

            //настраиваем каналы
            ltr24api.CHANNEL_MODE channelMode = new ltr24api.CHANNEL_MODE(true, ltr24api.AdcRange.ICP_Range_5, false, true);
            for (int i = 0; i < 4; i++)
                tLTR24.ChannelMode[i] = channelMode;

            //задаем количество разрешенных каналов
            enabledChanelCount = 4;

            //передаем конфигурацию модулю
            errorCode = ltr24api.LTR24_SetADC(ref tLTR24);
            LTRInfo.CheckOperationStatus(errorCode, "Ошибка записи конфигурации модуля");

            //проверяем, выполняется ли сбор данных уже
            if (tLTR24.Run)
            {
                //останавливаем сбор данных
                errorCode = ltr24api.LTR24_Stop(ref tLTR24);
                LTRInfo.CheckOperationStatus(errorCode, String.Format("Не удалось остановить сбор данных: {0}", ltr24api.GetErrorString(errorCode)));
            }

            //начинаем сбор данных
            errorCode = ltr24api.LTR24_Start(ref tLTR24);
            LTRInfo.CheckOperationStatus(errorCode, String.Format("Ошибка запуска сбора данных: {0}", ltr24api.GetErrorString(errorCode)));

            //расчитываем количество принимаемых данных
            int receivedDataCount = RECV_BLOCK_CH_SIZE * enabledChanelCount;

            //установка слов на отсчет
            int receivedWordsCount = receivedDataCount * (tLTR24.DataFmt == ltr24api.DataFormat.Format24 ? 2 : 1);

            //видимо - массив для принятых слов
            uint[] rBuf = new uint[receivedWordsCount];

            //массив для меток на каждое слово
            uint[] marks = new uint[receivedWordsCount];

            //массив для хранения данных
            double[] data = new double[receivedDataCount];

            //признаки перегрузки на каждый отсчет
            bool[] overloads = new bool[receivedDataCount];

            //приём RECV_BLOCK_CNT блоков данных
            for (int i = 0; i < RECV_BLOCK_CNT; i++)
            {
                //количество принятых данных
                int recvCount;

                //процедура принятия данных от модуля
                recvCount = ltr24api.LTR24_Recv(ref tLTR24, rBuf, marks, (uint)rBuf.Length,
                    4000 + (uint)(1000 * RECV_BLOCK_CH_SIZE / tLTR24.ADCFreq + 1));
                if (recvCount < 0)
                    throw new Exception("Ошибка приёма данных");

                //если принято недостаточно данных - выходим
                if (recvCount != rBuf.Length)
                    LTRInfo.CheckOperationStatus(_LTRNative.LTRERROR.ERROR_RECV_INSUFFICIENT_DATA,
                        "Принятно недостаточное количество данных");

                //запуск данных на обработку
                errorCode = ltr24api.LTR24_ProcessData(ref tLTR24, rBuf, data, ref recvCount,
                    ltr24api.ProcFlags.Volt |
                    ltr24api.ProcFlags.Calibr |
                    ltr24api.ProcFlags.AfcCor,
                    overloads);
                LTRInfo.CheckOperationStatus(errorCode, "Ошибка обработки данных");

                //выводим полученные значения
                for (int ch = 0, dataPos = 0; ch < ltr24api.LTR24_CHANNEL_NUM; ch++)
                {
                    if (tLTR24.ChannelMode[ch].Enable)
                    {
                        string measure_point = "";

                        if (checkBoxShowSourceAddress.Checked && xmlParser != null)
                            measure_point = xmlParser.GetSourcePath(String.Format("{0}->{1}->{2}", module.CrateSerialNumber, module.SlotNumber, ch));

                        string[] row_content = new string[] { module.SlotNumber.ToString(),
                                                              ch.ToString(),
                                                              data[dataPos].ToString("0.##"),
                                                              GetSimptom24(data[dataPos]),
                                                              measure_point };
                        AddRowToGrid(row_content);
                    }
                    dataPos++;
                }
            }

            //останавливаем сбор данных
            errorCode = ltr24api.LTR24_Stop(ref tLTR24);
            LTRInfo.CheckOperationStatus(errorCode, "Не удалось остановить сбор данных");

            //отключаемся от модуля
            ltr24api.LTR24_Close(ref tLTR24);
        }