• Автор
    Тема
  • #50264
    no_img
    Виталий К.
    Участник

    1. Исходя из блок схемы в 230-м модуле максимальная частота опроса каждого одного канала
    зависит от количества включенных каналов, это так? Если зависит то это означает что
    каналы опрашиваются не синхронно?

    2. Если имеются несколько 230-х модулей, каким образом можно их синхронизировать
    (одновременное начало сбора данных и синхронный опрос)?

    3. Вопрос по работе с Zadc.dll. Что будет в случае если необходимая для помещения в буфер
    (полученный с помощью ZGetBufferADC) порция данных размером больше области оставшейся до конца буфера?

    4. Количество включенных каналов можно получить с помощью ZGetNumberInputADC. А каким образом можно
    узнать номера включенных каналов?

  • Автор
    Ответы
  • #50265
    no_img
    Manager ZETLAB
    Участник

    Здравствуйте, Виталий!
    1. Частота дискретизации АЦП в ZET 230 не зависит от количества включенных каналов, соответственно, сколько бы ни было включено каналов, данные опрашиваются всегда синхронно.
    2. Синхронизовать модули ZET 230 можно через цифровой порт этих устройств. При этом одно из устройств будет мастером, а остальные слейвом. Кто мастер, а кто слейв настраивается через «Диспетчер устройств» на вкладке «Синхронизация». При таком подходе цифровые порты устройств должны быть физически соединены. Более подробно написано здесь.
    3) Поскольку буфер циклический, то указатель на текущий элемент заполнения буфера просто перейдет в начало и все продолжется.
    4) Узнать номера включенных каналов можно в цикле по всем каналам функцией ZGetInputADC. Для включенных каналов в параметре enable будет возвращаться значение 1, а для выключенных 0.
    Удачи!

    #50266
    no_img
    Виталий К.
    Участник

    Спасибо!
    Только по 3-му вопросу, осталось не понятным, часть данных будет записана в конце буфера, а часть в начале или же указатель перейдет на начало и данные полностью запишутся начиная с 0-го адреса?

    #50267
    no_img
    Manager ZETLAB
    Участник

    Здравствуйте, Виталий!
    Часть данных запишется в конец буфера, а оставшаяся часть в начало буфера.
    Удачи!

    #50268
    no_img
    Виталий К.
    Участник

    Здравствуйте!
    Для работы с модулями через библиотеку Zadc.dll используются константы typeDevice, определяющие тип устройства. (Например в функции ZOpen(typeDevice, numberDSP); ).
    Не подскажете число typeDevice для 230-го модуля?

    #50270
    no_img
    Manager ZETLAB
    Участник

    Добрый день!
    1)typeDevice для 230-го модуля равен 17
    2)В документе ZETLabStudio.pdf в главе 12 содержится информация по интересующему вас вопросу.
    Документ поставляется на дисках к приборам или в Doc.rar на ftp находится всегда последняя версия.

    #50271
    no_img
    Виталий К.
    Участник

    Добрый день. Есть код, основанный на Вашем с++ примере, который нормально читает данные с 210-го модуля (подключается
    по USB), при попытке использования этого же кода для чтения с 230-го модуля(подключение по Ethernet). При этом единственное
    изменение в коде — замена типа устройства с 10 на 17.

    В наличии 3 библиотеки(версия 2012.9.3.0 идет с ПО ZetLab), функция ZOpen возвращает разные значения в зависимости
    от передаваемого ей типа устройства (10 для 210 модуля, 17 — для 230-го)см. таблицу:

    Версия длл Тип устройства Результат ZOpen
    2012.9.3.0 10 0xA00
    2012.9.3.0 17 0xC00

    2011.12.2.0 10 0 (OK)
    2011.12.2.0 17 0x900

    5.1.0.0 10 0 (OK)
    5.1.0.0 17 0x900

    Т.е. ни одна из длл не работает с 230-м модулем, подключенным по Ethernet. Жду помощи.
    версия ПО ZetLab — 06.09.2012
    Windows XP SP3

    #50272
    no_img
    Manager ZETLAB
    Участник

    Добрый день!
    Ошибка 0xA00 — устройство с данным numberDSP не подключено (надо проверить значение numberDSP — для Ethernet оно скорее всего начинается с номера 67)
    Ошибка 0xC00 (для 230) это ошибка несовпадения версий

    #50273
    no_img
    Виталий К.
    Участник

    Спасибо за разъяснения. Действительно, для Ethernet numberDSP начинается с 67.

    #50274
    no_img
    Manager ZETLAB
    Участник

    Добрый день. Никак не можем разобраться с синхронизацией двух (и более) 230-х модулей. Есть необходимость получать данные с всех каналов двух модулей синхронно (т.е. отсчеты должны сниматься одновременно с каналов обоих модулей).
    Пытаемся читать самописной программой (которая функционально собственно почти полностью содрана с Вашего примера)
    При установке режимов ведущий и ведомый, соединения 8-го пина цифрового порта и подаче на все каналы синусоиды в 1000 Гц частотой:
    1) снимаемые отсчеты стартуют не синхронно (возможно тут необходимо учитывать порядок вызова ZStartADC для ведущего и ведомого модулей, подскажите как тут быть)
    2) по характеру снимаемых с двух модулей синусоид видно, что частота дискретизации у них немного разная (в следствии чего синусоиды, построенные только по отсчетам то сходятся то расходятся с большим периодом)
    Как решение этих проблем вижу установку одного из модулей «Задатчиком синхронизации», и организация дискретизации с одной частотой. Но в документе ZET 2xx Base.pdf в п.4.2.3 есть описание старого интерфейса настройки, а в новом пункта «Задатчик синхронизации» нет.
    Заранее спасибо за ответ.

    #50275
    no_img
    Manager ZETLAB
    Участник

    Добрый день!
    Единственное, что нужно, чтобы устройства все были одного типа.
    1)Порядок вызова ZStartADC: сначала запускаются ведомые устройства (в режиме ожидания внешнего сигнала запуска), затем запускается ведущее устройство, которое подает сигнал ведомым.
    2)Соединять нужно несколько ножек. Их функции описаны:
    в пункте 4.2.3 описана цифровая ножка 8 как источник управления — то есть это сигнал внешнего запуска. Помимо этого в пп. 4.2.3.1 и 4.2.3.2 описаны еще цифровые ножки 7 и 6 — по ним передается внешняя частота дискретизации АЦП и ЦАП.
    Если используется Диспетчере устройств, то во вкладке «Синхронизация» выставить в задатчике флажок Ведущий, а в остальных — Ведомый
    3) Настройка синхронизации по цифровому порту:
    Код
    // проверка значения err после каждого вызова опущена для краткости
    long err;

    // настройка задатчика синхронизации
    err = ZSetEnableExtStartADC(typeDSP, numberDSP, 1);
    err = ZSetEnableExtFreqADC(typeDSP, numberDSP, 1);
    err = ZSetMasterSynchr(typeDSP, numberDSP, 1);

    // получаем частоту с задатчика
    double freq;
    err = ZGetExtFreqADC(typeDSP, numberDSP, &freq);

    // настройка ведомых устройств
    err = ZSetEnableExtStartADC(typeDSP, numberDSP, 1);
    err = ZSetEnableExtFreqADC(typeDSP, numberDSP, 1);
    err = ZSetExtFreqADC(typeDSP, numberDSP, freq);
    err = ZSetMasterSynchr(typeDSP, numberDSP, 0),

    потом ZStartADC в указанном порядке. Вот такой пример должен работать.
    Сообщите еще, пожалуйста, какой пример Вы используйте?

    #50276
    no_img
    Виталий К.
    Участник

    Используемый пример — Пример работы с драйвером с использованием библиотеки ZADC.dll. Программа написана на Microsoft Visual С++ 6.0. со страницы Программирование с вашего сайта. Т.е. с этого адреса https://www.zetms.ru/support/programming/index.php

    #50277
    no_img
    Виталий К.
    Участник

    Описание приведенных Вами функций отсутствует в имеющемся в примере модуле Zadc_int.h. После внесения их в *.h-файл, линкер выдает unresolved external symbol. Скажите, как у Вас можно получить актуальные версии Zadc_int.h и Zadc.lib. Если не трудно можете выслать мне на адрес k1981ua@mail.ru
    С уважением, Виталий.

    #50278
    no_img
    Manager ZETLAB
    Участник

    Добрый день!
    Файлы высланы.

    #50279
    no_img
    Виталий К.
    Участник

    Спасибо!

    #50281
    no_img
    Виталий К.
    Участник

    Добрый день! Скопилось еще несколько вопросов:
    1) функция ZGetExtFreqADC(typeDSP, numberDSP, &freq) в параметре частоты всегда(на разных частотах 2500, 25000 и 50000Гц)
    возвращает 12800000. Это так и должно быть?
    2) есть ли способ получения данных с 230-х модулей напрямую, т.е. без Zadc.dll? Их протокол обмена открытый?
    3) При считывании данных с приборов они идут пачками по несколько тысяч сэмплов, иногда при частоте дискретизации
    25000 Гц пачки составляют 20-30 тыс. сэмплов (т.е. 160-1400 тыс. байт ( *4 канала*2байта)). Такое поведение нормально?
    По ощущениям ЗетЛаб считывает данные меньшими порциями.

    Заранее спасибо за ответы.

    #50283
    no_img
    Manager ZETLAB
    Участник

    Добрый день!
    1) да, это опорная частота, затем данные проходят через фильтр, чтобы исключить возможные помехи и получить требуемую частоту
    2) нет, единственный способ это работа через интерфейс Zadc.dll
    Протокол обмена между драйвером и ПО может быть в любой момент изменен, в связи с чем его сопровождение за пределами компании сильно затруднено
    3) это связанно с особенностями протокола USB: передача данных от устройства происходит пакетами одинакового размера; драйвер же (в целях производительности) буферизует эти данные в своей внутренней памяти, а внешний буфер заполняет после получения нескольких пакетов.

    #50284
    no_img
    Виталий К.
    Участник

    Добрый день!
    А если 3-й вопрос касается Ethernet-модулей, такое поведение нормально? сейчас подключено два 230-х модуля, если их подключить восемь, они смогут нормально передавать все данные без потерь и больших задержек?
    Может посоветуете как следует организовывать Ethernet-сеть для гарантированного обеспечения нормальной работы?
    С уважением, Виталий

    #50285
    no_img
    Manager ZETLAB
    Участник

    Добрый вечер!

    При работе по интерфейсу Ethernet данные также буферизуются пакетами (разве что размеры и количество пакетов во внутреннем буфере могут отличаться от USB). Данные передаются по TCP/IP и не должны теряться, однако при увеличении частоты увеличиваются также и возможные задержки.

    #50286
    no_img
    Виталий К.
    Участник

    Добрый день!
    Возник вопрос касающийся генерации сигнала на выходе «Генератор 1» модуля 230-го (или 220-го). Откомпилировав и запустив последний пример Test_DAC, установив нужные typeDevice и numberDSP (17 и 67 соответственно, у нас Ethernet-модуль) видим что ZOpen и вобщем-то остальные функции отрабатываю нормально. Стартует, доходит до цикла генерации, входит в него, но ничего на выходе Генератора 1 нет. Пробовали забить буфер DAC значениями вручную — все равно ничего нет. Скажите может есть другой пример или мы что-то делаем не так? Какой алгоритм работы для генерирования напряжения на выходе Генератора 1? Может мы что-то не учитываем?

    #50287
    no_img
    Manager ZETLAB
    Участник

    Здравствуйте, Виталий!
    Очередной раз проверил пример Test_DAC для ZET230 при подключении его и по USB и по Ethernet — все работает так, как и заложено. Ваши проблемы могут быть связаны со следующими факторами:
    1) При работе с устройством самостоятельно через драйвер не рекомендуется использовать программы из пакета ZETLab, поскольку при этом запускается сервер данных ZETLab, который самостоятельно конфигурирует устройства, а следовательно, может остановить ЦАП или АЦП, настроить другие параметры и т.д., что приведет к сбою в работе Test_DAC.
    2) Если же вы все-таки решите использовать устройство в режиме работы с драйвером и при этом пользоваться программами из пакета ZETLab, то в программе, работающей через драйвер необходимо предусмотреть дополнительные возможности для отслеживания останова ЦАП, АЦП и других изменений в устройстве, поскольку сервер данных ZETLab может их изменять.
    3) Нужно проверить то, с какого контакты вы смотрите сигнал генератора (это на всякий случай).
    Удачи!

    #50288
    no_img
    Виталий К.
    Участник

    Спасибо за ответ!
    По ходу работы возник еще вопрос: заметили что показания напряжения на входе 230-го модуля, рассчитанное нашей программой, работающей через zadc.dll отличается от показаний программ комплекса ЗетЛаб примерно на 6-7% (меряем величины порядка 450 мВ). Наша программа показывает больше на 30мВ.
    Перепроверено неоднократно.
    Рассчитываем по формуле,заимствованной из примеров:
    volt0 = resolutionADC * (pBuffer32ADC[pointerADC/numWordsADC]) / amplifyADC0
    Скажите, в чем может быть проблема? Есть ли еще какие-нибудь параметры, влияющие на рассчет напряжения?
    Заранее спасибо за ответ.

    #50289
    no_img
    Manager ZETLAB
    Участник

    Здравствуйте, Виталий!
    На расчет напряжения могут влиять параметры чувствительности и смещения, настроенные через «Диспетчер устройств»
    Удачи!

    #50290
    no_img
    Виталий К.
    Участник

    Скажите пожалуйста, могу ли я получить эти параметры (чувствительность и смещение) через zadc.dll, как например получаю вес младшего разряда с помощью функции ZGetDigitalResolChanADC и рассчитать значение напряжения используя только функции предоставляемые zadc.dll.
    Заранее спасибо за ответ!

    #50291
    no_img
    Manager ZETLAB
    Участник

    Здравствуйте, Виталий!
    Эти параметры в zadc.dll не имеют места быть, поэтому вы их оттуда никак не возьмете. Эти параметры есть только в ZETServer. В zadc.dll предоставлена возможность работать только с исходными данными. Все их преобразование в измеряемую величину осуществляется в ZETServer.
    Удачи!

    #50292
    no_img
    Виталий К.
    Участник

    В очередной раз перепроверили:
    показания Зетлаба = 432 мВ.
    Снимаем данные:
    младший разряд АЦП=0.00000000488944351673
    код АЦП = 95070036
    коэфф. усиления = 1
    Пожалуйста объясните как из этих данных получается 432 мВ?
    Заранее спасибо за ответ.

    #50293
    no_img
    Manager ZETLAB
    Участник

    Здравствуйте, Виталий!

    Из тех данных, что вы предоставили, никак не получается 432 мВ. Для большей информативности прошу вас прислать на почту настройки вашего измерительного канала в ZETLab и желательно запись сигнала, который вы измеряете.

    Удачи!

    #50294
    no_img
    Виталий К.
    Участник

    Здравствуйте!
    Я знаю что не получается, но тем не менее вольтметр Зетлаб показывает именно это значение. Вы не могли бы уточнить алгоритм перевода кода АЦП в напряжение?
    Сообщите на какой е-мэйл выслать скриншоты и запись сигнала.
    Заранее спасибо за ответ!

    #50295
    no_img
    Manager ZETLAB
    Участник

    Здравствуйте, Виталий!

    Формула перевода приведена в примере, и она ничем не отличаетя от той, что в ZETLAB. Почта info@zetlab.com или zetlab@zetlab.com.

    Удачи!

    #50296
    no_img
    Виталий К.
    Участник

    Здравствуйте, Антон!
    Файлы отправил.

    #50297
    no_img
    Виталий К.
    Участник

    Здравствуйте!
    Модули мы не путаем, просто Зетлаб показывает одно — правильное значение, а при обращении к библиотеке получаем код АЦП, вес младшего разряда и коэффициент усиления — при их перемножении получается другое значение, погрешность относительная, не абсолютная.

    #50298
    no_img
    Manager ZETLAB
    Участник

    Здравствуйте, Виталий!

    Скажите, данный эффект проявляется только на одном канале конкретного модуля или это проявляется на всех каналах всех модулей?

    Удачи!

    #50303
    no_img
    Виталий К.
    Участник

    Здравствуйте!
    Сдалали тестовую программку для измерения напряжения на канале, ее код (ничего лишнего, только опрос):

    //==========================================================­================================
    #include «stdafx.h»
    #include <Windows.h>
    #include «Zadc_int.h»
    #include <stdio.h>
    #include <conio.h>

    class Z230Device
    {
    public:
    long err;
    long typeDevice;
    long numberDSP;
    long numChannelsADC; // Кол-во включенных каналов АЦП
    long numWordsADC; // Кол-во слов (по два байта) в одном отсчете АЦП
    void *pBuffer; // Указатель на начало буфера драйвера типа void
    short *pBuffer16ADC; // Указатель на начало буфера драйвера для АЦП с разрядностью не более 16 бит
    long *pBuffer32ADC; // Указатель на начало буфера драйвера для АЦП с разрядностью более 16 бит
    long sizeBufferADC; // Размер буфера драйвера в словах
    long pointerADC; // Указатель на текущий элемент заполнения буфера драйвера (кратен 2)
    long pointerADC_old; // Предыдущее значение указателя на буфер драйвера
    double amplifyADC[4];// Коэф. усиления по каналам
    double resolutionADC; // Вес младшего разряда АЦП
    double volt[4]; // Мгновенное текущее значение АЦП (в Вольтах)
    double freq; //частота задатчика синхронизации
    };
    //==========================================================­====================
    HINSTANCE dllHandle=NULL;
    Z230Device devs[1];
    //——————————————————————-
    int numDev=0;
    //==========================================================­=========
    long Init230(long numDev,long typeDev, long number_DSP, long err)
    {
    devs[numDev].typeDevice=typeDev;
    devs[numDev].numberDSP=number_DSP;

    dllHandle = LoadLibrary(L»zadc.dll» 😉 ;

    // подключиться к драйверу (обязательно)
    err = ZOpen(devs[numDev].typeDevice, devs[numDev].numberDSP);

    // опросить коэф. усиления по каналу АЦП
    err = ZGetAmplifyADC(devs[numDev].typeDevice, devs[numDev].numberDSP, 0, &devs[numDev].amplifyADC[0] 😉 ;
    err = ZGetAmplifyADC(devs[numDev].typeDevice, devs[numDev].numberDSP, 0, &devs[numDev].amplifyADC[1] 😉 ;
    err = ZGetAmplifyADC(devs[numDev].typeDevice, devs[numDev].numberDSP, 0, &devs[numDev].amplifyADC[2] 😉 ;
    err = ZGetAmplifyADC(devs[numDev].typeDevice, devs[numDev].numberDSP, 0, &devs[numDev].amplifyADC[3] 😉 ;

    // опросить вес младшего разряда АЦП
    err = ZGetDigitalResolutionADC(devs[numDev].typeDevice, devs[numDev].numberDSP, &devs[numDev].resolutionADC);

    // опросить кол-во слов в одном отсчете АЦП
    err = ZGetWordsADC(devs[numDev].typeDevice, devs[numDev].numberDSP, &devs[numDev].numWordsADC);

    // запросить буфер АЦП
    err = ZGetBufferADC(devs[numDev].typeDevice, devs[numDev].numberDSP, &devs[numDev].pBuffer, &devs[numDev].sizeBufferADC);

    // Проинициализировать локальные указатели для конкретных типов данных
    devs[numDev].pBuffer16ADC = (short*) devs[numDev].pBuffer;
    devs[numDev].pBuffer32ADC = (long*) devs[numDev].pBuffer;

    return 0;
    }
    //==========================================================­===============
    double getValueCh(long numDev,long numCh, long err, long *CodeADC, double *ResolADC,double *AmplifADC, long *pointer)
    {

    // запросить указатель на текущий элемент буфера
    err = ZGetPointerADC(devs[numDev].typeDevice, devs[numDev].numberDSP, &devs[numDev].pointerADC);
    if(err != 0) return -1;

    *pointer=devs[numDev].pointerADC;

    // перейти на отсчет первого включенного канала последнего кадра АЦП
    if(devs[numDev].pointerADC — devs[numDev].numWordsADC * devs[numDev].numChannelsADC < 0)
    devs[numDev].pointerADC = devs[numDev].sizeBufferADC + devs[numDev].pointerADC — devs[numDev].numWordsADC * devs[numDev].numChannelsADC;
    else
    devs[numDev].pointerADC = devs[numDev].pointerADC — devs[numDev].numWordsADC * devs[numDev].numChannelsADC;

    *CodeADC=devs[numDev].pBuffer32ADC[devs[numDev].pointerADC/devs[numDev].numWordsADC + numCh];
    *ResolADC=devs[numDev].resolutionADC;
    *AmplifADC=devs[numDev].amplifyADC[numCh];

    // вычислить из целого значения отсчета АЦП вещественное значение отсчета (в Вольтах)
    if(devs[numDev].numWordsADC == 1)
    devs[numDev].volt[numCh] = devs[numDev].resolutionADC * (devs[numDev].pBuffer16ADC[devs[numDev].pointerADC + numCh] 😉 / devs[numDev].amplifyADC[numCh];
    else
    devs[numDev].volt[numCh] = devs[numDev].resolutionADC * (devs[numDev].pBuffer32ADC[devs[numDev].pointerADC/devs[numDev].numWordsADC + numCh] 😉 / devs[numDev].amplifyADC[numCh];

    return devs[numDev].volt[numCh];

    }
    //——————————————————————

    int _tmain(int argc, _TCHAR* argv[] 😉
    {
    long CodeADC;
    long pointer;
    double ResolADC;
    double AmplifADC;
    long err;

    err=Init230(0,17,67,0);
    err=ZStartADC(devs[0].typeDevice,devs[0].numberDSP);

    while(!kbhit())
    {
    Sl eep(1000);
    double val=getValueCh(0,0,0,&CodeADC,&ResolADC,&AmplifADC,&pointer);
    printf(«%i %i %.14f %.5f %.8f\n»,pointer,CodeADC,ResolADC,AmplifADC,val);
    }

    ZRemBufferADC(devs[0].typeDevice, devs[0].numberDSP,&(devs[0].pBuffer));
    ZClose(devs[0].typeDevice, devs[0].numberDSP);
    FreeLibrary(dllHandle);
    dllHandle = NULL;

    return 0;
    }
    //==========================================================­=================================

    Запускаем ее, и потом Вольтметр постоянного тока Зетлаб, их скрины:
    формат вывода программы: указатель на элемент буфера, код АЦП, вес мл. разряда. коэфф. усиления, значение в Вольтах
    forum5
    Запускали много раз, ошибка воспроизводима и постоянна. По другим каналам этого модуля то же самое. Объясните пожалуйста как из кода АЦП=90358324 и веса мл.разряда 0,00000000488944
    получить то что показывает вольтметр Зетлаба.

    Очень рассчитываю на помощь.

    #50304
    no_img
    Manager ZETLAB
    Участник

    Здравствуйте, Виталий!

    Функция ZGetDigitalResolutionADC предназначена для запроса веса младшего разряда АЦП. Однако при настройке устройств данный параметр проходит калибровку и становится для каждого канала свой, поэтому запрашивать нужно откалиброванный вес младшего разряда АЦП фукнцией ZGetDigitalResolChanADC, которая уже привязана к конкретному каналу.

    Удачи!

    #50306
    no_img
    Виталий К.
    Участник

    Спасибо за ответ, будем пробовать.

Для ответа в этой теме необходимо авторизоваться.

Авторизация
*
*

Потеряли пароль?

Политика конфиденциальности персональных данных

Регистрация
*
*
*

Политика конфиденциальности персональных данных

Генерация пароля