Форум: Техническая поддержка

Тема: LTR27 Как отследить момент получения новых значений измерений?

Вы не вошли.

 Поиск | Регистрация | Вход 

Роман Б
16.09.2020 08:15:58
#1

Гость

LTR27 Как отследить момент получения новых значений измерений?

Добрый день. Пишу программу на C# (WPF). Всё общение с LTR27 сделано в фоновом потоке. Настроил LTR27 на частоту измерений 4Гц (чтобы иметь точность измерений 16 бит), данные об измерениях должны приходить 4 раза в секунду. Вот укороченный вариант кода, который я использую:

        private void RecieveData_LTR27()
        {
            while (!break_thread)
            {
                if (ltr27 == null || ltr27.IsOpened() != _LTRNative.LTRERROR.OK)
                {
                    if (!OpenSlot()) return;//вероятно не установлены библиотеки для общения с LTR27
                }
                

                if (errSlot == _LTRNative.LTRERROR.OK)
                {
                    /* установка частоты сбора АЦП (Гц). Метод сам заполняет поле делителя */
                    ltr27.FillAdcFreqParams(adcFreq, out adcFreq);

                    errSlot = ltr27.SetConfig();
                }

                if (errSlot == _LTRNative.LTRERROR.OK)
                {
                    int recv_data_cnt = RECV_BLOCK_CH_SIZE * ltr27api.LTR27_CHANNELS_CNT;

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

                    errSlot = ltr27.ADCStart();// запуск сбора данных

                    if (errSlot == _LTRNative.LTRERROR.OK)
                        while (!break_thread && errSlot == _LTRNative.LTRERROR.OK)
                        {
                            int rcv_cnt;//количество принятых данных
                            uint[] tstamp = new uint[recv_data_cnt];

                            /* в таймауте учитываем время выполнения самого преобразования*/
                            uint tout = 1200 + (uint)(1000 * RECV_BLOCK_CH_SIZE / adcFreq + 1);
                            /* прием необработанных слов. есть варинант с tmark и без него для удобства */
                            rcv_cnt = ltr27.Recv(rbuf, (uint)rbuf.Length, tstamp, tout);

                            if (rcv_cnt > 0)
                            {
                                uint proc_cnt = (uint)rcv_cnt;
                                data = new double[recv_data_cnt];
                                bool value_type = true;//тип данных в возвращаемом массиве. false - значения в виде АЦП, представленные как double. true - физические величины.
                                errSlot = ltr27.ProcessData(rbuf, data, ref proc_cnt, true, value_type);
                                if (errSlot == _LTRNative.LTRERROR.OK)
                                {
                                    List<List<double>> channels = new List<List<double>>();//данные для четырех каналов (4 коллекции)

                                    TimeSpan cur_time = MainTimer.TimeSpanFromStart_inUI;

                                    for (int ch = 0; ch < 4; ch++)//считываем данные для каждого канала
                                    {
                                        int mezzanine_idx = ch / ltr27api.LTR27_MAZZANINE_CHANNELS_CNT;

                                        //ltr27.Mezzanine[0] - 2 десятивольтовых канала
                                        //ltr27.Mezzanine[1] - 2 одновольтовых канала
                                        if (ltr27.Mezzanine[mezzanine_idx].Name != "EMPTY")
                                        {
                                            List<double> ListData = new List<double>();//данные для одного канала (RECV_BLOCK_CH_SIZE точек измерения)

                                            if (data != null)
                                            {
                                                for (int j = 0; j < proc_cnt; j += 16) ListData.Add(data[ch + j]);

                                                channels.Add(ListData);
                                            }
                                        }
                                    }

                                    Dispatcher.BeginInvoke(System.Windows.Threading.DispatcherPriority.Normal, (ThreadStart)delegate ()
                                    {
                                        Split_AO(channels);
                                    });
                                }
                            }
                        }
                }
            }
        }

        private bool OpenSlot()
        {
            try { ltr27 = new ltr27api(); }//если на этом месте ошибка, то надо установить: ltrdll.exe, ltrd-setup.exe и ltrmanager_setup.exe
            catch (Exception ex) {
                
                return false;
            }

            errSlot = ltr27.Open(slot_Ltr27);

            if (errSlot != _LTRNative.LTRERROR.OK)
            { }
            else
            {
                /* Считываем информацию о конфигурации модуля и о мезанинах */
                errSlot = ltr27.GetConfig();
                if (errSlot != _LTRNative.LTRERROR.OK)
                { }
                else
                {
                    errSlot = ltr27.GetDescription(ltr27api.Descriptions.MODULE);

                    for (int i = 0; (i < ltr27api.LTR27_MEZZANINE_NUMBER) && (errSlot == _LTRNative.LTRERROR.OK); i++)
                        if (ltr27.Mezzanine[i].Name != "EMPTY")
                            errSlot = ltr27.GetDescription((ushort)(1 << i));
                }
            }

            return true;
        }

Проблема в том, что при циклическом считывании метод ltr27.Recv(...), как я понял, возвращает мне то, что имеется в буффере, даже если последние данные из него были считаны на предыдущей итерации. При этом время таймаута не выдерживается. Массив меток tstamp всегда содержит одни 0. Возвращаемое значение (ref) proc_cnt - всегда 16. В своей задаче мне необходимо хранить массив ранее измеренных значений с привязкой ко времени их получения. В качестве времени получения мне подойдет и системное время в Windows. Сейчас массив ранее измеренных значений у меня заполняется большим количеством дублированных данных. Как мне изменить код, чтобы добиться желаемого результата?

Роман Б
16.09.2020 09:06:04
#2

Гость

Re: LTR27 Как отследить момент получения новых значений измерений?

Пардон. Нашел ошибку в своем коде. Прошу удалить тему.

Контакты

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

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

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

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