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

Считывание данных с LTR24-2 Python

Вы не вошли.

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

18.04.2024 14:56:36
#1

Участник
Здесь с 18.04.2024
Сообщений: 3

Считывание данных с LTR24-2 Python

Здравствуйте, набросал программу для LTR24-2 на python 3.7, OC AstraLinux
В крейте LTR-EU-2 один модуль LTR24-2 и подаю на 1 канал него с помощью блока питания 3В
На выходе получаю:
-0.000118255615234375
-0.00023651123046875
-0.000118255615234375
-0.00023651123046875

Пожалуйста подскажите, что я делаю неправильно

# -*- coding: utf-8 -*-
from time import sleep
import ctypes

LTR24_CHANNEL_CNT = 4       #Количество каналов АЦП модуля LTR24
LTR24_RANGE_CNT = 2         #Количество диапазонов в режиме дифференциального входаам
LTR24_ICP_RANGE_CNT = 2     #Количество диапазонов в режиме ICP-входа
LTR24_FREQ_CNT = 16         #Количество частот дискретизации
LTR24_I_SRC_VALUE_CNT = 2   #Количество значений источника тока
LTR24_NAME_SIZE = 8         #Размер поля с названием модуля
LTR24_SERIAL_SIZE = 16      #Размер поля с серийным номером модуля

LTR24_RANGE_NUM = LTR24_RANGE_CNT
LTR24_FREQ_NUM = LTR24_FREQ_CNT
LTR24_I_SRC_VALUE_NUM = LTR24_I_SRC_VALUE_CNT
# количество отсчетов на канал, принмаемых за раз (блок)
RECV_BLOCK_CH_SIZE = 1024

LTR24_PROC_FLAG_CALIBR = 0x00000001
LTR24_PROC_FLAG_VOLT = 0x00000002
LTR24_PROC_FLAG_AFC_COR = 0x00000004
LTR24_PROC_FLAG_AFC_COR_EX = 0x00000008
LTR24_PROC_FLAG_ICP_PHASE_COR = 0x00000010
LTR24_PROC_FLAG_NONCONT_DATA = 0x00000100

class TLTR(ctypes.Structure):
    _pack_ = 1
    _fields_ = [
        ("saddr", ctypes.c_ulong),
        ("sport", ctypes.c_ushort),
        ("csn", ctypes.c_byte*16),
        ("cc", ctypes.c_ushort),
        ("flags", ctypes.c_ulong),
        ("tmark", ctypes.c_ulong),
        ("internal", ctypes.c_void_p)
    ]


class TLTR24_CHANNEL_CONFIG(ctypes.Structure):
    _pack_ = 1
    _fields_ = [
        ("Enable", ctypes.c_bool),
        ("Range", ctypes.c_byte),
        ("AC", ctypes.c_bool),
        ("ICPMode", ctypes.c_bool),
        ("SensorROut", ctypes.c_float),
        ("Reserved", ctypes.c_ulong*3)
    ]


class TLTR24_CBR_COEF(ctypes.Structure):
    _pack_ = 1
    _fields_ = [
        ("Offset", ctypes.c_float),
        ("Scale", ctypes.c_float)
    ]


class TLTR24_AFC_IIR_COEF(ctypes.Structure):
    _pack_ = 1
    _fields_ = [
        ("a0", ctypes.c_double),
        ("a1", ctypes.c_double),
        ("b0", ctypes.c_double)
    ]


class TLTR24_AFC_COEFS(ctypes.Structure):
    _pack_ = 1
    _fields_ = [
        ("AfcFreq", ctypes.c_double),
        ("FirCoef", (ctypes.c_double*LTR24_RANGE_NUM)*LTR24_CHANNEL_CNT),
        ("AfcIirCoef", TLTR24_AFC_IIR_COEF)
    ]


class TLTR24_MODULE_INFO(ctypes.Structure):
    _pack_ = 1
    _fields_ = [
        ("Name", ctypes.c_char*LTR24_NAME_SIZE), # *LTR24_NAME_SIZE
        ("Serial", ctypes.c_char*LTR24_SERIAL_SIZE), # *LTR24_SERIAL_SIZE
        ("VerPLD", ctypes.c_byte),
        ("SupportICP", ctypes.c_bool),
        ("SupportedFeatures", ctypes.c_ulong),
        ("Reserved", ctypes.c_ulong*7),
        ("CalibCoef", (((TLTR24_CBR_COEF*LTR24_FREQ_NUM)*LTR24_RANGE_NUM)*LTR24_CHANNEL_CNT)),
        ("AfcCoef", TLTR24_AFC_COEFS),
        ("ISrcVals", (ctypes.c_double*LTR24_I_SRC_VALUE_NUM)*LTR24_CHANNEL_CNT) # *LTR24_CHANNEL_CNT
    ]


class TLTR24(ctypes.Structure):
    _pack_ = 1
    _fields_ = [
        ("Size", ctypes.c_int),
        ("Channel", TLTR),
        ("Run", ctypes.c_bool),
        ("ADCFreqCode", ctypes.c_byte),
        ("ADCFreq", ctypes.c_double),
        ("DataFmt", ctypes.c_byte),
        ("ISrcValue", ctypes.c_byte),
        ("TestMode", ctypes.c_bool),
        ("Reserved", ctypes.c_ulong*16), #DWORD
        ("ChannelMode", TLTR24_CHANNEL_CONFIG*LTR24_CHANNEL_CNT),
        ("ModuleInfo", TLTR24_MODULE_INFO),
        ("CalibCoef", (((TLTR24_CBR_COEF*LTR24_FREQ_NUM)*LTR24_RANGE_NUM)*LTR24_CHANNEL_CNT)),
        ("AfcCoef", TLTR24_AFC_COEFS),
        ("Internal", ctypes.c_void_p)
    ]


# e_LTR24_I_SOURCES
LTR24_I_SRC_VALUE_2_86 = 0      #2.86 мА.
LTR24_I_SRC_VALUE_10 = 1        #10 мА.

# e_LTR24_FORMATS
LTR24_FORMAT_20 = 0     #20-битный целочисленный (1 слово на отсчет)
LTR24_FORMAT_24 = 1     #24-битный целочисленный (2 слова на отсчет)

# e_LTR24_FREQS
LTR24_FREQ_117K = 0     #117.1875 кГц
LTR24_FREQ_78K = 1      #78.125 кГц
LTR24_FREQ_58K = 2      #58.59375 кГц
LTR24_FREQ_39K = 3      #39.0625 кГц
LTR24_FREQ_29K = 4      #29.296875 кГц
LTR24_FREQ_19K = 5      #19.53125 кГц
LTR24_FREQ_14K = 6      #14.6484375 кГц
LTR24_FREQ_9K7 = 7      #9.765625 кГц
LTR24_FREQ_7K3 = 8      #7.32421875 кГц
LTR24_FREQ_4K8 = 9      #4.8828125 кГц
LTR24_FREQ_3K6 = 10     #3.662109375 кГц
LTR24_FREQ_2K4 = 11     #2.44140625 кГц
LTR24_FREQ_1K8 = 12     #1.8310546875 кГц
LTR24_FREQ_1K2 = 13     #1.220703125 кГц
LTR24_FREQ_915 = 14     #915.52734375 Гц
LTR24_FREQ_610 = 15     #610.3515625 Гц

# e_LTR24_ICP_RANGES
LTR24_ICP_RANGE_1 = 0   #1 В (RMS)
LTR24_ICP_RANGE_5 = 1   #5 В (RMS)

LTR24_RANGE_2 = 0       #±2 В
LTR24_RANGE_10 = 1      #±10 В


def MeasureLTR24(slot):
    try:
        ltr24api = ctypes.CDLL('/usr/lib/libltr24api.so.1.32.37')
        # число измерений
        RECV_BLOCK_CNT = 5
        # число разрешенных каналов для измерений
        enabledChanelCount = 0
        # инициализируем класс для работы с 24-м модулем
        #tTLTR24 = TLTR24()
        #tTLTR24.ChannelMode[0].Enable = True
        pLTR24 = ctypes.pointer(TLTR24())
        errorCode = ltr24api.LTR24_Init(pLTR24)
        # открываем модуль, получение конфигурации происходит автоматически здесь же
        # serialNumber = "6T773008"
        errorCode = ltr24api.LTR24_Open(pLTR24, 0x7F000001, 11111, ctypes.c_char_p(), slot) #127.0.0.1, 11111
        # print(errorCode)
        # получаем конфигурацию модуля
        errorCode = ltr24api.LTR24_GetConfig(pLTR24)
        # print(errorCode)
        # устанавливаем формат обмена данными
        pLTR24.contents.DataFmt = LTR24_FORMAT_24
        # устанавливаем частоту
        pLTR24.contents.ADCFreqCode = LTR24_FREQ_2K4
        # переключаем модуль в тестовый режим
        pLTR24.contents.TestMode = True
        #
        # pLTR24.contents.ISrcValue = LTR24_I_SRC_VALUE_2_86
        # настраиваем каналы
        channelMode = TLTR24_CHANNEL_CONFIG()
        channelMode.Enable = True
        channelMode.Range = LTR24_RANGE_10
        channelMode.AC = False
        channelMode.ICPMode = False

        for i in range(LTR24_CHANNEL_CNT):
            pLTR24.contents.ChannelMode[i] = channelMode

        # задаем количество разрешенных каналов
        enabledChanelCount = 4
        # передаем конфигурацию модулю
        errorCode = ltr24api.LTR24_SetADC(pLTR24)
        # print(errorCode)
        # проверяем, выполняется ли сбор данных уже
        if pLTR24.contents.Run:
            # останавливаем сбор данных
            errorCode = ltr24api.LTR24_Stop(pLTR24)
        # # начинаем сбор данныхыы
        errorCode = ltr24api.LTR24_Start(pLTR24)

        # расчитываем количество принимаемых данных
        receivedDataCount = RECV_BLOCK_CH_SIZE * enabledChanelCount
        # установка слов на отсчет
        receivedWordsCount = receivedDataCount * (2 if pLTR24.contents.DataFmt == LTR24_FORMAT_24 else 1)
        # массив для принятых слов
        buf = (ctypes.c_ulong * receivedWordsCount)()
        # массив для меток на каждое слово
        tmark = (ctypes.c_ulong * receivedWordsCount)()

        size = ctypes.c_ulong(len(buf))
        # массив для хранения данных
        data = (ctypes.c_double * receivedDataCount)()
        # признаки перегрузки на каждый отсчет
        overloads = (ctypes.c_bool * receivedDataCount)()
        # прием RECV_BLOCK_CNT блоков данных

        for i in range(RECV_BLOCK_CNT):
            # Управление режимом отсечки постоянной составляющей во время сбора
            # errorCode = ltr24api.LTR24_SetACMode(pLTR24, 0, False)
            # errorCode = ltr24api.LTR24_SetACMode(pLTR24, 1, False)
            # errorCode = ltr24api.LTR24_SetACMode(pLTR24, 2, False)
            # errorCode = ltr24api.LTR24_SetACMode(pLTR24, 3, False)

            # количество принятых данных
            recvCount = 0
            # процедура принятия данных от модуля
            recvCount = ltr24api.LTR24_Recv(pLTR24, buf, tmark, size, 100)
            print(recvCount)

            if recvCount < 0:
                raise Exception("Ошибка приема данных")

            num = ctypes.c_ulong(recvCount)
            addr = ctypes.addressof(num)
            ptr = ctypes.cast(addr, ctypes.POINTER(ctypes.c_ulong))
            # запуск данных на обработку

            errorCode = ltr24api.LTR24_ProcessData(pLTR24, buf, data, ctypes.pointer(tmark), LTR24_PROC_FLAG_VOLT or
                                                   LTR24_PROC_FLAG_CALIBR or
                                                   LTR24_PROC_FLAG_AFC_COR,  overloads)

            # выводим полученные значения
            for ch in range(LTR24_CHANNEL_CNT):
                if pLTR24.contents.ChannelMode[ch].Enable:
                    print(str(data[ch]))

        # останавливаем сбор данных
        errorCode = ltr24api.LTR24_Stop(pLTR24)

        ltr24api.LTR24_Close(pLTR24)
    except Exception as ex:
        print(ex)
18.04.2024 15:48:43
#2

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

Re: Считывание данных с LTR24-2 Python

Enanik пишет:

# переключаем модуль в тестовый режим
   pLTR24.contents.TestMode = True

А в тестовый режим зачем переключаете? Тестовый режим для канала диф. входа это как раз режим измерения собственного нуля, тогда данные вполне объяснимы...

22.04.2024 10:05:30
#3

Участник
Здесь с 18.04.2024
Сообщений: 3

Re: Считывание данных с LTR24-2 Python

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

# переключаем модуль в тестовый режим
   pLTR24.contents.TestMode = True

А в тестовый режим зачем переключаете? Тестовый режим для канала диф. входа это как раз режим измерения собственного нуля, тогда данные вполне объяснимы...

Выключил Тестовый режим. Значение такие же.

22.04.2024 19:40:15
#4

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

Re: Считывание данных с LTR24-2 Python

Также смущает, что у Вас в объявлении идет _pack_ = 1, хотя ltr24api.h используется выравнивание на 4, а не 1.
Также, чтобы проверить правильность описания структур в Phyton, сравните значение размера структуры TLTR24, полученное sizeof из вашей программы, и значение, которое будет в поле Size после вызова LTR24_Init()

03.05.2024 11:50:31
#5

Участник
Здесь с 18.04.2024
Сообщений: 3

Re: Считывание данных с LTR24-2 Python

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

Также смущает, что у Вас в объявлении идет _pack_ = 1, хотя ltr24api.h используется выравнивание на 4, а не 1.
Также, чтобы проверить правильность описания структур в Phyton, сравните значение размера структуры TLTR24, полученное sizeof из вашей программы, и значение, которое будет в поле Size после вызова LTR24_Init()

Если я ставлю  _pack_ = 3 или _pack_ = 4 то я получаю нулевые значения:
0.0
0.0
0.0
0.0
Если _pack_ = 1 или _pack_ = 2 то:
-0.0094757080078125
-0.025661468505859375
-0.009464263916015625
-0.02562713623046875

Размер созданной структуры: 2664
При выполнении LTR24_Init() в поле Size: 2636

Проверил правильность описания структур, все соответствует из документации (ltr24api.pdf структура -  TLTR24, ltrapi.pdf  - TLTR)
CHAR = ctypes_char
INT = ctypes.c_int
BOOL =  ctypes.c_bool
BYTE = ctypes.c_byte
double = ctypes.c_double
float = ctypes.c_float
WORD = ctypes.c_ushort
DWORD = ctypes.c_ulong
PVOID = ctypes.c_void_p

06.05.2024 18:57:03
#6

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

Re: Считывание данных с LTR24-2 Python

Насчет соответствия размеров типов есть сомнения... по крайней мере у меня sizeof(ctypes.c_ulong) дает 8 вместо 4, а sizeof(ctypes.c_bool) - 1, вместо также 4 (BOOL определен как 4-байтовое в типах Windows, в отличие от BOOLEAN - 1 байт). Лучше бы использовать типы с явным размером:

int = ctypes.c_int32
BOOL =  ctypes.c_uint32
BYTE = ctypes.c_uint8
WORD = ctypes.c_uint16
DWORD = ctypes.c_uint32

Если поменять на такое соответствие типов и использовать pack = 4, то что с соответствием размеров и данными будет?

Контакты

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

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

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

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