|
|
Непрерывная чтение данных. Миф или реальность?
Братья, помогите. Прочитал руководство программиста для Е14-440, (вроде внимательно) и не понял!
1. Реализация двойного фифо буфера позволила организовать непрерывный сбор данных. Это факт!
2. Длина буфера может выставляться от 32 до 12288 и должна быть кратной 32. Это факт! Так написанно в руководстве. А теперь то что в примерах и на самом деле.
3. Функция РидДата позволяет вести асинхронное чтение фифо буффера, причем модуль возвращает по 1/2 фифо буфера, чем и достигаеться двойная буфферезация, и как следствие асинхронная работа.
Внимание! Причем второй параметр этой функции указывает на кол-во данных необходимое забрать из буффера, и в руководстве указанно от 64 до 1024х1024 и кратно 64. Так написанно в руководстве. А теперь, как мы можем забрать кол-во данных равное 1048576=1024х1024 если
12288/0,5=6144? Или другой случай, когда мы хотим забрать кол-во данных меньше половины фифо, вторая попытка приведет к чтению из другой половины или из этой-же, так как точного указания на то, из какой половины фифо буфера читать нет.
4. И в результате сшивая два файла записанные таким вот образом видем, ага, нестыковка, то есть имеет место временная задержка или сдвиг или вообще непонятное что-то. Уточню, что модуль был запущен на оцифровку и работал, неостанавливаясь.
Теперь вопросы.
Вопрос первый. Нужно ли указывать длину буффера из расчета необходимой длины пакета, ну например, хочу я собирать из 1 2 3 и 4 каналов, это кадр,таких кадров 800, это пакет, и записывать его в файл. получим что один пакет равен 3200, значит длинна буффера должна быть равна 6400, чтобы ее читать в два присеста, то есть по очереди пока мы читаем из одной половины, модуль собирает данные в другую. и как точнее отлавливать момент когда модуль заканчивает собирать данные в одну половину и переключаетсья на другу?
Может кто встречалься с такой проблемой. Подскажите, буду благодарен.
|
|
- Сотрудник "Л Кард"
- Здесь с 24.04.2014
- Сообщений: 1,495
|
Re: Непрерывная чтение данных. Миф или реальность?
Судя по всему Вы всё-таки не очень внимательно читали руководство программиста.
>> 2. Длина буфера может выставляться от 32 до 12288 и должна быть кратной 32. Это факт! Так написанно в руководстве.
На самом деле там написано, что длина FIFO буфера "может находиться в диапазоне от 0x40 (64) до 0x3000 (12288), а также быть обязательно кратной 0x40(64)".
>>3. Функция РидДата позволяет вести асинхронное чтение фифо буффера, причем модуль возвращает по 1/2 фифо буфера ...
На самом деле функция ReadData() "обеспечивает асинхронный режим получения очередных NumberOfWordsToRead отсчетов из FIFO буфера АЦП". При этом ни о каком получении данных строго по половинкам FIFO буфера речи не идёт. Более того, собственно сама функция совершенно ничего не знает о каком то ни было FIFO буфере модуля. Единственная задача этой функции получить с модуля ровно NumberOfWordsToRead отсчётов. Другое дело, что модуль передаёт данные в РС порциями по 1/2 FIFO буфера модуля. Но Функция ReadData() совершенно не обязана вычитывать полностью половину FIFO буфера. Она вполне законно может вычитать только необходимое кол-во данных из этой половинки FIFO буфера. Невычитанная чать данных может быть получена при выполнении следующей функции ReadData().
>>Причем второй параметр этой функции указывает на кол-во данных необходимое забрать из буффера, и в руководстве указанно от 64 до 1024х1024 и кратно 64. Так написанно в руководстве.
На самом деле в руководстве написано, что "величина NumberOfWordsToRead должна быть в диапазоне от 32 до (1024*1024), а также быть кратной 32".
На счёт сшивания двух файлов я ничего не понял
Смотри также:
http://www.lcard.ru/forumthreads/875
http://www.lcard.ru/forumthreads/875%20 … hread=1128
|
|
|
Re: Непрерывная чтение данных. Миф или реальность?
Сергей.
Извинюсь, перепутал две цифры, по сравнению с тем что я имею на руках это пустяк.
От случая к случаю плата такие перлы выдает. Смешно сказать, такое впечатление что буфферы специально путает!
В общем случая простой, хочется собирать дату в файлы непрерывным
потоком. То есть выбрали каналы АЦП указали их параметры, указали
сколько хотим кадров в файле, под кадром подразумевается один цикл
логических каналов и вперед, логер типа. И пущай шлепает их в файлы. Хочется правда при
этом, что бы если два соседних файла состыковать, не было ни каких
пробелов. Для этого приходится запускать АЦП и организовывать два
процесса запроса данных, и по мере их готовности писать их в файл, по оканчанию указанного количества файлов, стопарить АЦП.
Так вот первый вопрос. Правда, что данные которые валяться из модуля,
в ПК еще раз буфферезируются, то есть я хочу сказать, что если я
запрошу столько данных, кол-во, которых будет состоять из 5 целых и
одного полубуффера ФИФО, или еще чего хуже четверти. То следующий
запрос будет брать данные из новой порции, или даберет из старой и
только потом из новой. ИЛИ Я ВСЕТАКИ потеряю драгоценные данные, в
размере полу или четверти или еще какого количества данных, так
сказать на стыке файлов.
Могу выслать код процедурку, которая так сказать этим и занимается.
Хочется надеяться на помощь, а то крыша едет. Заранее благодарен.
Михаил Макаров.
|
|
|
Re: Непрерывная чтение данных. Миф или реальность?
Вот так народ! Нет, что ли среди вас настоящих знатоков L-Card? Ведь вопрос пустяк, но момент очень тонкий! Обрисуйте пожалуйста реальный путь данных от модуля усб до пк, а точнее в плоть до функции РеадДата. Примного благодарен.
|
|
- Сотрудник "Л Кард"
- Здесь с 24.04.2014
- Сообщений: 1,495
|
Re: Непрерывная чтение данных. Миф или реальность?
Всё равно с трудом понимаю, что такое два соседних файла. Но нсколько я понял, Вам просто требуется организовать непрерывный сбор данных. Тогда посмотрите на консольные примеры на нашем CD-ROM (непример, /Examples/BC5/ReadData). Там показан один из алгоритмов сбора данных.
|
|
|
Re: Непрерывная чтение данных. Миф или реальность?
Да смотрел я и читал это пример. Там все в один большой буффер ложиться. Расказываю что надо.
Надо писать лог, пусть в разные файлы, но долго. Мы настраиваем карту, запускаем два процесса чтения и стартуем АЦП, в общем все как в примере, но каждый процесс чтения ложит не в один и тотже буффер, как в примере, добавляя его, а в отдельные пронумерованные файлы, и все так и работает успешно, файл за файлом буффер за буффером. Пришлось правда создать всех элементов по два комплекта. А теперь мы берем два последовательных файла с номерами 9785 и 9786, и ставим друг за другом, и видим что данные несшиваються есть разрывы на стыке фалов. Вот что я имел ввиду!
Вроде проблему решил, взяв все всему кратное. Теперь DataStep равно полбуфферу умноженному на N. Сам буффер выбираеться из расчета наименьшего кратного 64 и числу логических каналов в кадре и умножаеться на два в степени K где числдо от 1 до ---, такое чтобы длинна полубуффера была больше 1024 слова. Что бы избежать каких то засоров в начале первого процесса чтения данных, так и не понял от куда они беруться. теперь буду тестировать, может еще какой баг вылезит. Огромное спасибо Сергей за поддержу. С уважением PicStar. Может еще что есть написать пиши, с радостью прочту. А да, еще необходимо меду стартами АЦП делать ресет дсп и заново грузить биос, а иначе там вообще в первом чтении гадасть. Я бы сказал хаос из предыдущих данных.
|
|
|
Re: Непрерывная чтение данных. Миф или реальность?
Подобная задача решена в утилите File Recorder, которая входит в состав ПО PowerGraph. Программа осуществляет непрерывный сбор данных и записывает данные в последовательность нумерованных файлов, заданного размера. Непрерывность ('сшиваемость') файлов тоже можно обеспечить использованием счетчика значений.
'Мусора' при каждом очередном запуске не наблюдается, биос грузится только один раз при запуске программы.
Использовать два отдельных потока (процесса) для чтения данных из одного модуля - решение очень проблематичное, так как придется усиленно напрягаться с синхронизацией запросов. Можем посоветовать Вам следующее - разделить потоки (процессы) по выполняемым задачам:
- один обеспечивает непрерывный сбор данных в единый общий буфер в компьютере;
- другой 'нарезает' этот буфер на файлы по мере его заплонения.
|
|
|
Re: Непрерывная чтение данных. Миф или реальность?
Здравствуйте!
Посоветуйте,пожалуйста, что делать. Проблема с функцией ReadData, модуль E14-140. Работает с частотой дискретизации 400кГц. Программа пишется на Delphi7 и в отдельном потоке должна быть организована запись в файл. Алгоритм точно такой же, как в WriteTread у LGraph'а (процедура bool __fastcall TWriteThread::UsbReadAndWrite(void)).
DataStep=1024*1024
два буфера:
Buffer1, Buffer2: array[0..1048576] of SHORT;
делаем примерно следующее:
ReadData(Buffer2...),
ЦИКЛ
ReadData(Buffer1...);
file.write(Buffer2...);
WaitForSingleObject(...);
ReadData(Buffer2...);
file.write(Buffer1...);
WaitForSingleObject(...);
В НАЧАЛО ЦИКЛА
Просматриваем записанный файл,видим:
1. Теряются отсчеты на стыке участков записей.
2. Теряются отсчеты в начале каждого участка, то есть после того, как запускается ReadData, считывание данных из буфера модуля в буфер в ОЗУ прерывается один или несколько раз? В чем причина? Повышение приоритета потока записи в файл не помогает.
ReadData по разному работает в Делфи и в Си?
|
|
- Сотрудник "Л Кард"
- Здесь с 24.04.2014
- Сообщений: 1,495
|
Re: Непрерывная чтение данных. Миф или реальность?
Модуль E14-140 не предназначен для работы с частотой дискретизации 400 кГц. Максимум 100 кГц.
|
|
|
Re: Непрерывная чтение данных. Миф или реальность?
Я ошибся, модуль E 14-440.
И даже если DataStep < 1024*1024 скажем, 131072, непрерывной работы функции ReadData не получается. С чем это может быть связано, не подскажете?
|
|
- Сотрудник "Л Кард"
- Здесь с 24.04.2014
- Сообщений: 1,495
|
Re: Непрерывная чтение данных. Миф или реальность?
На вскиду, Ваш алгоритм должен быть примерно таков:
START_ADC();
ReadData(Buffer1...),
ЦИКЛ
ReadData(Buffer2...);
WaitForSingleObject(Buffer1...);
file.write(Buffer1...);
ReadData(Buffer1...);
WaitForSingleObject(Buffer2...);
file.write(Buffer2...);
В НАЧАЛО ЦИКЛА
|
|
|
Re: Непрерывная чтение данных. Миф или реальность?
Да, все правильно. START_ADC() ставим непосредсвенно перед тем кодом, который я выше привел. Это уже есть и это не помогает. Все равно данные теряются. Причем наблюдается некоторая систематичность: начинается считывание данных в буфер; около 50 отсчетов читаются непрерывно, затем первая пауза; далее 500-2000 отсчетов опять непрерывно; вторая пауза, после которой чтение идет непрерывно до заполнения буфера 1024*1024 отсчетами. Потом опять потеря отсчетов, потом идут данные из второго буфера. Что может повлиять на непрерывность считывания? Была ли попытка реализовать запись данных в файл, подобная той, которая есть в WriteThread у LGraph'а, на Делфи? код Examples/D6/ReadData с изменением частоты дискретизации на 400 кГц и числом каналов на 1 работает нормально. Если добавить к проекту форму и перенести код из файла .dpr в файл .pas, то он уже не работает так же хорошо, возникают вышеописанные проблемы
|
|
- Сотрудник "Л Кард"
- Здесь с 24.04.2014
- Сообщений: 1,495
|
Re: Непрерывная чтение данных. Миф или реальность?
1. Дело не только в наличии ф. START_ADC(). Вы посмотрите внимательней, там алгоритмы совершенно разные.
2. Ситуация с добавлением к проекту формы вообще выглядит непонятной. Засылайте исходники. Будем посмотреть.
|
|
|
Re: Непрерывная чтение данных. Миф или реальность?
Код Examples/D6/ReadData работает в любых видах. Это я поторопился, извините. Сделал в своей программе вместо WaitForSingleObject() цикл с GetOverlappedResult() как в Examples/D6/ReadData, сразу ситуация изменилась. Читает непрерывно, отсчеты не теряются.
Видимо, эти две функции не работаю одинаково хорошо в данном случае. Спасибо!
|