СЦБИСТ - железнодорожный форум, блоги, фотогалерея, социальная сеть СЦБИСТ - железнодорожный форум, блоги, фотогалерея, социальная сеть
Показать сообщение отдельно
Старый 26.01.2016, 15:47   #1319 (ссылка)
ЛИИЖТ АТ-103 (1981-1986)
 
Аватар для Просто инженер АиТ

Регистрация: 16.10.2012
Адрес: Где резной палисад
Возраст: 64
Сообщений: 980
Поблагодарил: 220 раз(а)
Поблагодарили 140 раз(а)
Фотоальбомы: не добавлял
Репутация: 380
Цитата:
сегодня наконец-то подключили к РШ на измерительной панели к переменке, заработало , но не сразу (кондер подбирали для сглаживания пульсации) на мосте.
Мы тоже делали контроллер для аналогово съёма напряжения на том же процессоре, что стоит в Arduino. Но мы не сглаживали, а сразу оцифровали, считали средне квадратичное и делали быстрое преобразование Фурье для спектрального анализа. Считывание с АЦП по прерываниям от таймера, остальная обработка на фоне.
Я, когда (году 1987, книг тогда не было и я учился по чужим исходникам) изучал 'С' после ассемблера и Бейсика, тоже не мог привыкнуть!

Просто инженер АиТ добавил 26.01.2016 в 16:49
Чтобы не скучно было.
/*------------------------------------------------------------------------------
Класс Фурье преобразования
05.03.2015 13:35
------------------------------------------------------------------------------*/
class TFure
{
private:
// Параметры для Спектрального Анализа
public:
TFure ( ) : FureA ( NULL ), FureB ( NULL ), FureC ( NULL ),
Buff ( NULL )
{ }

~TFure ( )
{
if ( FureA != NULL )
{ delete ( FureA ); FureA = NULL; }
if ( FureB != NULL )
{ delete ( FureB ); FureB = NULL; }
if ( FureC != NULL )
{ delete ( FureC ); FureC = NULL; }
if ( Buff != NULL )
{ delete ( Buff ); Buff = NULL; }
}
//-----------------------------------------
// Исходные данные Спектрального Анализа.
int Count; // Общее кол-во Отсчётов в Выборке.
// Всегда должно быть Count >= FrequencyDiscr.
int FrequencyDiscr; // Частота Дискретизации, на каком
// кол-во отсчётов следует определять
// Спектральный анализ.
int StepFrequency; // Шаг Частоты определени
// Спектрального Анализа.
//------------------------------------------------------------
int CountPoints; // Необходимое кол-во Отсчётов дл
// требуемого Шага Частоты.
// Вычисление CountPoints = FrequencyDiscr/StepFrequency;
//------------------------------------------------------------
int CountHarmonicFrequency; // Кол-во Гармоник
//------------------------------------------------------------
int FrViewBeg; // Частота начала Сп. Анализа.
int FrViewEnd; // Частота конца Сп. Анализа.

int IndViewBeg; // Индекс начала Сп. Анализа.
int IndViewEnd; // Индекс конца Сп. Анализа.
//------------------------------------------------------------
Word* Buff; // Указатель на Буфер.
//--------------------------------------
// Преобразование Фурье.
double* FureA; // Коэффициенты А.
double* FureB; // Коэффициенты В.
double* FureC; // Коэффициенты С.
double FureCMax; // Максимум.
double IndCMax; // Индекс Максимума.
//-----------------------------------------
// Преобразование Фурье 27.02.2014 16:42
void MakeFure ( int _StepFrequency );

};
/*------------------------------------------------------------------------------
Преобразование Фурье
27.02.2014 16:42
------------------------------------------------------------------------------*/
void TFure::MakeFure ( int _StepFrequency ) // Шаг Частоты Дискретизации.
{
if ( _StepFrequency == 0 )
return;

StepFrequency = _StepFrequency;
// Определим сколько точек надо Анализировать?
/*
Так как полное количество точек определяетс количеством точек на 1 секунду
при частоте дискретизации для файла Wav равное FrequencyDiscr, тогда
T = 1 / FrequencyDiscr;
Дл исследуемой частоты, гармоники, которой будем вычислять период будет
равен t = 1 / StepFrequency.
А количество точек определится из отношени t/T. После некоторых
преобразований получаем CountPoints = FrequencyDiscr/StepFrequency;
*/
CountPoints = FrequencyDiscr/StepFrequency;
double K = 2.0/CountPoints;
double DeltaT = K * M_PI;
//-------------------------------------------------------------------
// Создадим буфера для Коэффициентов по кол-во Гармоник.

// Количество Гармоник.
CountHarmonicFrequency = (FrViewEnd - StepFrequency)/StepFrequency + 1;
IndViewBeg = FrViewBeg/StepFrequency;
IndViewEnd = FrViewEnd/StepFrequency + 1;
//-------------------------------------------------------------------
if ( FureA != NULL )
{ delete ( FureA ); FureA = NULL; }
if ( FureB != NULL )
{ delete ( FureB ); FureB = NULL; }
if ( FureC != NULL )
{ delete ( FureC ); FureC = NULL; }
FureA = new double[CountHarmonicFrequency];
FureB = new double[CountHarmonicFrequency];
FureC = new double[CountHarmonicFrequency];
//----------------------------------------
if ( FureA == NULL
|| FureB == NULL
|| FureC == NULL )
return;
//----------------------------------------
int SizeFure = CountHarmonicFrequency*sizeof(double);
memset ( FureA, 0, SizeFure );
memset ( FureB, 0, SizeFure );
memset ( FureC, 0, SizeFure );
//-------------------------------------------------------------------
// Бежим по Отсчётам.
for ( int j=0; j < CountPoints; j++ )
{
//------------------------------------------------
// Получить значение Отсчёта.
double CurAmp = Buff[j];
//------------------------------------------------
// Бежим по гармоникам.
for ( int i=1; i <= CountHarmonicFrequency; i++ )
{
FureA[i-1] += CurAmp * cos( (j*i*DeltaT));
FureB[i-1] += CurAmp * sin( (j*i*DeltaT));
}
}
//-------------------------------------------------------------------
// Получить Модуль Вектора.
FureCMax = 0;
IndCMax = 0;
for ( int i=0; i < CountHarmonicFrequency; i++ )
{
FureC[i] = sqrt( K * ((FureA[i]*FureA[i])
+ (FureB[i]*FureB[i])) );
if ( FureCMax < FureC[i] )
{
FureCMax = FureC[i];
IndCMax = i;
}
}
}
__________________
Не важна реальность, важно как мы к ней относимся!

Последний раз редактировалось Просто инженер АиТ; 26.01.2016 в 15:47. Причина: Добавлено сообщение
Просто инженер АиТ вне форума   Цитировать 0
Комментариев к сообщению: 1 (нажмите, чтобы увидеть)  Нажмите здесь, чтобы написать комментарий к этому сообщению