Hi Folks,
This is my first post on the forum, i have read the "how to use this forum", but didn't found anything about introducing new user on special topic, so i just hope i don't violate anything... If so, let me know.
I'm working on a project with an ESP32 and an ADXL337, which purpose is to detect vibration frequency and amplitude on mechanical devices.
From what i have seen, max sampling rate is 1600Hz on X&Y and 550Hz on Z for the ADXL337, which let me work in the frequency range 0->800Hz on X&Y and 0-275Hz for Z. That's fine for what i'm looking at.
I have use ArduinoFFT (GitHub - kosme/arduinoFFT: Fast Fourier Transform for Arduino) to compute Frequency/Amplitude from the Time/amplitude acquisition.
Actually i use only X axis for testing. I'm sampling at 512Hz and i'm using 1024 samples (which means that my acquisition lasts 2s, but no problem, because i don't need real time).
Shaking the ADXL337 i can actually achieve easily 5/6 hz Freq. The result of the FFT is nice for the frequency, which gives me a huge peak at 5.5 hz. By the way, i don't understand the amplitude.
it is said that the amplitude, should be the same that in the time/amplitude domain. As i'm using an ESP32, the range of the ADC is 0-4095. So amplitude in the Freq/Amplitude domain should not be greater than my ADC range. But at the peak Frequency (5.5Hz) i have an amplitude of 613881 !!!
Do i miss something, is there some normalization to do on the amplitude ?
Here is the code, largely inspired from examples :
//----
//inspiré de https://github.com/G6EJD/ESP32-8266-Audio-Spectrum-Display
// de https://github.com/kosme/arduinoFFT/blob/master/Examples/FFT_01/FFT_01.ino (ArduinoFFT)
//----
#include <arduinoFFT.h>
//max Sampling rate of ADXL337 is 1600Hz on X&Y and 550Hz on Z
arduinoFFT FFT = arduinoFFT();
#define SAMPLES 1024 //Must be a power of 2
#define SAMPLING_FREQUENCY 512 //Hz. Determines maximum frequency that can be analysed by the FFT.
unsigned int sampling_period_us;
unsigned long microseconds;
double vRealADC[SAMPLES];
double vReal[SAMPLES];
double vImag[SAMPLES];
// ADXL337 is connected to ESP32 Analog pins :
const int ADXL_ZPin = 32; //Z
const int ADXL_YPin = 35; //Y
const int ADXL_XPin = 34; //X
// variable for storing the analog value for raw acceleration on each axis
int rawZ = 0;
int rawY = 0;
int rawX = 0;
// Scaled values for each axis
float scaledX, scaledY, scaledZ;
void setup() {
Serial.begin(256000);
sampling_period_us = round(1000000 * (1.0 / SAMPLING_FREQUENCY));
pinMode(ADXL_ZPin, INPUT);
pinMode(ADXL_YPin, INPUT);
pinMode(ADXL_XPin, INPUT);
delay(1000);
}
void loop() {
rawX=0;
for (int i = 0; i < SAMPLES; i++)
{
microseconds = micros();
rawX = analogRead(ADXL_XPin);
vRealADC[i] = rawX;
vReal[i] = rawX;
vImag[i] = 0;
//wait for next sampling time according to freq
while (micros() < (microseconds + sampling_period_us)) { }
}
FFT.Windowing(vReal, SAMPLES, FFT_WIN_TYP_HAMMING, FFT_FORWARD);
FFT.Compute(vReal, vImag, SAMPLES, FFT_FORWARD);
FFT.ComplexToMagnitude(vReal, vImag, SAMPLES);
Serial.println("+++ Freq / Amplitude +++++");
for(int i=0; i<(SAMPLES/2); i++) {
Serial.print((i * 1.0 * SAMPLING_FREQUENCY) / SAMPLES, 1);
Serial.print("\t");
Serial.println(vReal[i]);
}
Serial.println("*** ADC val ***");
for(int i=0; i<(SAMPLES); i++) {
Serial.println(vRealADC[i]);
}
}
Many thx for your help
Cédric