ESP32S3 fft samples
Posted: Sat Mar 02, 2024 10:10 am
I have an accelerometer interfaced to 24 bit ADC, and the ADC is interfaced to ESP32S3 using SPI protocol. My aim is to detect frequency peak using fft function.
Right now the i'm taking 1024 sampless for fft calculation, If I put 16384 instead of 1024, the arduino IDE throws error saying
/xtensa-esp32s3-elf/bin/ld.exe: region `dram0_0_seg' overflowed by 498464 bytes
how can I solve this error.
Right now the i'm taking 1024 sampless for fft calculation, If I put 16384 instead of 1024, the arduino IDE throws error saying
/xtensa-esp32s3-elf/bin/ld.exe: region `dram0_0_seg' overflowed by 498464 bytes
how can I solve this error.
Code: Select all
#include <SPI.h>
#include <arduinoFFT.h>
#define CS_PIN 5
#define DRDY_PIN 22
#define RST_PIN 21
int j;
#define SPISPEED 2500000
#define SAMPLING_FREQUENCY 30000
#define SAMPLES 1024
arduinoFFT FFT = arduinoFFT();
unsigned long microseconds = 0;
#define BUFFER_SIZE (30000)
unsigned int sampling_period_us;
double vReal[SAMPLES];
double vImag[SAMPLES];
double xaxis[SAMPLES/2];
#define STATUS_REG 0x00
#define MUX_REG 0x01
#define ADCON_REG 0x02
#define DRATE_REG 0x03
#define WAKEUP_CMD 0x00
#define RDATA_CMD 0x01
#define RREG_CMD 0x10
#define WREG_CMD 0x50
#define SELFCAL_CMD 0xF0
#define SYNC_CMD 0xFC
#define STANDBY_CMD 0xFD
#define RESET_CMD 0xFE
#define VREF (2.5)
#define SENSITIVITY (40.0) // Sensitivity in mV/g
#define OFFSET_CORRECTION (2.5) // Offset correction in volts
#define DRATE_30K (0xF0)
#define STATUS_REG_0x03 (0x03)
#define ADCON_REG_VALUE (0x21)
#define DRATE_REG_VALUE (DRATE_30K)
#define MUX_REG_VALUE (B00001000)
volatile int DRDY_state = HIGH;
float adc_volt[BUFFER_SIZE];
void writeRegister(uint8_t address, uint8_t value)
{
SPI.transfer( WREG_CMD | address );
SPI.transfer( 0x00 );
SPI.transfer( value );
delayMicroseconds( 100 );
}
void setup()
{
Serial.begin(115200);
Serial.println( "ADS1256 test program" );
START_SPI();
attachInterrupt( DRDY_PIN, DRDY_Interrupt, FALLING );
}
void loop()
{
int sampleCount = 0;
float meanValue = 0.0;
// Collect data and compute mean
while (true) {
uint32_t t0 = micros();
for (int i = 0; i < BUFFER_SIZE; i++) {
waitDRDY();
adc_volt[i] = READ_ADC();
meanValue += adc_volt[i];
delayMicroseconds(10);
sampleCount++;
if (sampleCount >= BUFFER_SIZE) {
meanValue /= BUFFER_SIZE;
sampleCount = 0;
}
}
// Subtract mean from each data value
for (int i = 0; i < BUFFER_SIZE; i++) {
adc_volt[i] -= meanValue;
}
fft(adc_volt);
}
}
void fft(float* samples)
{
uint32_t start = 0;
for (int i = start; i < (BUFFER_SIZE - SAMPLES / 2); i += SAMPLES / 2)
{
// now put data into vReal and vImag
for (int j = 0; j < SAMPLES; j++) {
vReal[j] = samples[i + j];
vImag[j] = 0;
}
// now you're ready to compute the FFT
FFT.Windowing(vReal, SAMPLES, FFT_WIN_TYP_HANN, FFT_FORWARD);
FFT.Compute(vReal, vImag, SAMPLES, FFT_FORWARD);
FFT.ComplexToMagnitude(vReal, vImag, SAMPLES);
double peak = FFT.MajorPeak(vReal, SAMPLES, SAMPLING_FREQUENCY);
Serial.print("Peak frequency is: ");
Serial.println(peak);
// Print frequency values along with vReal values
for (int k = 0; k < SAMPLES / 2; k++) {
xaxis[k] = (k / (double)(SAMPLES / 2)) * (SAMPLING_FREQUENCY / 2.0);
// Serial.print("Frequency: ");
// Serial.print(xaxis[k]);
// Serial.print(" Hz, vReal: ");
// Serial.println(vReal[k]);
}
}
}
float READ_ADC()
{
int32_t adc_raw;
SPI.beginTransaction(SPISettings(SPISPEED, MSBFIRST, SPI_MODE1));
digitalWrite(CS_PIN, LOW);
SPI.transfer( RDATA_CMD );
delayMicroseconds(5);
adc_raw = 0;
adc_raw |= SPI.transfer(0);
adc_raw <<= 8;
adc_raw |= SPI.transfer(0);
adc_raw <<= 8;
adc_raw |= SPI.transfer(0);
digitalWrite(CS_PIN, HIGH);
SPI.endTransaction();
if (adc_raw & (1<<23)) {
adc_raw |= 0xFF000000;
}
float v = adc_raw * (float)(VREF / (1<<23));
float acceleration = (v - OFFSET_CORRECTION) / SENSITIVITY;
return acceleration;
//return( v );
}
void DRDY_Interrupt()
{
DRDY_state = LOW;
}
void waitDRDY()
{
while (DRDY_state == HIGH) {
continue;
}
DRDY_state = HIGH;
}
void START_SPI ()
{
sampling_period_us = round(1000000*(1.0/SAMPLING_FREQUENCY));
pinMode(CS_PIN, OUTPUT);
digitalWrite(CS_PIN, HIGH);
pinMode(DRDY_PIN, INPUT);
pinMode(RST_PIN, OUTPUT);
digitalWrite(RST_PIN, LOW);
delay(1);
digitalWrite(RST_PIN, HIGH);
delay(500);
SPI.begin();
delay(500);
while (digitalRead(DRDY_PIN)) {}
SPI.beginTransaction(SPISettings(SPISPEED, MSBFIRST, SPI_MODE1));
digitalWrite(CS_PIN, LOW);
delayMicroseconds(100);
SPI.transfer( RESET_CMD );
delay(5);
writeRegister( STATUS_REG, STATUS_REG_0x03 );
writeRegister( ADCON_REG, ADCON_REG_VALUE );
writeRegister( DRATE_REG, DRATE_REG_VALUE );
writeRegister( MUX_REG, MUX_REG_VALUE );
SPI.transfer( SELFCAL_CMD );
uint32_t t0 = micros();
while (digitalRead(DRDY_PIN)!=LOW && micros()-t0 < 10000) {}
while (digitalRead(DRDY_PIN)!=HIGH && micros()-t0 < 10000) {}
digitalWrite(CS_PIN, HIGH);
SPI.endTransaction();
}