Российский производитель и разработчик сертифицированного измерительного оборудования с 1987 года

Проблема с LTR22

Вы не вошли.

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

Санников Павел
24.03.2022 14:50:51
#1

Гость

Проблема с LTR22

Здравствуйте, возникла такая проблема. Не получается собирать данные с LTR22, получаю шум (рис. 2). Однако после того как я запускаю Lgraph2 и смотрю на данные там, а потом, не закрывая Lgraph2 запускаю свою программу всё работает (рис. 3). Еще заметил, что в первые две секунды значения с АЦП равны около -0.12 (рис. 1, Lgraph2). Это связано с буферизацией, описанной в Руководстве пользователя (пункт про функцию LTR22_Recv)?
Параметры: включен только первый канал, диапазон +-3В, частота 3472.0 Гц.
Часть программы приведена ниже, ориентировался на пример из руководства пользователя.
Спасибо.
image.jpg
image.jpg
image.jpg

// Инициализация
Ltr22::Ltr22(QObject *parent)
    : QThread(parent)
{
    settings = new Ltr22Settings;
    m_module = new TLTR22();
    m_ltr22_error = 0;
    getParams(slot);
    initModule();
}
void Ltr22::getParams(int slot) {
    m_param.slot = LTR_CC_CHNUM_MODULE1;
    m_param.serial = "";
    m_param.addr = LTRD_ADDR_DEFAULT;
    m_param.sport = LTRD_PORT_DEFAULT;
    if (slot > 0) {
        m_param.slot = slot;
    }
}
void Ltr22::initModule() {
    LTR22_GetConfig(m_module);
    LTR22_Init(m_module);
    m_ltr22_error = LTR22_Open(m_module, m_param.addr, m_param.sport,
                     m_param.serial, m_param.slot);
    if (m_ltr22_error==LTR_WARNING_MODULE_IN_USE) {
        qDebug("ltr22 уже открыт");
        m_ltr22_error = LTR_OK;
    }
    if (m_ltr22_error != LTR_OK) {
        QString status = QString("Ошибка %1").arg(m_ltr22_error);
        return;
    }
    if ((m_ltr22_error = LTR22_IsOpened(m_module)) != LTR_OK) {
        QString status = QString("Ошибка %1").arg(m_ltr22_error);
        return;
    }
    else {
        configureModule();
    }
}
void Ltr22::configureModule()
{
    m_ltr22_error = LTR22_SetFreq(m_module, true, 15);
    LTR22_SetADCChannel(m_module, 0, PlotsList::instance().plotsList.at(1).enabled);
    LTR22_SetADCChannel(m_module, 1, PlotsList::instance().plotsList.at(2).enabled);
    LTR22_SetADCChannel(m_module, 2, PlotsList::instance().plotsList.at(3).enabled);
    LTR22_SetADCChannel(m_module, 3, PlotsList::instance().plotsList.at(4).enabled);
    for (int channel = 0; channel < 4; channel++) {
        int ch = channel + 1;
        if (PlotsList::instance().plotsList.at(ch).enabled) {
            if ((m_ltr22_error = LTR22_SetADCRange(m_module, channel, LTR22_ADC_RANGE_3)) != LTR_OK) {
                QString status = QString("Ошибка %1").arg(m_ltr22_error);
            }
        }
    }
}
// Сбор данных
void Ltr22::transaction()
{
    if (m_ltr22_error != LTR_OK) {
        return;
    }
    const QMutexLocker locker(&m_mutex);
    if (!isRunning()) {
        configureModule();
        start();
    }
    else
        m_cond.wakeOne();
}
void Ltr22::run() {
    if (m_ltr22_error != LTR_OK) {
        QString status = QString("Ошибка %1").arg(m_ltr22_error);
        return;
    }
    DWORD receivedBlocks = 0;
    INT receivedDataCnt = RECV_BLOCK_CH_SIZE * channels;
    DWORD *rbuf = new DWORD[receivedDataCnt]();
    double *data = new double[receivedDataCnt]();
    if ((rbuf == nullptr) || (data == nullptr)) {
        QString status = QString("Ошибка выделения памяти");
        m_ltr22_error = LTR_ERROR_MEMORY_ALLOC;
        return;
    }
    while (m_ltr22_error==LTR_OK && !m_abort) {
        if (m_pause) {
            m_ltr22_error = LTR22_StartADC(m_module, false);
            if (m_ltr22_error != LTR_OK) {
                QString status = QString("Ошибка %1").arg(m_ltr22_error);
                delete[] rbuf;
                delete[] data;
                return;
            }
            m_pause = false;
            time = 0.0;
            receivedBlocks = 0;
            QString status = QString("Сбор данных запущен");
        }
        INT recvd;
        /* в таймауте учитываем время выполнения самого преобразования*/
        DWORD tout = RECV_TOUT;
        /* получение данных от LTR */
        recvd = LTR22_Recv(m_module, rbuf, NULL, receivedDataCnt, tout);
        /* Значение меньше нуля соответствуют коду ошибки */
        if (recvd < 0) {
            m_ltr22_error = recvd;
            QString status = QString("Ошибка приема данных. Ошибка %1").arg(m_ltr22_error);
        } else if (recvd!=receivedDataCnt) {
            QString status = QString("Принято недостаточно данных. Запрашивали %1, приняли %2")
                    .arg(receivedDataCnt).arg(recvd);
            m_ltr22_error = LTR_ERROR_RECV_INSUFFICIENT_DATA;
        } else {
            /* сохранение принятых и обработанных данных в буфере */
            m_ltr22_error = LTR22_ProcessDataEx(m_module, rbuf, data, &recvd, LTR22_PROC_FLAG_CALIBR | LTR22_PROC_FLAG_VOLT, NULL, NULL);
            if (m_ltr22_error!=LTR_OK) {
                QString status = QString("Ошибка %1").arg(m_ltr22_error);
            } else {
                /* Принимаем данные */
                receivedBlocks++;
                for (INT i = 0; i < receivedDataCnt; i++) {
                    SignalData::instance(1).append(QPointF(time, data[i]));
                    time += 1.0/3472.0;
                }
            }
        }
        if (m_pause) {
            m_mutex.lock();
            QString status = QString("Сбор данных остановлен");
            setStatus(status, 0, true);
            LTR22_StopADC(m_module);
            LTR22_ClearBuffer(m_module, true);
            m_cond.wait(&m_mutex);
            m_mutex.unlock();
        }
    }
    delete[] rbuf;
    delete[] data;
}
void Ltr22::closeModule()
{
    m_ltr22_error = LTR22_Close(m_module);
    if (m_ltr22_error != LTR_OK) {
        QString status = QString("Ошибка %1").arg(m_ltr22_error);
    }
    else {
        QString status = QString("Закрыт");
    }
}
24.03.2022 21:13:21
#2

Сотрудник "Л Кард"
Здесь с 05.04.2019
Сообщений: 571

Re: Проблема с LTR22

Здравствуйте. По программной части ответит наш программист. Я только замечу: Чтобы входы канала LTR22 находились в рабочем режиме, цепи GND, X, Y соответствующего канала должны быть подключены к источнику сигнала https://www.lcard.ru/download/ltr.pdf , п. 13.4.6.
В нерабочем режиме входа будет некорректно интерпретировать измеренное входное напряжение.
Если входы не подключены, то корректно интерпретировать измеренное напряжение будет возможно только в режиме измерения собственного нуля.

Отредактировано Инженер (24.03.2022 21:14:29)

27.03.2022 23:16:01
#3

Сотрудник "Л Кард"
Здесь с 17.04.2014
Сообщений: 1,291

Re: Проблема с LTR22

Скорее всего проблема в отсутствии в программе вызовов LTR22_SwitchMeasureADCZero и LTR22_SwitchACDCState (в приведенном участке кода их не нашел). Т.к. эти режимы не настраиваются, они сохраняют предыдущие значения (скорее всего остается включенным измерение нуля), а запуск LGraph2 приводит к их изменению. Нужно вызывать все функции настроек перед запуском.

Про первые 2 секунды, то буферизация тут не влияет. Похоже, что это связано с:

После процедуры фазировки AVR ждет 8192 сэмплов АЦП – поскольку АЦП
входит в режим автокалибровки, поэтому timeout на минимальной частоте сбора
данных (3472 сэмпла/c) может составить 2,35 с, максимальное значение
определяется пользователем.

По видимому до прихода действительных данных LGraph отображает не корректные данные.

Санников Павел
31.03.2022 12:53:52
#4

Гость

Re: Проблема с LTR22

Алексей L Card пишет:

Скорее всего проблема в отсутствии в программе вызовов LTR22_SwitchMeasureADCZero и LTR22_SwitchACDCState (в приведенном участке кода их не нашел). Т.к. эти режимы не настраиваются, они сохраняют предыдущие значения (скорее всего остается включенным измерение нуля), а запуск LGraph2 приводит к их изменению. Нужно вызывать все функции настроек перед запуском.

Про первые 2 секунды, то буферизация тут не влияет. Похоже, что это связано с:

После процедуры фазировки AVR ждет 8192 сэмплов АЦП – поскольку АЦП
входит в режим автокалибровки, поэтому timeout на минимальной частоте сбора
данных (3472 сэмпла/c) может составить 2,35 с, максимальное значение
определяется пользователем.

По видимому до прихода действительных данных LGraph отображает не корректные данные.

Спасибо, действительно был включен режим измерения нуля. После добавления LTR22_SwitchMeasureADCZero(m_module, false); всё заработало.

Контакты

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

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

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

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