예제 #1
0
        static int Main(string[] args)
        {
            /* LTR11_Init() вызывается уже в конструкторе */
            ltr11api hltr11 = new ltr11api();

            /* отрываем модуль. Используем упрощенный вариант функции с указанием только слота.
             * (есть вариант как с только со слотом, так и с серийным крейта и слотом
             *  + полный) */
            _LTRNative.LTRERROR err = hltr11.Open(SLOT);
            if (err != _LTRNative.LTRERROR.OK)
            {
                Console.WriteLine("Не удалось открыть модуль. Ошибка {0}: {1}",
                                  err,ltr11api.GetErrorString(err));
            }
            else
            {
                /* получение информации о модуле из flash-памяти */
                err = hltr11.GetConfig();
                if (err != _LTRNative.LTRERROR.OK)
                {
                    Console.WriteLine("Не удалось прочитать информацию о модуле. Ошибка {0}: {1}",
                                      err,ltr11api.GetErrorString(err));
                }
                else
                {
                    /* выводим информацию из hltr11.ModuleInfo */
                    Console.WriteLine("Информация о модуле: ");
                    Console.WriteLine("  Название модуля: {0}",hltr11.ModuleInfo.Name);
                    Console.WriteLine("  Серийный номер : {0}",hltr11.ModuleInfo.Serial);
                    Console.WriteLine("  Версия прошивки: {0}",hltr11.ModuleInfo.VerStr);

                    /* --------------- задание параметров работы модуля ------------ */


                    /* режим старта сбора данных - внутренний */
                    hltr11.StartADCMode = ltr11api.StartAdcModes.EXTRISE;
                    /* режим синхронизации АПЦ - внутренний */
                    hltr11.InpMode = ltr11api.InpModes.INT;
                    /* количество логических каналов - 4 */
                    hltr11.LChQnt = 4;

                    /* таблица управления логическими каналами. Для упращения сделан
                     * метод установки лог. канала,  который принимает номер логического канала и его параметры*/
                    /* диапазон - 10В, режим - дифференциальный, физический канал - 1 */
                    hltr11.SetLChannel(0,0,ltr11api.ChModes.DIFF,ltr11api.ChRanges.Range_10000MV);
                    /* диапазон - 2.5В, режим - измерение собственного нуля, физический канал - 2 */
                    hltr11.SetLChannel(1,1,ltr11api.ChModes.ZERO,ltr11api.ChRanges.Range_2500MV);
                    /* диапазон - 0.6В, режим - с общей землей, физический канал - 3 */
                    hltr11.SetLChannel(2,2,ltr11api.ChModes.COMM,ltr11api.ChRanges.Range_625MV);
                    /* диапазон - 0.156В, режим - с общей землей, физический канал - 25 */
                    hltr11.SetLChannel(3,24,ltr11api.ChModes.COMM,ltr11api.ChRanges.Range_156MV);
                    /* режим сбора данных */
                    hltr11.ADCMode = ltr11api.AdcModes.ACQ;

                    /* частота дискретизации - 400 кГц. Данный метод сам устанавливает поля
                     * делителей в классе */
                    hltr11.FindAdcFreqParams(400000);

                    err = hltr11.SetADC();
                    if (err != _LTRNative.LTRERROR.OK)
                    {
                        Console.WriteLine("Не удалось установить настройки модуля. Ошибка {0}: {1}",
                                          err,ltr11api.GetErrorString(err));
                    }
                }

                if (err == _LTRNative.LTRERROR.OK)
                {
                    int recv_data_cnt = RECV_BLOCK_CH_SIZE * hltr11.LChQnt;


                    /* запуск сбора данных */
                    err = hltr11.Start();
                    if (err != _LTRNative.LTRERROR.OK)
                    {
                        Console.WriteLine("Не удалось запустить сбор данных. Ошибка {0}: {1}",
                                          err,ltr11api.GetErrorString(err));
                    }
                    else
                    {
                        uint[]              first_wrd = new uint[1];
                        uint[]              rbuf      = new uint[recv_data_cnt];
                        double[]            data      = new double[recv_data_cnt];
                        _LTRNative.LTRERROR stop_err;

                        /* признак того, что приняли первое слово.
                        * он же в дальнейшем используется как признак,
                        * что сейчас обрабатывается первый блок */
                        bool first_valid = false;
                        /* признак запроса на завершение работы (устанавливаем по нажатию любой клавиши) */
                        bool out_request = false;
                        uint block_cnt   = 0;

                        Console.WriteLine("Запущен сбор данных от внешнего сигнала запуска.");
                        Console.WriteLine("Ожидается приход первых данных от модуля. Для выхода нажмите любую клавишу");

                        /* Реально сбор данных начнется только по фронту сигнала на входе START.
                         * Единственным признаком, что сигнал пришел и модуль начал сбирать данные,
                         * является собственно наличие данных на прием (начало поступления данных).
                         * Время прихода первого блока при внешенм старте мы не можем знать, более того,
                         * независимо от использованного таймаута, мы не можем быть уверены, что примем
                         * первый блок целиком (так как начало приема блока может произойти почти на
                         * истечении таймаута, указанного в Recv()), т.е. его в любом случае может
                         * понадобится принимать за два раза.
                         * В примере мы ждем прихода одного первого слова, чтобы убедиться, что сбор
                         * начался. До реального начала прихода данных Recv() будет возвращать 0.
                         * После приема первого слова надо будет принять остаток блока и соединить с первым словом */
                        while (!out_request && !first_valid && (err == _LTRNative.LTRERROR.OK))
                        {
                            int rcvd_cnt = hltr11.Recv(first_wrd,1,100);
                            if (rcvd_cnt < 0)
                            {
                                err = (_LTRNative.LTRERROR)rcvd_cnt;
                                Console.WriteLine("Ошибка приема данных. Ошибка {0}: {1}",
                                                  err,ltr11api.GetErrorString(err));
                            }
                            else if (rcvd_cnt != 0)
                            {
                                /* приняли первое слово */
                                first_valid = true;
                                Console.WriteLine("Принято первого слово!");
                            }
                            else if (Console.KeyAvailable)
                            {
                                /* прерываем ожидание по произвольной клавише */
                                out_request = true;
                            }
                        }

                        while (!out_request && (err == _LTRNative.LTRERROR.OK))
                        {
                            int rcv_cnt;
                            /* в таймауте учитываем время выполнения самого преобразования*/
                            uint tout = RECV_TOUT + (uint)(RECV_BLOCK_CH_SIZE / hltr11.ChRate + 1);
                            /* если принимаем остаток первого блока, то 1-ое слово мы уже приняли => размер на 1 меньше */
                            int rcv_request = first_valid ? rbuf.Length - 1 : rbuf.Length;
                            /* прием необработанных слов. есть варинант с tmark и без него для удобства */
                            rcv_cnt = hltr11.Recv(rbuf,(uint)rcv_request,tout);

                            /* значение меньше 0 => код ошибки */
                            if (rcv_cnt < 0)
                            {
                                err = (_LTRNative.LTRERROR)rcv_cnt;
                                Console.WriteLine("Ошибка приема данных. Ошибка {0}: {1}",
                                                  err,ltr11api.GetErrorString(err));
                            }
                            else if (rcv_cnt != rcv_request)
                            {
                                err = _LTRNative.LTRERROR.ERROR_RECV_INSUFFICIENT_DATA;
                                Console.WriteLine("Приняли недостаточно данных: запрашивали {0}, приняли {1}",
                                                  rbuf.Length,rcv_cnt);
                            }
                            else
                            {
                                /* для первого блока объединяем принятый массив с первым словом -
                                 * сдвигаем его на 1 элемент вправо и на место первого элемента
                                 * записываем ранее принятое слово */
                                if (first_valid)
                                {
                                    Array.Copy(rbuf,0,rbuf,1,rcv_request);
                                    rbuf[0] = first_wrd[0];

                                    /* т.к. first_valid мы также используем для отличия
                                     * дочитывания первого блока, от остальных, то
                                     * сбрасываем его тут, чтобы выполнять
                                     * прием остальных блоков обычным образом */
                                    first_valid = false;
                                }

                                err = hltr11.ProcessData(rbuf,data,ref rcv_cnt,true,true);
                                if (err != _LTRNative.LTRERROR.OK)
                                {
                                    Console.WriteLine("Ошибка обработки данных. Ошибка {0}: {1}",
                                                      err,ltr11api.GetErrorString(err));
                                }
                                else
                                {
                                    /* при успешной обработке для примера выводим по одному значению
                                     * для каждого канала */
                                    Console.Write("Блок {0}.",block_cnt + 1);
                                    for (int ch = 0; ch < hltr11.LChQnt; ch++)
                                    {
                                        /* если все ок - выводим значение (для примера только первое) */
                                        Console.Write(" {1}",ch + 1,data[ch].ToString("F7"));
                                        if (ch == (hltr11.LChQnt - 1))
                                        {
                                            Console.WriteLine("");
                                        }
                                        else
                                        {
                                            Console.Write(", ");
                                        }
                                    }
                                    block_cnt++;
                                }
                            }

                            if (Console.KeyAvailable)
                            {
                                /* прерываем ожидание по произвольной клавише */
                                out_request = true;
                            }
                        }

                        /* останавливаем сбор данных */
                        stop_err = hltr11.Stop();
                        if (stop_err != _LTRNative.LTRERROR.OK)
                        {
                            Console.WriteLine("Не удалось остановить сбор данных. Ошибка {0}: {1}",
                                              stop_err,ltr11api.GetErrorString(stop_err));
                            if (err == _LTRNative.LTRERROR.OK)
                            {
                                err = stop_err;
                            }
                        }
                    }
                }
            }

            /* закрываем соединение */
            if (hltr11.IsOpened() == _LTRNative.LTRERROR.OK)
            {
                hltr11.Close();
            }

            return((int)err);
        }
예제 #2
0
        static int Main(string[] args)
        {
            /* LTR11_Init() вызывается уже в конструкторе */
            ltr11api hltr11 = new ltr11api();

            /* отрываем модуль. Используем упрощенный вариант функции с указанием только слота.
             * (есть вариант как с только со слотом, так и с серийным крейта и слотом
             *  + полный) */
            _LTRNative.LTRERROR err = hltr11.Open(SLOT);
            if (err != _LTRNative.LTRERROR.OK)
            {
                Console.WriteLine("Не удалось открыть модуль. Ошибка {0}: {1}",
                                  err,ltr11api.GetErrorString(err));
            }
            else
            {
                /* получение информации о модуле из flash-памяти */
                err = hltr11.GetConfig();
                if (err != _LTRNative.LTRERROR.OK)
                {
                    Console.WriteLine("Не удалось прочитать информацию о модуле. Ошибка {0}: {1}",
                                      err,ltr11api.GetErrorString(err));
                }
                else
                {
                    /* выводим информацию из hltr11.ModuleInfo */
                    Console.WriteLine("Информация о модуле: ");
                    Console.WriteLine("  Название модуля: {0}",hltr11.ModuleInfo.Name);
                    Console.WriteLine("  Серийный номер : {0}",hltr11.ModuleInfo.Serial);
                    Console.WriteLine("  Версия прошивки: {0}",hltr11.ModuleInfo.VerStr);

                    /* --------------- задание параметров работы модуля ------------ */


                    /* режим старта сбора данных - внутренний */
                    hltr11.StartADCMode = ltr11api.StartAdcModes.INT;
                    /* режим синхронизации АПЦ - внутренний */
                    hltr11.InpMode = ltr11api.InpModes.INT;
                    /* количество логических каналов - 4 */
                    hltr11.LChQnt = 4;

                    /* таблица управления логическими каналами. Для упращения сделан
                     * метод установки лог. канала,  который принимает номер логического канала и его параметры*/
                    /* диапазон - 10В, режим - дифференциальный, физический канал - 1 */
                    hltr11.SetLChannel(0,0,ltr11api.ChModes.DIFF,ltr11api.ChRanges.Range_10000MV);
                    /* диапазон - 2.5В, режим - измерение собственного нуля, физический канал - 2 */
                    hltr11.SetLChannel(1,1,ltr11api.ChModes.ZERO,ltr11api.ChRanges.Range_2500MV);
                    /* диапазон - 0.6В, режим - с общей землей, физический канал - 3 */
                    hltr11.SetLChannel(2,2,ltr11api.ChModes.COMM,ltr11api.ChRanges.Range_625MV);
                    /* диапазон - 0.156В, режим - с общей землей, физический канал - 25 */
                    hltr11.SetLChannel(3,24,ltr11api.ChModes.COMM,ltr11api.ChRanges.Range_156MV);
                    /* режим сбора данных */
                    hltr11.ADCMode = ltr11api.AdcModes.ACQ;

                    /* частота дискретизации - 400 кГц. Данный метод сам устанавливает поля
                     * делителей в классе */
                    hltr11.FindAdcFreqParams(400000);

                    err = hltr11.SetADC();
                    if (err != _LTRNative.LTRERROR.OK)
                    {
                        Console.WriteLine("Не удалось установить настройки модуля. Ошибка {0}: {1}",
                                          err,ltr11api.GetErrorString(err));
                    }
                }

                if (err == _LTRNative.LTRERROR.OK)
                {
                    int recv_data_cnt = RECV_BLOCK_CH_SIZE * hltr11.LChQnt;

                    uint[]   rbuf = new uint[recv_data_cnt];
                    double[] data = new double[recv_data_cnt];

                    /* запуск сбора данных */
                    err = hltr11.Start();
                    if (err != _LTRNative.LTRERROR.OK)
                    {
                        Console.WriteLine("Не удалось запустить сбор данных. Ошибка {0}: {1}",
                                          err,ltr11api.GetErrorString(err));
                    }
                    else
                    {
                        _LTRNative.LTRERROR stop_err;
                        for (int i = 0; (i < RECV_BLOCK_CNT) &&
                             (err == _LTRNative.LTRERROR.OK); i++)
                        {
                            int rcv_cnt;
                            /* в таймауте учитываем время выполнения самого преобразования*/
                            uint tout = RECV_TOUT + (uint)(RECV_BLOCK_CH_SIZE / hltr11.ChRate + 1);
                            /* прием необработанных слов. есть варинант с tmark и без него для удобства */
                            rcv_cnt = hltr11.Recv(rbuf,(uint)rbuf.Length,tout);

                            /* значение меньше 0 => код ошибки */
                            if (rcv_cnt < 0)
                            {
                                err = (_LTRNative.LTRERROR)rcv_cnt;
                                Console.WriteLine("Ошибка приема данных. Ошибка {0}: {1}",
                                                  err,ltr11api.GetErrorString(err));
                            }
                            else if (rcv_cnt != rbuf.Length)
                            {
                                err = _LTRNative.LTRERROR.ERROR_RECV_INSUFFICIENT_DATA;
                                Console.WriteLine("Приняли недостаточно данных: запрашивали {0}, приняли {1}",
                                                  rbuf.Length,rcv_cnt);
                            }
                            else
                            {
                                err = hltr11.ProcessData(rbuf,data,ref rcv_cnt,true,true);
                                if (err != _LTRNative.LTRERROR.OK)
                                {
                                    Console.WriteLine("Ошибка обработки данных. Ошибка {0}: {1}",
                                                      err,ltr11api.GetErrorString(err));
                                }
                                else
                                {
                                    /* при успешной обработке для примера выводим по одному значению
                                     * для каждого канала */
                                    Console.Write("Блок {0}.",i + 1);
                                    for (int ch = 0; ch < hltr11.LChQnt; ch++)
                                    {
                                        /* если все ок - выводим значение (для примера только первое) */
                                        Console.Write(" {1}",ch + 1,data[ch].ToString("F7"));
                                        if (ch == (hltr11.LChQnt - 1))
                                        {
                                            Console.WriteLine("");
                                        }
                                        else
                                        {
                                            Console.Write(", ");
                                        }
                                    }
                                }
                            }
                        }

                        /* останавливаем сбор данных */
                        stop_err = hltr11.Stop();
                        if (stop_err != _LTRNative.LTRERROR.OK)
                        {
                            Console.WriteLine("Не удалось остановить сбор данных. Ошибка {0}: {1}",
                                              stop_err,ltr11api.GetErrorString(stop_err));
                            if (err == _LTRNative.LTRERROR.OK)
                            {
                                err = stop_err;
                            }
                        }
                    }
                }
            }

            /* закрываем соединение */
            if (hltr11.IsOpened() == _LTRNative.LTRERROR.OK)
            {
                hltr11.Close();
            }

            return((int)err);
        }
예제 #3
0
        static int Main(string[] args)
        {
            _LTRNative.LTRERROR err;

            /* Для настройки генерации метки старт по внешнему сигналу необходимо
             * установить соединение с крейтом и изменить его настройки */
            ltrcrate crate = new ltrcrate();

            /* устанавливаем соединение. в случае нескольких
             * крейтов необходимо указать серийный номер крейта, с которым работаем,
             * иначе установка соединения с первым найденным */
            err = crate.Open();
            if (err != _LTRNative.LTRERROR.OK)
            {
                Console.WriteLine("Не удалось установить соединение с крейтом. Ошибка {0}: {1}",
                                  err,ltrcrate.GetErrorString(err));
            }
            else
            {
                /* В примере настраиваем генерацию метки старт по фронту сигнала
                 * на входе разъема синхронизации крейта DIGIN1 */
                err = crate.MakeStartMark(_LTRNative.en_LTR_MarkMode.LTR_MARK_EXT_DIGIN1_RISE);
                if (err != _LTRNative.LTRERROR.OK)
                {
                    Console.WriteLine("Не удалось настроить генерацию метки СТАРТ. Ошибка {0}: {1}",
                                      err,ltrcrate.GetErrorString(err));
                }
                else
                {
                    Console.WriteLine("Генерация метки старт была настроена успешно");
                }

                /* соезинение с крейтом больше не нужно */
                crate.Close();
            }

            /* LTR11_Init() вызывается уже в конструкторе */
            ltr11api hltr11 = new ltr11api();

            /* отрываем модуль. Используем упрощенный вариант функции с указанием только слота.
             * (есть вариант как с только со слотом, так и с серийным крейта и слотом
             *  + полный) */
            err = hltr11.Open(SLOT);
            if (err != _LTRNative.LTRERROR.OK)
            {
                Console.WriteLine("Не удалось открыть модуль. Ошибка {0}: {1}",
                                  err,ltr11api.GetErrorString(err));
            }
            else
            {
                /* получение информации о модуле из flash-памяти */
                err = hltr11.GetConfig();
                if (err != _LTRNative.LTRERROR.OK)
                {
                    Console.WriteLine("Не удалось прочитать информацию о модуле. Ошибка {0}: {1}",
                                      err,ltr11api.GetErrorString(err));
                }
                else
                {
                    /* выводим информацию из hltr11.ModuleInfo */
                    Console.WriteLine("Информация о модуле: ");
                    Console.WriteLine("  Название модуля: {0}",hltr11.ModuleInfo.Name);
                    Console.WriteLine("  Серийный номер : {0}",hltr11.ModuleInfo.Serial);
                    Console.WriteLine("  Версия прошивки: {0}",hltr11.ModuleInfo.VerStr);

                    /* --------------- задание параметров работы модуля ------------ */


                    /* режим старта сбора данных - внутренний */
                    hltr11.StartADCMode = ltr11api.StartAdcModes.INT;
                    /* режим синхронизации АПЦ - внутренний */
                    hltr11.InpMode = ltr11api.InpModes.INT;
                    /* количество логических каналов - 4 */
                    hltr11.LChQnt = 3;

                    /* таблица управления логическими каналами. Для упращения сделан
                     * метод установки лог. канала,  который принимает номер логического канала и его параметры*/
                    /* диапазон - 10В, режим - дифференциальный, физический канал - 1 */
                    hltr11.SetLChannel(0,0,ltr11api.ChModes.DIFF,ltr11api.ChRanges.Range_10000MV);
                    /* диапазон - 2.5В, режим - измерение собственного нуля, физический канал - 2 */
                    hltr11.SetLChannel(1,1,ltr11api.ChModes.ZERO,ltr11api.ChRanges.Range_2500MV);
                    /* диапазон - 0.6В, режим - с общей землей, физический канал - 3 */
                    hltr11.SetLChannel(2,2,ltr11api.ChModes.COMM,ltr11api.ChRanges.Range_625MV);
                    /* диапазон - 0.156В, режим - с общей землей, физический канал - 25 */
                    //hltr11.SetLChannel(3, 24, ltr11api.ChModes.COMM, ltr11api.ChRanges.Range_156MV);
                    /* режим сбора данных */
                    hltr11.ADCMode = ltr11api.AdcModes.ACQ;

                    /* частота дискретизации - 400 кГц. Данный метод сам устанавливает поля
                     * делителей в классе */
                    hltr11.FindAdcFreqParams(400000);

                    err = hltr11.SetADC();
                    if (err != _LTRNative.LTRERROR.OK)
                    {
                        Console.WriteLine("Не удалось установить настройки модуля. Ошибка {0}: {1}",
                                          err,ltr11api.GetErrorString(err));
                    }
                }

                if (err == _LTRNative.LTRERROR.OK)
                {
                    /* запуск сбора данных */
                    err = hltr11.Start();
                    if (err != _LTRNative.LTRERROR.OK)
                    {
                        Console.WriteLine("Не удалось запустить сбор данных. Ошибка {0}: {1}",
                                          err,ltr11api.GetErrorString(err));
                    }
                    else
                    {
                        int  block_cnt   = 0;
                        bool out_request = false;

                        const int TMP_BUF_SIZE = 4096;
                        uint[]    tmp_buf      = new uint[TMP_BUF_SIZE];
                        uint[]    mark_buf     = new uint[TMP_BUF_SIZE];

                        /* Сбор данных выполняем всегда, сохраняя данные во временный буфер,
                         * во входных данных ищем изменение значения метки старт и только
                         * отчеты после этого изменения обрабатываем */
                        while (!out_request && (err == _LTRNative.LTRERROR.OK))
                        {
                            bool   start_mark_valid = false;
                            bool   start_fnd        = false;
                            ushort start_mark       = 0; /* текущее значение метки СТАРТ */
                            uint   rem_size         = 0;

                            while (!start_fnd && !out_request && (err == _LTRNative.LTRERROR.OK))
                            {
                                /* в примере не обязательно принимать все TMP_BUF_SIZE, поэтому
                                 * можем использовать относительно небольшой таймаут.
                                 * Единственное, размер буфера не должен быть слишком маленький,
                                 * чтобы снизить нагрузку на ПК */
                                uint tout = 100;
                                /* прием необработанных слов. есть варинант с tmark и без него для удобства */
                                int rcv_cnt = hltr11.Recv(tmp_buf,mark_buf,(uint)tmp_buf.Length,tout);
                                if (rcv_cnt < 0)
                                {
                                    err = (_LTRNative.LTRERROR)rcv_cnt;
                                    Console.WriteLine("Ошибка приема данных. Ошибка {0}: {1}",
                                                      err,ltr11api.GetErrorString(err));
                                }
                                else if (rcv_cnt > 0)
                                {
                                    /* по первому отсчету сохраняем значение метки СТАРТ. Надо иметь
                                     * ввиду, что старте сбора оно не обязательно = 0, т.к. кол-во
                                     * меток старт считается от момента подключения крейта
                                     * к ПК и не сбрасывается до его отключения */
                                    if (!start_mark_valid)
                                    {
                                        start_mark       = (ushort)((mark_buf[0] >> 16) & 0xFFFF);
                                        start_mark_valid = true;
                                    }

                                    for (int i = 0; (i < rcv_cnt) && !start_fnd; i++)
                                    {
                                        /* ищем изменение метки СТАРТ */
                                        ushort cur_mark = (ushort)((mark_buf[i] >> 16) & 0xFFFF);
                                        if (cur_mark != start_mark)
                                        {
                                            start_mark = cur_mark;
                                            start_fnd  = true;
                                            rem_size   = (uint)(rcv_cnt - i);

                                            uint idx;

                                            /* если изменение метки произошло не вначале блока,
                                             * то откидываем все отсчеты, которые были до изменения
                                             * метки путем сдвига буфера */
                                            if (i != 0)
                                            {
                                                Array.Copy(tmp_buf,i,tmp_buf,0,rem_size);
                                            }

                                            /* Следует учитывать, что если у нас используется не один канал,
                                             * то изменение метки может произойти в середине кадра, а не на
                                             * границе. Для корректной обработки данных нам нужно выровнять
                                             * данные на границу кадра (чтобы первый отсчет соответствовал
                                             * первому каналу из логической таблицы). Функция SearchFirstFrame()
                                             * находит индекс начала ближайшего кадра в массиве */
                                            if (hltr11.SearchFirstFrame(tmp_buf,rem_size,out idx) == _LTRNative.LTRERROR.OK)
                                            {
                                                /* если индекс не равен нулю - то находимся в середине
                                                 * кадра и нужно отбросить остаток кадра -
                                                 * первые idx отсчетов */
                                                if (idx != 0)
                                                {
                                                    rem_size -= idx;
                                                    Array.Copy(tmp_buf,idx,tmp_buf,0,rem_size);
                                                }
                                            }
                                            else
                                            {
                                                /* если не найдено начало кадра, то значит изменение
                                                 * метки произошло в конце буфера. При корректной
                                                 * работе достаточно принять данных на один кадр
                                                 * и в нем обязательно должно быть начало */
                                                rem_size = (uint)hltr11.LChQnt;

                                                rcv_cnt = hltr11.Recv(tmp_buf,mark_buf,rem_size,RECV_TOUT);
                                                if (rcv_cnt < 0)
                                                {
                                                    err = (_LTRNative.LTRERROR)rcv_cnt;
                                                    Console.WriteLine("Ошибка приема данных. Ошибка {0}: {1}",
                                                                      err,ltr11api.GetErrorString(err));
                                                }
                                                else if (rcv_cnt != rem_size)
                                                {
                                                    err = _LTRNative.LTRERROR.ERROR_RECV_INSUFFICIENT_DATA;
                                                    Console.WriteLine("Приняли недостаточно данных: запрашивали {0}, приняли {1}",
                                                                      rem_size,rcv_cnt);
                                                }
                                                else
                                                {
                                                    err = hltr11.SearchFirstFrame(tmp_buf,rem_size,out idx);
                                                    if (err != _LTRNative.LTRERROR.OK)
                                                    {
                                                        Console.WriteLine("Не удалось найти начало кадра. Ошибка {0}: {1}",
                                                                          err,ltr11api.GetErrorString(err));
                                                    }
                                                    else if (idx != 0)
                                                    {
                                                        rem_size -= idx;
                                                        Array.Copy(tmp_buf,idx,tmp_buf,0,rem_size);
                                                    }
                                                }
                                            }
                                        }
                                    }
                                }


                                if (Console.KeyAvailable)
                                {
                                    /* прерываем ожидание по произвольной клавише */
                                    out_request = true;
                                    Console.WriteLine("Запрос завершения работы...");
                                }
                            }

                            /* если нашли изменения - допринимаем и обрабатываем блок */
                            if (start_fnd)
                            {
                                int block_data_cnt = (RECV_BLOCK_CH_SIZE * hltr11.LChQnt);

                                uint[]   rbuf = new uint[block_data_cnt];
                                double[] data = new double[block_data_cnt];

                                /* rem_size полезных отсчетов находится во временном
                                 * буфере, определяем, сколько данных нужно еще допринять,
                                 * чтобы получить целый блок */
                                int block_recv_cnt = (int)(block_data_cnt - rem_size);

                                if (block_recv_cnt > 0)
                                {
                                    uint tout = RECV_TOUT + (uint)(block_recv_cnt / hltr11.ChRate + 1);

                                    int rcv_cnt = hltr11.Recv(rbuf,(uint)block_recv_cnt,tout);
                                    /* значение меньше 0 => код ошибки */
                                    if (rcv_cnt < 0)
                                    {
                                        err = (_LTRNative.LTRERROR)rcv_cnt;
                                        Console.WriteLine("Ошибка приема данных. Ошибка {0}: {1}",
                                                          err,ltr11api.GetErrorString(err));
                                    }
                                    else if (rcv_cnt != block_recv_cnt)
                                    {
                                        err = _LTRNative.LTRERROR.ERROR_RECV_INSUFFICIENT_DATA;
                                        Console.WriteLine("Приняли недостаточно данных: запрашивали {0}, приняли {1}",
                                                          block_recv_cnt,rcv_cnt);
                                    }
                                }
                                if (err == _LTRNative.LTRERROR.OK)
                                {
                                    /* склеиваем две части в один массив -
                                     * сдвигаем принятые данные на rem_size влево
                                     * и в освободившееся место вначале копируем
                                     * действительные данные из временного буфера */
                                    if (rem_size != 0)
                                    {
                                        if (block_recv_cnt > 0)
                                        {
                                            Array.Copy(rbuf,0,rbuf,rem_size,block_recv_cnt);
                                        }
                                        Array.Copy(tmp_buf,rbuf,rem_size);
                                    }


                                    err = hltr11.ProcessData(rbuf,data,ref block_data_cnt,true,true);
                                    if (err != _LTRNative.LTRERROR.OK)
                                    {
                                        Console.WriteLine("Ошибка обработки данных. Ошибка {0}: {1}",
                                                          err,ltr11api.GetErrorString(err));
                                    }
                                    else
                                    {
                                        /* при успешной обработке для примера выводим по одному значению
                                         * для каждого канала */
                                        Console.Write("Блок {0} (СТАРТ = {1}): ",block_cnt + 1,start_mark);
                                        for (int ch = 0; ch < hltr11.LChQnt; ch++)
                                        {
                                            /* если все ок - выводим значение (для примера только первое) */
                                            Console.Write(" {1}",ch + 1,data[ch].ToString("F7"));
                                            if (ch == (hltr11.LChQnt - 1))
                                            {
                                                Console.WriteLine("");
                                            }
                                            else
                                            {
                                                Console.Write(", ");
                                            }
                                        }
                                        block_cnt++;
                                    }
                                }
                            }
                        }



                        /* останавливаем сбор данных */
                        _LTRNative.LTRERROR stop_err = hltr11.Stop();
                        if (stop_err != _LTRNative.LTRERROR.OK)
                        {
                            Console.WriteLine("Не удалось остановить сбор данных. Ошибка {0}: {1}",
                                              stop_err,ltr11api.GetErrorString(stop_err));
                            if (err == _LTRNative.LTRERROR.OK)
                            {
                                err = stop_err;
                            }
                        }
                    }
                }
            }

            /* закрываем соединение */
            if (hltr11.IsOpened() == _LTRNative.LTRERROR.OK)
            {
                hltr11.Close();
            }

            return((int)err);
        }