Программирование устройств

с использованием библиотеки ZADC.dll

В данном разделе наши специалисты дают развёрнутый ответ на наиболее сложные и интересные вопросы клиентов о программировании устройств, подключенных по USB.

  • Беседовал с вашим консультантом через форму на сайте, где получил этот адрес.
    Мы заказывали у вас прибор ZET 210, физики с университета УдГУ, г. Ижевск. С помощью стандартного функционала среды зет-лаб нужные нам данные частично данные снимаются. Сейчас руководством поставлена задача написания программы на языке Delphi 7. С этим возникают вопросы, в документации вроде бы что-то изложено, но сделать ничего не получается

    В связи с этим есть просьба. Не могли ли бы скинуть примитив для выше обозначенной среды, где снимался бы сигнал с первого пина аналогового входа-выхода с заданной заранее частотой, чтобы мы могли понять, как это делается. То есть самый простой исходник, который мы бы скомпилировали, подали тестовые данные и дальше уже понимали, как работать с интерфейсом zetlab в Delphi .

    Кроме того, будем рады любым примерам приложений, использующих библиотеки zetlab, а также документации для работы в среде Delphi .

    Заранее благодарны, надеюсь получилось понятно сформулировать.

  • Руководство программиста с описанием функций есть на диске с дистрибутивами
    (HELP_ZETLab studio_special.pdf), а также на ftp (https://file.zetlab.ru/Document/HELP_ZETLab%20studio_special.pdf).

    Примеры программирования (в том числе и на Delphi) есть на диске с дистрибутивами (папка Documentation\Samples), а также на ftp https://file.zetlab.ru/Document/Samples/

  • Из представленного примера стало понятно, как обращаться к вашей разделяемой библиотеке.
    Не удалось следующее: изменить частоту сбора/отображения данных, сбора данных с вольтметра, осциллографа. Плюс в PDF описание функций для с++. Как использовать это в Delphi не совсем понятно. Не могли бы прояснить этот момент, либо прислать пример на Delphi , демонстрирующий как работать с указанными выше параметрами?

    Как это применимо в среде Delphi ?

    То есть как мы можем это поменять через программу и опросить устройство, какие данные оно получает? Хотелось бы увидеть всё же рабочий пример, в документации сказано, что поддержка Delphi неполная, возможно эти функции просто недоступны? Если доступны, пришлите пожалуйста пример как можно менять частоту и опрашивать пины устройства.

  • Получение списка возможных частот дискретизации АЦП/ЦАП
    long ZGetListFreqADC (long typeD

    evice, long numberDSP, long n

    ext, double *freq) (Zadc.dll)

    long ZGetListFreqDAC (long typeDevice, l

    ong numberDSP, long next, double *freq)

    Эти функции применимы в Delphi, так же, как и, например, функции ZGetNumberInputADC/ZGetNumberInputDAC, используемые в примере на диске. Функции ZGetListFreqADC/ZGetListFreqDAC используются для получения списка возможных частот дискретизации. В пункте 1.7 руководства ZETLabStudio описано, как с ними работать. Рабочий пример есть на диске с дистрибутивом, а также на ftp-сервере. В нем как раз отражен алгоритм чтения измеренных данных с устройства.

  • Да, на основе программы получилось забирать данные с аналогового входа.
    Однако с выставленной частотой 31250 герц мы всё равно получаем около 100 строк параметров в секунду. То есть реальная скорость аналогового порта 100 герц?

    Но это не главное. Наша задача подразумевает получение данных с частотой от 50 килогерц и выше. Видимо нужно использовать цифровой порт, ЦАП. В примере никак не отражена работа с цифровым портом, но самое главное — у нас не получилось организовать работу по аналогии с аналоговым. Подобных функций похоже просто нет. Не могли бы прислать пример работы именно с цифровым портом? 

  • Лучение данных измерительных каналов не предполагает работу по одному отсчету АЦП
    Частота дискретизации в ZET210 может достигать 500 кГц, если работать с одним включенным каналом на максимальной частоте, но это не означает, что программа 500000 раз в секунду будет брать по одному отсчету. Данные из устройства пересылаются на компьютер и в драйвере буферизируются. Пересылка осуществляется определенными порциями. В ОС Windows не получится часто забирать данные, даже если они будут приходить по одному отсчету. Обработка данных должна происходить порциями. Точно также придется работать и с цифровым портом. Работа с ним отличается от работы с аналоговыми данными тем, что у каналов цифрового порта нет частоты дискретизации, можно только считывать состояние цифрового порта. А вот как часто это можно делать зависит от параметров компьютера и ОС. Описание функций по работе с цифровым портом представлены в п. 1.14 руководства ZETLabStudio.
  • Благодарю за информацию и прошу прощения за глупые вопросы!
    Дело в том, что наша задача снимать данные с частотой хотя бы 100 килогерц, выборка на частоте менее 50 уже становится не репрезентативной. То есть нам действительно нужно получать сто тысяч строк данных в секунду. Не могли бы подсказать, можно ли это сделать на данном контроллере и если да, каким образом и с использованием каких дополнительных компонентов? На данный момент мы работаем на intel i3, озу 4gb, windows 7. При необходимости, имеется возможность программировать на си или лазарус под ubuntu linux. Но нам понадобятся инструкции.

    По функциям для работы с цифровым портом, пока ясности мало, но прежде чем задавать конкретные вопросы мы ещё раз попробуем разобраться с матчастью, благодарю за ссылку на документацию. В любом случае, полагаю, нам бы не повредил рабочий пример работы с цифровым портом.

  • В предыдущем письме имелось ввиду, что получать данные с такой частотой от устройства можно (максимум 500 кГц)
    и у Вас действительно получится столько отсчетов АЦП, сколько выставлена частота дискретизации. Но все эти отсчеты Вы будете получать не по одному, а определенными порциями, то есть, например, при частоте 100 кГц Вы получите N порций по M отсчетов за секунду и N * M = 100000. Передача данных порциями вытекает из особенностей передачи данных по USB, чтобы обеспечить максимальную пропускную способность потоков данных от устройства и к устройству. При работе с цифровым портом вы сможете получить столько отсчетов в секунду, сколько успеете раз опросить цифровой порт программой, потому что для него нет понятия частоты дискретизации.
  • Становится понятнее. На данный момент программа из примеров даёт нам возможность забирать приблизительно 100 строк в секунду.
    Получается нам как-то нужно брать за один отсчёт 1000 значений из устройства. И вновь неясно как это сделать. Кроме того, пока у нас не получилось опросить цифровой вход в принципе. Пришлите нам пожалуйста пример, как это можно делать. Или хотя-бы подскажите конкретные функции, с помощью которых это можно делать.

    При этом если нужно работать с порциями данных, непонятно, сколько данных максимально может быть в порции. Реально ли в принципе на этом устройстве получать 1000 состояний 100 раз в секунду?

  • Для работы с цифровым портом необходимо сделать следующие манипуляции:
    1) Вызвать ZSetDigOutEnable, где в качестве digitalOutEnableMask задать маску для настройки работы пинов на вход (если все должны работать на вход, то получится 0)

    2) В цикле вызывать функцию ZGetDigInput для чтения состояния цифрового порта. В переменной digitalInput будет выдано состояние входа цифрового порта, где каждый бит отвечает за соответствующий пин цифрового порта.

  • Процесс получения и обработки данных имеет следующий алгоритм.
    При передаче данных с устройства на компьютер в драйвере происходит буферизация данных в циклическом буфере, указатель на который мы получаем функцией ZGetBufferADC. По мере прихода данных этот буфер заполняется и перезаписывается. Для позиционирования по буферу существует переменная-указатель на текущую позицию заполнения буфера, т.е. это фактически индекс последнего принятого от устройства отсчета в циклическом буфере. Получение текущего значения указателя происходит функцией ZGetPointerADC. Соответственно в цикле постоянно опрашивается значение указателя и если оно изменилось, значит пришли новые данные и их нужно вычитать из буфера драйвера и обработать требуемым алгоритмом. Размер данных это разница между предыдущим значением указателя и текущим. Собственно, это и происходит в примере (только на экран выводится не все отсчеты, а последний из порции).
  • Очень благодарны за подробное разъяснение. Процесс пошёл. Остались вопросы следующего плана:
    1) Не получилось забрать остальные результаты из порции в примере, но думаю завтра мы это сделаем.

    2) В принципе получается, что, читая данные из буфера мы их не теряем, а если потеряем — драйвер отдаст ошибку указателя?

  • В примере просто при изменении указателя копируется один отсчет
    ( CopyMemory(@sample16ADC[0], pBuffer16ADC, 2);) из буфера, а нужно копировать все от pointerADC_old до pointerADC.

    2) Задача драйвера просто заполнять буфер с данными и не заботиться о том, прочитали из него или нет. Поэтому нужно следить за указателем pointerADC из программы и вовремя забирать из буфера драйвера данные куда-нибудь в буфер в программы. Если долго не копировать данные из буфера драйвера, они могут затереться, так как буфер циклический. Чтобы определить на сколько хватает буфера, можно опросить его размер, количество включенных каналов устройства, частоту дискретизации по каналам, размер одного отсчета и по формуле посчитать на сколько времени хватает буфера.