ESP32S3 fft samples

riddhesh
Posts: 1
Joined: Tue Feb 27, 2024 11:29 am

ESP32S3 fft samples

Postby riddhesh » 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.

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(); 
}



Who is online

Users browsing this forum: No registered users and 124 guests