• Автор
    Тема
  • #98569
    no_img
    Trifonoff ilya
    Участник

    Добрый день, использую вашу продукцию (ZET 210) для дипломного проекта. Возник вопрос по функциям:
    long ZGetBufferADC(long typeDevice, long numberDSP, void **buffer, long *size)
    long ZGetMaxInterruptADC(long typeDevice, long numberDSP, long * size)

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

  • Автор
    Ответы
  • #98575
    no_img
    Trifonoff ilya
    Участник

    Проблема с буферами ушла: ошибочно интерпретировали данные. Возник другой вопрос : при увеличении частоты дискретизации частота обновления значений в буфере не увеличивается. Как можно решить данный вопрос?

    #98585

    Добрый день!
    Есть несколько моментов, которые нужно учитывать при использовании устройств, подробно они описаны в статье по ссылке: https://zetlab.com/programmirovanie-ustroystv-s-ispolzovaniem-biblioteki-zadc-dll/napisanie-programmnyx-prilozhenij-dlya-kontrollera-zetlab/.
    Проверьте пожалуйста учтены ли данные рекомендации, и если да то опишите проблему подробнее.

    #98614
    no_img
    Trifonoff ilya
    Участник

    Да данные моменты учитывались при использовании Zet210. Включены два канала, частота дискретизации на каждом 200 кГц. При подаче на канал синуса с частотой 10 кГц, и записи полученных значений в файл. я получаю график сигнала отличный от синуса, хотя частота дискретизации на порядок превышает частоту `поданного сигнала.
    Код программы:

    // Программа, включающая два канала АЦП устройства и отображающая мгновенное амплитудное значение по двум каналам два раза в секунду
    // © ЗАО "ЭТМС" 1992-2011. Все права защищены
    
    #include "stdafx.h"
    #include <windows.h> 
    #include <conio.h>
    #include <stdio.h>
    #include <iostream>
    #include <fstream>
    #include "zadc_int.h"						// Интерфейс библиотеки Zadc.dll
    using namespace std;
    
    #define MAX_TYPE_DSP	20					// Максимальное поддерживаемое количество типов устройств
    #define MAX_DEVICE_NAME	16					// Максимальное значение длины возвращаемого имени устройства
    
    int main(int argc, char* argv[])
    {
    	long typeDevice;						// Тип устройства
    	long numberDSP = 0;						// Порядковый номер сигнального процессора
    	long Err;								// Код ошибки
    	long enable;							// Флаг поддерживается / не поддерживается
    	long numChannelsADC;					// Количество включенных каналов АЦП
    	long numWordsADC;						// Количество слов (по два байта) в одном отсчете АЦП
    	short *pBuffer16ADC = NULL;				// Указатель на начало буфера драйвера для АЦП с разрядностью не более 16 бит
    	long *pBuffer32ADC = NULL;				// Указатель на начало буфера драйвера для АЦП с разрядностью более 16 бит 
    	long sizeBufferADC;						// Размер буфера драйвера в словах
    	long pointerADC = 0;					// Указатель на текущий элемент заполнения буфера драйвера (кратен 2)
    	long pointerADC_old = 0;				// Предыдущее значение указателя на буфер драйвера
    	double amplifyADC0, amplifyADC1;		// Коэффициент усиления по первым двум каналам 
    	double resolutionADC0, resolutionADC1;	// Вес младшего разряда АЦП по первым двум каналам
    	double volt0, volt1;					// Мгновенное текущее значение АЦП (в вольтах)
    	long serial;							// Серийный номер устройства
    	char deviceName[MAX_DEVICE_NAME];		// Имя устройства
    
    	// Цикл подключения к первому поддерживаемому устройству
    	for(typeDevice = 0; typeDevice < MAX_TYPE_DSP; typeDevice++)
    	{
    		// Подключение к драйверу устройства
    		Err = ZOpen(typeDevice, numberDSP);
    		// Если подключение прошло без ошибок
    		if(Err == 0)
    		{
    			// Проверка поддержки устройством АЦП
    			Err = ZGetEnableADC(typeDevice, numberDSP, &enable);
    			// Если устройство поддерживает АЦП
    			if(Err == 0 && enable != 0)
    			{
    				// Выход из цикла подключения
    				break;
    			}
    			// Если устройство не поддерживает АЦП
    			else
    			{
    				// Вывод информации об ошибке
    				printf("ZGetEnableADC() return Error = 0x%X\n\r", Err);
    				// Отключение от драйвера устройства
    				Err = ZClose(typeDevice, numberDSP);
    			}
    		}
    	}
    
    	// Если не удалось подключиться к драйверу устройства
    	if(typeDevice >= MAX_TYPE_DSP)
    	{
    		// Вывод информации об ошибке
    		printf("Device not found! Error = 0x%X\n\r", Err);
    		getch();
    		return 0;
    	}
    	// Если удалось подключиться к драйверу устройства
    	else
    	{
    		// Вывод информации о том, что произошло подключение к драйверу устройства
    		printf("Device found...\n\r");
    	}
    
    	// Опрос имени устройства
    	Err = ZGetNameDevice(typeDevice, numberDSP, deviceName, MAX_DEVICE_NAME);
    	// Если опрос выполнился с ошибкой
    	if(Err != 0)
    	{
    		// Вывод информации об ошибке
    		printf("ZGetNameDevice() return Error = 0x%X\n\r", Err);
    		// Отключение от драйвера устройства
    		Err = ZClose(typeDevice, numberDSP);
    		getch();
    		return 0;
    	}
    	// Если опрос выполнился без ошибок
    	else
    	{
    		// Вывод имени устройства
    		printf("Device name: %s\n\r", deviceName);
    	}
    
    	// Опрос серийного номера устройства
    	Err = ZGetSerialNumberDSP(typeDevice, numberDSP, &serial);
    	// Если опрос выполнился с ошибкой
    	if(Err != 0)
    	{
    		// Вывод информации об ошибке
    		printf("ZGetNameDevice() return Error = 0x%X\n\r", Err);
    		// Отключение от драйвера устройства
    		Err = ZClose(typeDevice, numberDSP);
    		getch();
    		return 0;
    	}
    	// Если опрос выполнился без ошибок
    	else
    	{
    		// Вывод серийного номера устройства
    		printf("Serial number: %ld\n\r", serial);
    	}
    
    	// Опрос колличества каналов АЦП устройства
    	Err = ZGetQuantityChannelADC(typeDevice, numberDSP, &numChannelsADC);
    	// Если опрос выполнился с ошибкой
    	if(Err != 0)
    	{
    		// Вывод информации об ошибке
    		printf("ZGetQuantityChannelADC() return Error = 0x%X\n\r", Err);
    		// Отключение от драйвера устройства
    		Err = ZClose(typeDevice, numberDSP);
    		getch();
    		return 0;
    	}
    	// Если опрос выполнился без ошибок
    	else
    	{
    		// Вывод количества каналов АЦП устройства
    		printf("Quantity of ADC channel: %ld\n\r", numChannelsADC);
    	}
    
    	// Запрос на включение первого канала АЦП устройства
    	Err = ZSetInputADC(typeDevice, numberDSP, 0, 1);
    	// Если запрос выполнился с ошибкой
    	if(Err != 0)
    	{
    		// Вывод информации об ошибке
    		printf("ZSetInputADC() return Error = 0x%X\n\r", Err);
    		// Отключение от драйвера устройства
    		Err = ZClose(typeDevice, numberDSP);
    		getch();
    		return 0;
    	}
    	// Если запрос выполнился без ошибок
    	else
    	{
    		// Вывод информации об успешном включении первого канала АЦП устройства
    		printf("First channel activation is successful...\n\r");
    	}
    	// Если количество каналов устройства больше одного
    	if(numChannelsADC > 1)
    	{
    		// Запрос на включение второго канала АЦП устройства
    		Err = ZSetInputADC(typeDevice, numberDSP, 1, 1);
    		// Если запрос выполнился с ошибкой
    		if(Err != 0)
    		{
    			// Вывод информации об ошибке
    			printf("ZSetInputADC() return Error = 0x%X\n\r", Err);
    			// Отключение от драйвера устройства
    			Err = ZClose(typeDevice, numberDSP);
    			getch();
    			return 0;
    		}
    		// Если запрос выполнился без ошибок
    		else
    		{
    			// Вывод информации об успешном включении первого канала устройства
    			printf("Second channel activation is successful...\n\r");
    		}
    	}
    
    	// Опрос коэффициента усиления по первому каналу АЦП
    	Err = ZGetAmplifyADC(typeDevice, numberDSP, 0, &amplifyADC0);
    	// Если опрос выполнился с ошибкой
    	if(Err != 0)
    	{
    		// Вывод информации об ошибке
    		printf("ZGetAmplifyADC() return Error = 0x%X\n\r", Err);
    		// Отключение от драйвера устройства
    		Err = ZClose(typeDevice, numberDSP);
    		getch();
    		return 0;
    	}
    	// Если опрос выполнился без ошибок
    	else
    	{
    		// Вывод коэффициента усиления по первому каналу АЦП
    		printf("First channel amplifier: %f\n\r", amplifyADC0);
    	}
    	// Если количество каналов устройства больше одного
    	if(numChannelsADC > 1)
    	{
    		// Опрос коэффициента усиления по второму каналу АЦП
    		Err = ZGetAmplifyADC(typeDevice, numberDSP, 1, &amplifyADC1);
    		// Если опрос выполнился с ошибкой
    		if(Err != 0)
    		{
    			// Вывод информации об ошибке
    			printf("ZGetAmplifyADC() return Error = 0x%X\n\r", Err);
    			// Отключение от драйвера устройства
    			Err = ZClose(typeDevice, numberDSP);
    			getch();
    			return 0;
    		}
    		// Если опрос выполнился без ошибок
    		else
    		{
    			// Вывод коэффициента усиления по второму каналу АЦП
    			printf("Second channel amplifier: %f\n\r", amplifyADC1);
    		}
    	}
    
    	// Опрос веса младшего разряда АЦП первого канала устройства
    	Err = ZGetDigitalResolChanADC(typeDevice, numberDSP, 0, &resolutionADC0);
    	// Если опрос выполнился с ошибкой
    	if(Err != 0)
    	{
    		// Вывод информации об ошибке
    		printf("ZGetDigitalResolChanADC() return Error = 0x%X\n\r", Err);
    		// Отключение от драйвера устройства
    		Err = ZClose(typeDevice, numberDSP);
    		getch();
    		return 0;
    	}
    	// Если опрос выполнился без ошибок
    	else
    	{
    		// Вывод веса младшего разряда АЦП первого канала устройства
    		printf("First channel digital resolution: %f\n\r", resolutionADC0);
    	}
    	// Если количество каналов устройства больше одного
    	if(numChannelsADC > 1)
    	{
    		//  Опрос веса младшего разряда АЦП второго канала устройства
    		Err = ZGetDigitalResolChanADC(typeDevice, numberDSP, 1, &resolutionADC1);
    		// Если опрос выполнился с ошибкой
    		if(Err != 0)
    		{
    			// Вывод информации об ошибке
    			printf("ZGetDigitalResolChanADC() return Error = 0x%X\n\r", Err);
    			// Отключение от драйвера устройства
    			Err = ZClose(typeDevice, numberDSP);
    			getch();
    			return 0;
    		}
    		else
    		{
    			// Вывод веса младшего разряда АЦП второго канала устройства
    			printf("Second channel digital resolution: %f\n\r", resolutionADC1);
    		}
    	}
    	Err = ZSetInputADC(typeDevice, numberDSP, 0.0, 1);
    	Err = ZSetInputADC(typeDevice, numberDSP, 1.0, 1);
    	Err = ZSetInputADC(typeDevice, numberDSP, 2.0, 0);
    	Err = ZSetInputADC(typeDevice, numberDSP, 3.0, 0);
    	Err = ZSetInputADC(typeDevice, numberDSP, 4.0, 0);
    	Err = ZSetInputADC(typeDevice, numberDSP, 5.0, 0);
    	Err = ZSetInputADC(typeDevice, numberDSP, 6.0, 0);
    	Err = ZSetInputADC(typeDevice, numberDSP, 7.0, 0);
    	Err = ZSetInputADC(typeDevice, numberDSP, 8.0, 0);
    	Err = ZSetInputADC(typeDevice, numberDSP, 9.0, 0);
    	Err = ZSetInputADC(typeDevice, numberDSP, 10.0, 0);
    	Err = ZSetInputADC(typeDevice, numberDSP, 11.0, 0);
    	Err = ZSetInputADC(typeDevice, numberDSP, 12.0, 0);
    	Err = ZSetInputADC(typeDevice, numberDSP, 13.0, 0);
    	Err = ZSetInputADC(typeDevice, numberDSP, 14.0, 0);
    	Err = ZSetInputADC(typeDevice, numberDSP, 15.0, 0);
    	if (Err != 0)
    	{
    		// Вывод информации об ошибке
    		printf("Function ZSetInputADC() return Error = 0x%X\n\r", Err);
    		// Отключение от драйвера устройства
    		Err = ZClose(typeDevice, numberDSP);
    		_getch();;
    		return 0;
    	}
    
    	// Опрос количества включенных каналов АЦП устройства
    	Err = ZGetNumberInputADC(typeDevice, numberDSP, &numChannelsADC);
    	// Если опрос выполнился с ошибкой
    	if(Err != 0)
    	{
    		// Вывод информации об ошибке
    		printf("Function ZGetNumberInputADC() return Error = 0x%X\n\r", Err);
    		// Отключение от драйвера устройства
    		Err = ZClose(typeDevice, numberDSP);
    		getch();
    		return 0;
    	}
    	// Если опрос выполнился без ошибок
    	else
    	{
    		// Вывод количества включенных каналов АЦП устройства
    		printf("Quantity of activated ADC channel: %ld\n\r", numChannelsADC);
    	}
    
    	// Опрос количества слов в одном отсчета АЦП устройства
    	Err = ZGetWordsADC(typeDevice, numberDSP, &numWordsADC);
    	// Если опрос выполнился с ошибкой
    	if(Err != 0)
    	{
    		// Вывод информации об ошибке
    		printf("ZGetWordsADC() return Error = 0x%X\n\r", Err);
    		// Отключение от драйвера устройства
    		Err = ZClose(typeDevice, numberDSP);
    		getch();
    		return 0;
    	}
    	// Если опрос выполнился без ошибок
    	else
    	{
    		// Вывод количества слов в одном отсчете АЦП устройства
    		printf("Quantity of words: %ld\n\r", numWordsADC);
    	}
    
    	//список возможных частот дискретизации
    	long next = 0;
    	double  freqIn = 0;
    	double  freq = 0;
    	printf("List of possible discret. freq ");
    	while (1) //бесконечный цикл
    	{
    		Err = ZGetListFreqADC(typeDevice, numberDSP, next, &freq); //получить
    		if (freq > freqIn && freq <250000.0)
    			freqIn = freq;
    		//значение частоты
    		if (Err != 0) break; //если ошибка, то выход из цикла
    		printf("%E Hz\n", freq); //распечатать значение частоты
    		next = 1; //при следующем обращении, будет
    		//считываться следующее значение частоты
    	}
    	double freqOut = 0;
    	printf("MAX discret. freq");
    	printf("%E Hz\n", freqIn);
    
    	Err = ZSetFreqADC(typeDevice, numberDSP, freqIn, &freqOut);
    	if (Err != 0)
    	{
    		// Вывод информации об ошибке
    		printf("Function ZSetFreqADC() return Error = 0x%X\n\r", Err);
    		// Отключение от драйвера устройства
    		Err = ZClose(typeDevice, numberDSP);
    		_getch();;
    		return 0;
    	}
    
    	printf("Setup discret. freq");
    	printf("%E Hz\n", freqOut);
    
    	// Проверка переменных, чтобы избежать деления на ноль
    	if(numWordsADC == 0 || amplifyADC0 == 0 || amplifyADC1 == 0)
    	{
    		// Вывод информации об ошибке
    		printf("Error DAC parameters\n\r");
    		// Отключение от драйвера устройства
    		Err = ZClose(typeDevice, numberDSP);
    		getch();
    		return 0;
    	}
    
    	// Запрос буфера АЦП
    	Err = ZGetBufferADC(typeDevice, numberDSP, (void**) &pBuffer16ADC, &sizeBufferADC);
    	// Если запрос выполнился с ошибкой
    	if(Err != 0)
    	{
    		// Вывод информации об ошибке
    		printf("Function ZGetBufferADC() return Error = 0x%X\n\r", Err);
    		// Отключение от драйвера устройства
    		Err = ZClose(typeDevice, numberDSP);
    		getch();
    		return 0;
    	}
    	pBuffer32ADC = (long*) pBuffer16ADC;
    
    	// Запрос на останов АЦП
    	Err = ZStopADC(typeDevice, numberDSP);
    	// Запрос на запуск АЦП
    	Err = ZStartADC(typeDevice, numberDSP);
    
    	ofstream file;
    	file.open("test.txt", ios_base::out);
    
    	// Цикл чтения данных АЦП
    	while(!kbhit())
    	{
    		// Задержка обновления данных АЦП для отображения
    		//Sleep(10);
    
    		// Запрос указателя на текущий элемент буфера
    		Err = ZGetPointerADC(typeDevice, numberDSP, &pointerADC);
    		// Если запрос выполнился с ошибкой
    		if(Err != 0)
    		{
    			// Вывод информации об ошибке
    			printf("Function ZGetPointerADC() return Error = 0x%X\n\r", Err);
    			// Выход из цикла
    			break;
    		}
    
    		// Если новые данные в буфер от АЦП не поступили, то перейти в начало цикла и подождать
    		//if(pointerADC == pointerADC_old)
    			//continue;
    
    		// Обновление предыдущего значения указателя
    		pointerADC_old = pointerADC;
    
    		// Переход на отсчет первого включенного канала последнего кадра АЦП
    		if(pointerADC - numWordsADC * numChannelsADC < 0)
    			pointerADC = sizeBufferADC + pointerADC - numWordsADC * numChannelsADC;
    		else 
    			pointerADC = pointerADC - numWordsADC * numChannelsADC; 
    
    		// Вычисление из целого значения отсчета АЦП вещественного значение отсчета (в вольтах) для первого канала
    		//if(numWordsADC == 1)
    			volt0 = resolutionADC0 * (pBuffer16ADC[pointerADC]) / amplifyADC0;
    		//else
    			//volt0 = resolutionADC0 * (pBuffer32ADC[pointerADC / numWordsADC]) / amplifyADC0;
    
    		// Вывод мгновенного значения напряжения для первого канала
    		printf("%+8.4f", volt0);
    
    		// Если количество каналов устройства больше одного
    		if(numChannelsADC > 1)
    		{
    			// Переход на следующий отсчет АЦП
    			pointerADC += numWordsADC;
    			
    			// При выходе за границу буфера, осуществляется переход в начало
    			if(pointerADC >= sizeBufferADC)
    				pointerADC = pointerADC - sizeBufferADC;
    
    			// Вычисление из целого значения отсчета АЦП вещественного значение отсчета (в вольтах) для второго канала
    			//if(numWordsADC == 1)
    				volt1 = resolutionADC1 * (pBuffer16ADC[pointerADC]) / amplifyADC1;
    			//else
    				//volt1 = resolutionADC1 * (pBuffer32ADC[pointerADC/numWordsADC]) / amplifyADC1;
    
    			// Вывод мгновенного значения напряжения для второго канала
    			printf("\t%+8.4f", volt1);
    		}
    		printf("\n\r");
    		file << volt0 << " " << volt1 << endl;
    	}
    	file.close();
    
    	// Запрос на останов АЦП
    	Err = ZStopADC(typeDevice, numberDSP);
    	// Если запрос выполнился с ошибкой
    	if(Err != 0)
    	{
    		// Вывод информации об ошибке
    		printf("Function ZStopADC() return Error = 0x%X\n\r", Err);
    	}
    
    	// Запрос на освобождение буфера АЦП
    	if(pBuffer16ADC != NULL)
    	{
    		Err = ZRemBufferADC(typeDevice, numberDSP, (void**) &pBuffer16ADC);
    		// Если запрос выполнился с ошибкой
    		if(Err != 0)
    		{
    			// Вывод информации об ошибке
    			printf("Function ZRemBufferADC() return Error = 0x%X\n\r", Err);
    		}
    	}
    
    	// Отключение от драйвера устройства
    	Err = ZClose(typeDevice, numberDSP);
    	// Если запрос выполнился с ошибкой
    	if(Err != 0)
    	{
    		// Вывод информации об ошибке
    		printf("Function ZClose() return Error = 0x%X\n\r", Err);
    	}
    
    	if(!kbhit())
    		getch();
    
    	printf("Press any key for exit...");
    	getch();
    
     	return 0;
    }
    
    #98639

    Добрый день!
    Во-первых, Вы в бесконечном цикле считываете значения, поступившие в буфер АЦП и не используете Sleep, что будет приводить к тому, что ваша программа будет зависать.
    Во-вторых, в файл Вы выводите одно единственное значение, полученное, когда указатель в буфере АЦП меняет свое значение. Указатель буфера изменяет свое значение не на один отсчет за раз, а на гораздо большее число. Это означает, что за одно изменение указателя в буфере появляется не одно новое значение, а много. Таким образом, чтобы получить в файле синус, Вам нужно писать туда все новые пришедшие отсчеты. Все новые пришедшие отсчеты хранятся в буфере с индекса pointerADC_old до индекса pointerADC (естественно нужно учитывать количество каналов и количество слов в одном отсчете АЦП).

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

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

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

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

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

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

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