создание анализатора гармоник мощности, который будет измерять амплитуды основной и кратных ей частот (например, 50 Гц, 100 Гц, 150 Гц, 200 Гц,...)

Я намеревался создать анализатор гармоник промышленной частоты, который будет измерять амплитуды основной и кратных ей частот (например, 50 Гц, 100 Гц, 150 Гц, 200 Гц,...). Есть примеры создания анализатора спектра с библиотекой FFT. вот пример библиотеки fft, созданной косомой

   #include <arduinoFFT.h>

   #define SAMPLES 128             //Должна быть степенью 2
   #define SAMPLING_FREQUENCY 1000 //Гц, должно быть меньше 10000 из-за АЦП

   arduinoFFT FFT = arduinoFFT();

   unsigned int sampling_period_us;
   unsigned long microseconds;

   double vReal[SAMPLES];
   double vImag[SAMPLES];

   void setup() {
        Serial.begin(115200);

        sampling_period_us = round(1000000*(1.0/SAMPLING_FREQUENCY));
   }

   void loop() {

        /*SAMPLING*/
        for(int i=0; i<SAMPLES; i++)
        {
            microseconds = micros();    //Переполняется примерно через 70 минут!

            vReal[i] = analogRead(0);
            vImag[i] = 0;

            while(micros() < (microseconds + sampling_period_us)){
            }
        }

        /*FFT*/
        FFT.Windowing(vReal, SAMPLES, FFT_WIN_TYP_HAMMING, FFT_FORWARD);
        FFT.Compute(vReal, vImag, SAMPLES, FFT_FORWARD);
        FFT.ComplexToMagnitude(vReal, vImag, SAMPLES);
        double peak = FFT.MajorPeak(vReal, SAMPLES, SAMPLING_FREQUENCY);

        /*PRINT RESULTS*/
        //Serial.println(пик); //Распечатываем, какая частота является наиболее доминирующей.

        for(int i=0; i<(SAMPLES/2); i++)
        {
            /*View all these three lines in serial terminal to see which frequencies has which amplitudes*/

            //Serial.print((i * 1.0 * SAMPLING_FREQUENCY) / SAMPLES, 1);
            //Serial.print(" ");
            Serial.println(vReal[i], 1);    //Просмотр только этой строки в последовательном плоттере для визуализации ячеек
        }

        //задержка(1000); //Повторяем процесс каждую секунду ИЛИ:
        while(1);       //Запускаем код один раз
   } 

Как я могу разделить амплитуды для определенных частот, например, амплитуду 50 Гц = ?, 150 Гц = ? и сохраните их в других переменных

, 👍0

Обсуждение

используйте кнопку {} для форматирования кода, @jsotola


1 ответ


1

Общая идея вашего кода выглядит нормально, но рассмотрите возможность использования аппаратного таймера вместо цикла for для сбора данных. Частота выборки будет намного более точной и однородной, поскольку вы устраняете (возможно, кумулятивные) ошибки во времени. Пример см. в этом сообщении.

Знаете ли вы, как работает функция FFT.MajorPeak? Если он просто находит частоту самой большой точки в спектре магнитуды, это может быть не очень хорошим показателем пика 50 Гц и т. д. Вместо этого рассмотрите возможность взять площадь под кривой вокруг интересующей частоты f_0, скажем, от f_0 - 2 Гц до f_0 + 2 Гц. Тот же код можно использовать для измерения спектральной мощности любой гармоники.

Также обратите внимание, что частота электросети не равна точно 50/60 Гц. Кратковременное изменение составляет около плюс/минус 1 Гц. Описанный выше подход также поможет получить надежные показания.

,