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


Доработка примера 'ReadData' - нужна помощь чайнику

Вы не вошли.

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

30.07.2014 18:38:07
#1

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

Доработка примера 'ReadData' - нужна помощь чайнику

Добрый день!
Помогите, пожалуйста, с заменой WriteFile на fprintf в примере 'ReadData':

if(!WriteFile(hFile,IoReq[RequestNumber^0x1].Buffer, 2*DataStep, &FileBytesWritten,NULL)) { ReadThreadErrorNumber = 0x4; break; }

Заранее спасибо!

31.07.2014 12:23:36
#2

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

Re: Доработка примера 'ReadData' - нужна помощь чайнику

Нельзя заменить WriteFile на fprintf, потому что данные двоичные, а fprintf работает с текстом.
Если Вы хотите писать данные в виде текста (столбик цифр), то придется каждый отсчет преобразовывать как-то так:

for (i = 0; i < DataStep; i++)
    {
    fprintf(fp, "%d\n", (int)Buffer[i]);
    }

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

P.S. А если Вы имели в виду не fprintf, а fwrite, тогда файл должен быть открыт как двоичный (fp = fopen(filename, "wb")), ну и

fwrite(Buffer, sizeof(Buffer[0]), DataStep, fp)
31.07.2014 18:46:40
#3

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

Re: Доработка примера 'ReadData' - нужна помощь чайнику

Спасибо большое за ответ, обязательно попробую!

31.07.2014 18:47:21
#4

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

Re: Доработка примера 'ReadData' - нужна помощь чайнику

именно fprintf, чтобы текстовым редактором удобно было смотреть данные

29.08.2014 09:31:30
#5

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

Re: Доработка примера 'ReadData' - нужна помощь чайнику

Александр,если не сложно, подскажите, чем можно смотреть файлы данных,создаваемых ReadData?

29.08.2014 10:03:09
#6

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

Re: Доработка примера 'ReadData' - нужна помощь чайнику

Например, L-Graph I.

29.08.2014 17:45:33
#7

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

Re: Доработка примера 'ReadData' - нужна помощь чайнику

Спасибо!

29.08.2014 18:29:30
#8

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

Re: Доработка примера 'ReadData' - нужна помощь чайнику

Подскажите,пожалуйста, в строках примера:

	
*********
// формируем необходимые для сбора данных структуры
	for(i = 0x0; i < 0x2; i++)
	{
		// инициализация структуры типа OVERLAPPED
		ZeroMemory(&ReadOv[i], sizeof(OVERLAPPED));
*********

0x2 - это число опрашиваемых каналов АЦП (2 штуки)?

01.09.2014 12:14:37
#9

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

Re: Доработка примера 'ReadData' - нужна помощь чайнику

1.

0x2 - это число опрашиваемых каналов АЦП (2 штуки)?

Это кол-во запросов, используемых при получение данных из модуля. Подробнее смотри описание функции ReadData() в руководстве программиста.

2. Если Вы читали руководство программиста, то могли заметить, что кол-во активных каналов АЦП задаётся исключительно полем ChannelsQuantity структуры типа ADC_PARS_XXX.

01.09.2014 14:52:49
#10

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

Re: Доработка примера 'ReadData' - нужна помощь чайнику

Станислав пишет:

0x2 - это число опрашиваемых каналов АЦП (2 штуки)?

Чтобы лучше понять ответ Сергея, что это такое и почему два запроса, советую прочитать статью на нашем сайте про двойную буферизацию.

01.09.2014 18:31:10
#11

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

Re: Доработка примера 'ReadData' - нужна помощь чайнику

Спасибо за пояснения,обязательно прочту.
Хотелось бы прояснить.
В этом же примере.
1. Если я хочу-таки записать результаты измерений по всем каналам в различные файлы с указателями fp1, fp2, fp3,fp4, то как мне переписать приведенную выше строчку:

for (i = 0; i < DataStep; i++)
    {
    fprintf(fp, "%d\n", (int)Buffer[i]);
    }

Где указать номер канала?

2. Могу ли я опрашивать только 2 и 3 канал, не опрашивая первый? Где указывать номер канала, если такой запрос возможен?
Заранее спасибо за помощь!

01.09.2014 19:18:50
#12

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

Re: Доработка примера 'ReadData' - нужна помощь чайнику

@Станислав, ну это же все написано в руководстве программиста.
Список опрашиваемых каналов в ControlTable. В данных отсчеты каналов идут в том же порядке, что в ControlTable, кадр за кадром.
Если
ap.ControlTable[0] = канал x(t),
ap.ControlTable[1] = канал v(t),
ap.ControlTable[2] = канал w(t),
ChannelsQuantity = 3,
то поток данных будет x(0), v(0), w(0), x(1), v(1), w(1), x(2)...

При этом, разумеется, кадры никак не связаны с порциями чтения данных, то есть buffer[0] содержит отсчет не обязательно первого канала, а следующего за последним в предыдущем буфере. Если не хочется с этим возиться, то надо, чтобы буфер был кратен кадру.

04.09.2014 17:53:29
#13

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

Re: Доработка примера 'ReadData' - нужна помощь чайнику

Спасибо за разъяснения,буду разбираться!

04.09.2014 18:05:39
#14

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

Re: Доработка примера 'ReadData' - нужна помощь чайнику

Поправьте, пожалуйста,если ошибаюсь.
Планирую использовать дваканала, 2 и 3,
а) задаю
ap.ChannelsQuantity = 0x2;
б) устанавливаю первый логический номер канала для второго канала АЦП, диапазон +-5В (00000010):
ap.ControlTable[0]=1;
в) устанавливаю логический номер канала для третьего канала АЦП, диапазон +-5В (00000011):
ap.ControlTable[1]=3;
Верно?
Или нумерация каналов АЦП начинается с нуля и второй канал это 0000 0001, а третий 0000 0010?

04.09.2014 18:56:46
#15

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

Re: Доработка примера 'ReadData' - нужна помощь чайнику

Станислав пишет:

ap.ControlTable[0]=1;
ap.ControlTable[1]=3;
Верно?
Или нумерация каналов АЦП начинается с нуля и второй канал это 0000 0001, а третий 0000 0010?

Нумерация начинается с нуля в ControlTable и с единицы на разъеме, т.е. для каналов 2 и 3 ControlTable[] = { 1, 2 }
А что за прибор программируете? E154?

05.09.2014 11:24:32
#16

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

Re: Доработка примера 'ReadData' - нужна помощь чайнику

Александр Е пишет:
Станислав пишет:

ap.ControlTable[0]=1;
ap.ControlTable[1]=3;
Верно?
Или нумерация каналов АЦП начинается с нуля и второй канал это 0000 0001, а третий 0000 0010?

Нумерация начинается с нуля в ControlTable и с единицы на разъеме, т.е. для каналов 2 и 3 ControlTable[] = { 1, 2 }
А что за прибор программируете? E154?

Понял, спасибо, E154

15.09.2014 17:47:55
#17

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

Re: Доработка примера 'ReadData' - нужна помощь чайнику

Александр Е пишет:

for (i = 0; i < DataStep; i++) { fprintf(fp, "%d\n", (int)Buffer [ i ]); }

Сделал в ReadData такую запись в файл (параллельно с

if(!WriteFile(	  hFile,													// handle to file to write to
		    			 IoReq[RequestNumber^0x1].Buffer, // pointer to data to write to file
					 2*DataStep,	 		  // number of bytes to write
	    				 &FileBytesWritten,		  // pointer to number of bytes written
					 NULL 				  // pointer to structure needed for overlapped I/O
							   )) { ReadThreadErrorNumber = 0x4; break; }

При этом счетчик на экране "Counter=...from.." не идет дальше 0.
В файл fp что-то постоянно записывается.
Куда копать, подскажите, пожалуйста!

15.09.2014 18:43:55
#18

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

Re: Доработка примера 'ReadData' - нужна помощь чайнику

Вдобавок, не удается "переписать" этот пример в виде формы с кнопкой "старт". Дальше первого кадра запись не идет:(
http://www.lcard.ru/forums/img/members/42/My1.zip

15.09.2014 18:53:31
#19

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

Re: Доработка примера 'ReadData' - нужна помощь чайнику

Прошу прощения, снимаю 18 пост: запись не шла из-за наличия kbhit!

16.09.2014 11:25:10
#20

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

Re: Доработка примера 'ReadData' - нужна помощь чайнику

Станислав пишет:

При этом счетчик на экране "Counter=...from.." не идет дальше 0.

Вообще переменную, в которую один поток пишет, а второй ждет изменения (foo = 0; while (!foo) { код, не меняющий foo }) , надо делать volatile, а то компилятор имеет право заменить условие константой, потому что компиляция не учитывает многопоточности. Хотя конкретно этот компилятор ничего не соптимизировал.
Заработала программа-то?

16.09.2014 13:36:09
#21

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

Re: Доработка примера 'ReadData' - нужна помощь чайнику

Проблема, которую я описал в 17 посте для меня пока неясна. там же простой вывод в файл fprintf, почему не работает?!?

16.09.2014 13:37:54
#22

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

Re: Доработка примера 'ReadData' - нужна помощь чайнику

Добавлю. Запись идет "рядом" с WriteFile-ом, то есть, как я полагаю, в том же потоке...

16.09.2014 15:27:18
#23

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

Re: Доработка примера 'ReadData' - нужна помощь чайнику

Давайте по пунктам.

  • Без fprintf программа работает? Пишет двоичный дамп?

  • Когда добавляете fprintf, работа программы не нарушается? Так же пишет двоичный дамп?

  • Текстовый файл открывается fopen?

  • ...закрывается fclose перед выходом?

17.09.2014 10:27:12
#24

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

Re: Доработка примера 'ReadData' - нужна помощь чайнику

Александр, добрый день!
Спасибо за помощь.
Нашел ошибку в коде. Целиком и полностью моя вина, глупейшая ошибка. Использовал "бездумно" Ваш код:

for (i = 0; i < DataStep; i++) { fprintf(fp, "%d\n", (int)Buffer [ i ]); }

при этом не обратил внимание на то, что i уже используется в цикле сбора данных, внутри которого я работаю:

		for(i = 0x1; i < NDataBlock; i++)

Замена переменной i на j решила эту проблему!
Спасибо еще раз большое!

18.09.2014 12:09:40
#25

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

Re: Доработка примера 'ReadData' - нужна помощь чайнику

Пожалуйста smile
А в этом плане C++ и С99 хороши возможностью написать for (int i =...), причем если внутренняя локальная переменная перекрывает видимость внешней с тем же именем, компилятор может выдать предупреждение (gcc, например, говорит "warning: declaration of 'i' shadows a previous local [-Wshadow]"). Это на случай, если программист совсем не выспался и внутри цикла будет обращение сразу к двум разным переменным "i" smile