Saving analog values into an array

Hi, I am using an external ADS1256 ADC to read a sinusoidal signal and send it to ESP32 microcontroller using SPI protocol and store these in an array.
but I’m confused about coding with array. The code I attached reads data but when I try to save it in an array, only single data value is saved until the time for loop is executed.

#include <SPI.h>
#include <arduinoFFT.h>

#define cs 5 // chip select
#define rdy 25 // data ready, input
#define rst 26 // may omit

#define SPISPEED 2500000   // Teensy 3.2 @120 mhz
#define SAMPLES 1024 

float valuenew;

#define DEBUG 1



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

double k[SAMPLES];
double a[SAMPLES];
void setup()
{
  #if DEBUG
  while(!Serial);
#endif
  Serial.begin(115200); 
  pinMode(cs, OUTPUT);
  digitalWrite(cs, LOW); // tied low is also OK.
  pinMode(rdy, INPUT);
  pinMode(rst, OUTPUT);
  digitalWrite(rst, LOW);
  delay(1); // LOW at least 4 clock cycles of onboard clock. 100 microseconds is enough
  digitalWrite(rst, HIGH); // now reset to default values
  
  delay(500);
  SPI.begin(); //start the spi-bus
  delay(500);

  //init
  while (digitalRead(rdy)) {}  // wait for ready_line to go low
  SPI.beginTransaction(SPISettings(SPISPEED, MSBFIRST, SPI_MODE1)); // start SPI
  digitalWrite(cs, LOW);
  delayMicroseconds(100);

  //Reset to Power-Up Values (FEh)
  SPI.transfer(0xFE);
  delay(5);


  byte status_reg = 0x00 ;  // address (datasheet p. 30)
  byte status_data = 0x01; // 01h = 0000 0 0 0 1 => status: Most Significant Bit First, Auto-Calibration Disabled, Analog Input Buffer Disabled
  //byte status_data = 0x07; // 01h = 0000 0 1 1 1 => status: Most Significant Bit First, Auto-Calibration Enabled, Analog Input Buffer Enabled
  SPI.transfer(0x50 | status_reg);
  SPI.transfer(0x00);   // 2nd command byte, write one register only
  SPI.transfer(status_data);   // write the databyte to the register
  delayMicroseconds(100);
  

  byte adcon_reg = 0x00; //A/D Control Register (Address 02h)
  //byte adcon_data = 0x20; // 0 01 00 000 => Clock Out Frequency = fCLKIN, Sensor Detect OFF, gain 1
  byte adcon_data = 0x00; // 0 00 00 000 => Clock Out = Off, Sensor Detect OFF, gain 1
  //byte adcon_data = 0x01;   // 0 00 00 001 => Clock Out = Off, Sensor Detect OFF, gain 2
  SPI.transfer(0x50 | adcon_reg);  // 52h = 0101 0010
  SPI.transfer(0x00);              // 2nd command byte, write one register only
  SPI.transfer(adcon_data);        // write the databyte to the register
  delayMicroseconds(100);


  byte drate_reg = 0x03; //DRATE: A/D Data Rate (Address 03h)
  byte drate_data = 0xF0; // F0h = 11110000 = 30,000SPS
  SPI.transfer(0x50 | drate_reg);
  SPI.transfer(0x00);   // 2nd command byte, write one register only
  SPI.transfer(drate_data);   // write the databyte to the register
  delayMicroseconds(100);

  // Perform Offset and Gain Self-Calibration (F0h)
  SPI.transfer(0xF0);     
  delay(400);
  digitalWrite(cs, HIGH);
  SPI.endTransaction();

}


void loop()
{
#if DEBUG
  unsigned long start_timestamp = micros();
#endif
  //Single ended Measurements
  unsigned long adc_val[8] = {0,0,0,0,0,0,0,0}; // store readings in array
  byte mux[8] = {0x08,0x18,0x28,0x38,0x48,0x58,0x68,0x78};
  int i = 0;

  SPI.beginTransaction(SPISettings(SPISPEED, MSBFIRST, SPI_MODE1)); // start SPI
  digitalWrite(cs, LOW);
  delayMicroseconds(2);
  

  for (i=0; i <= 7; i++){         // read all 8 Single Ended Channels AINx-AINCOM
  byte channel = mux[i];             // analog in channels # 
  
  while (digitalRead(rdy)) {} ;                          


 
  SPI.transfer(0x50 | 0x01); // 1st Command Byte: 0101 0001  0001 = MUX register address 01h
  SPI.transfer(0x00);     // 2nd Command Byte: 0000 0000  1-1=0 write one byte only
  SPI.transfer(channel);     // Data Byte(s): xxxx 1000  write the databyte to the register(s)
  delayMicroseconds(2);

  //SYNC command 1111 1100                               // ********** Step 2 **********
  SPI.transfer(0xFC);
  delayMicroseconds(2);


  SPI.transfer(0x00);
  delayMicroseconds(250);   // Allow settling time


  SPI.transfer(0x01); // Read Data 0000  0001 (01h)       // ********** Step 3 **********
  delayMicroseconds(5);
  
  adc_val[i] = SPI.transfer(0);
  adc_val[i] <<= 8; //shift to left
  adc_val[i] |= SPI.transfer(0);
  adc_val[i] <<= 8;
  adc_val[i] |= SPI.transfer(0);
  delayMicroseconds(2);
  }                                // Repeat for each channel ********** Step 4 **********
  
  digitalWrite(cs, HIGH);
  SPI.endTransaction();

  //The ADS1255/6 output 24 bits of data in Binary Two's
  //Complement format. The LSB has a weight of
  //2VREF/(PGA(223 − 1)). A positive full-scale input produces
  //an output code of 7FFFFFh and the negative full-scale
  //input produces an output code of 800000h. 

  for (i=0; i < 1; i++)
  {   // Single ended Measurements 
  
  if(adc_val[i] > 0x7fffff)
  {   //if MSB == 1
    adc_val[i] = adc_val[i]-16777216; //do 2's complement
  }}
  
//float  Read_Data = adc_val[i] *0.0000002980232;
//valuenew = (Read_Data-0.5) * 5;
//  Serial.print(Read_Data);   // Raw ADC integer value +/- 23 bits
//  Serial.print("      ");
//  Serial.println(valuenew);

 for (i = 0; i < SAMPLES; i++) 
 {
  float  Read_Data = adc_val[i] *0.0000002980232;
valuenew = (Read_Data-0.5) * 5;
      a[i] = valuenew;
    
       Serial.println(a[i], 6); // print a separator line if you want it
    }

#if DEBUG
  Serial.print("Time for inference (us): ");
  Serial.println(micros() - start_timestamp);
#endif
  
delay(1000);
}
 Serial.println(valuenew);

This line prints proper siusoidal signal.

  Serial.println(a[i], 6);

But in above line of code, a single value value is printed until for loop executes 1024 times.
Please help me out to solve this issue

  for (i = 0; i < 1; i++)

How many values of i will this for loop create ?
Have you tried printing i in the for loop ?

 for (i=0; i < 1; i++)
  {  
  if(adc_val[i] > 0x7fffff)
  {  
    adc_val[i] = adc_val[i]-16777216; //do 2's complement
  }
 
float  Read_Data = adc_val[i] *0.0000002980232;
valuenew = (Read_Data-0.5) * 5;

Serial.print(Read_Data);   // Raw ADC integer value +/- 23 bits
Serial.print("      ");
Serial.println(valuenew);
    }

#if DEBUG
//  Serial.print("Time for inference (us): ");
//  Serial.println(micros() - start_timestamp);
#endif
  
delay(100);
}

Actually this ADC has 8 channel single ended measurements. I’m trying to print only one channel.

These are the serial monitor values
Read_data valuenew
0.98 2.42
1.00 2.51
0.95 2.26
0.84 1.70
0.68 0.90
0.50 -0.02
0.31 -0.93
0.16 -1.72
0.05 -2.26
0.01 -2.47
0.03 -2.34
0.12 -1.88
0.27 -1.15
0.45 -0.25
0.64 0.68
0.80 1.52
0.93 2.15
1.00 2.48
0.99 2.47
0.92 2.11
0.79 1.46
0.62 0.61
0.44 -0.32
0.26 -1.21
0.12 -1.92
0.03 -2.36
0.01 -2.47
0.06 -2.22
0.17 -1.66
0.33 -0.87

Goodday to everyone,

Now, I managed to save values into array and taking those values for FFT peak detection.
But now the problem is with sampling rate used for FFT peak detection.

I’m providing 1.0V(p-p) Sinusoidal signal with 0.5Vdc offset with a frequency of 30Hz. I used 400Hz as sampling rate and number of samples is 1024 in code, therefore up to 200Hz, the peak detection is happening properly, FFT peak detected for 200Hz input signal is 198.74Hz.
But after 200Hz, I changed sampling rate to 1000Hz and if the input signal frequency is 300Hz, the peak is detected at 15.43Hz. I’m not understanding what is the problem. Can anybody tell me where the problem lies? I’m attaching the code. Thanks for your patience.

#include <SPI.h>
#include <arduinoFFT.h>

#define cs 5 // chip select
#define rdy 25 // data ready, input
#define rst 26 // may omit

#define SPISPEED 2500000   // Teensy 3.2 @120 mhz
#define SAMPLES 1024
#define SAMPLING_FREQUENCY 400

float value1;
float value2;
float value3;

float x;

#define DEBUG 1

arduinoFFT FFT = arduinoFFT();

unsigned int sampling_period_us;
unsigned long microseconds;

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

int i;

double xaxis[SAMPLES];

void setup()
{
  Serial.begin(115200); 
  pinMode(cs, OUTPUT);
  digitalWrite(cs, LOW); // tied low is also OK.
  pinMode(rdy, INPUT);
  pinMode(rst, OUTPUT);
  digitalWrite(rst, LOW);
  delay(1); // LOW at least 4 clock cycles of onboard clock. 100 microseconds is enough
  digitalWrite(rst, HIGH); // now reset to default values
  delay(100);
  SPI.begin(); //start the spi-bus
  delay(100);
  while (digitalRead(rdy)) {}  // wait for ready_line to go low
  SPI.beginTransaction(SPISettings(SPISPEED, MSBFIRST, SPI_MODE1)); // start SPI
  digitalWrite(cs, LOW);
  delayMicroseconds(100);
  SPI.transfer(0xFE);
  delay(5);

  byte status_reg = 0x00 ;  // address (datasheet p. 30)
  byte status_data = 0x01; // 01h = 0000 0 0 0 1 => status: Most Significant Bit First, Auto-Calibration Disabled, Analog Input Buffer Disabled
  //byte status_data = 0x07; // 01h = 0000 0 1 1 1 => status: Most Significant Bit First, Auto-Calibration Enabled, Analog Input Buffer Enabled
  SPI.transfer(0x50 | status_reg);
  SPI.transfer(0x00);   // 2nd command byte, write one register only
  SPI.transfer(status_data);   // write the databyte to the register
  delayMicroseconds(100);
  
  byte adcon_reg = 0x00; //A/D Control Register (Address 02h)
  //byte adcon_data = 0x20; // 0 01 00 000 => Clock Out Frequency = fCLKIN, Sensor Detect OFF, gain 1
  byte adcon_data = 0x00; // 0 00 00 000 => Clock Out = Off, Sensor Detect OFF, gain 1
  //byte adcon_data = 0x01;   // 0 00 00 001 => Clock Out = Off, Sensor Detect OFF, gain 2
  SPI.transfer(0x50 | adcon_reg);  // 52h = 0101 0010
  SPI.transfer(0x00);              // 2nd command byte, write one register only
  SPI.transfer(adcon_data);        // write the databyte to the register
  delayMicroseconds(100);

  byte drate_reg = 0x03; //DRATE: A/D Data Rate (Address 03h)
  byte drate_data = 0xF0; // F0h = 11110000 = 30,000SPS
  SPI.transfer(0x50 | drate_reg);
  SPI.transfer(0x00);   // 2nd command byte, write one register only
  SPI.transfer(drate_data);   // write the databyte to the register
  delayMicroseconds(100);

  SPI.transfer(0xF0);     
  delay(100);
  digitalWrite(cs, HIGH);
  SPI.endTransaction();
sampling_period_us = round(1000000*(1.0/SAMPLING_FREQUENCY));
}

void loop()
{
saveinarray();
plotfftx();
Serial.println("Iteration completed");
delay(10);
}


void test()
{
  unsigned long adc_val[8] = {0,0,0,0,0,0,0,0}; // store readings in array
  byte mux[8] = {0x08,0x18,0x28,0x38,0x48,0x58,0x68,0x78};
  int i = 0;
  SPI.beginTransaction(SPISettings(SPISPEED, MSBFIRST, SPI_MODE1)); // start SPI
  digitalWrite(cs, LOW);
  delayMicroseconds(2);
  
  for (i=0; i <=7; i++){         // read all 8 Single Ended Channels AINx-AINCOM
  byte channel = mux[i];             // analog in channels # 
  while (digitalRead(rdy)) {} ;                          
  SPI.transfer(0x50 | 0x01); // 1st Command Byte: 0101 0001  0001 = MUX register address 01h
  SPI.transfer(0x00);     // 2nd Command Byte: 0000 0000  1-1=0 write one byte only
  SPI.transfer(channel);     // Data Byte(s): xxxx 1000  write the databyte to the register(s)
  delayMicroseconds(2);

  //SYNC command 1111 1100                               // ********** Step 2 **********
  SPI.transfer(0xFC);
  delayMicroseconds(2);

  SPI.transfer(0x00);
  delayMicroseconds(250);   // Allow settling time

  SPI.transfer(0x01); // Read Data 0000  0001 (01h)       // ********** Step 3 **********
  delayMicroseconds(5);
  
  adc_val[i] = SPI.transfer(0);
  adc_val[i] <<= 8; //shift to left
  adc_val[i] |= SPI.transfer(0);
  adc_val[i] <<= 8;
  adc_val[i] |= SPI.transfer(0);
  delayMicroseconds(2);
  }                                // Repeat for each channel ********** Step 4 **********
  
  digitalWrite(cs, HIGH);
  SPI.endTransaction();

  //The ADS1255/6 output 24 bits of data in Binary Two's
  //Complement format. The LSB has a weight of
  //2VREF/(PGA(223 − 1)). A positive full-scale input produces
  //an output code of 7FFFFFh and the negative full-scale
  //input produces an output code of 800000h. 

  for (i=0; i <2; i++)
  {   // Single ended Measurements 
  if(adc_val[i] > 0x7fffff)
  {  
    adc_val[i] = adc_val[i]-16777216; //do 2's complement
  }
  
float  Read_Data = adc_val[i] *0.0000002980232;
value1 = adc_val[0] *0.0000002980232;
value2 = adc_val[1] *0.0000002980232;
value3 = adc_val[2] *0.0000002980232;
x = (value1 - 0.5)*5;

//  Serial.print(Read_Data);   // Raw ADC integer value +/- 23 bits
//  Serial.print("      ");
// Serial.println(x);
}
}

void saveinarray()
{
  for( i=0; i<SAMPLES; i++)
  {
    test();
    k[i]=x;
    //Serial.println(k[i]);
  }
  
}

void plotfftx()
{
   for (uint16_t i = 0; i < SAMPLES; i++) 
  {
   microseconds = micros(); 
    vReal[i] = k[i] ;
    vImag[i] = 0.0; //Imaginary part must be zeroed in case of looping to avoid wrong calculations and overflows
  
    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);
   double peak = FFT.MajorPeak(vReal, SAMPLES, SAMPLING_FREQUENCY);

   Serial.print("Peak frequency is: ");
   Serial.println(peak);
}

might help if you posted your data

you require Analog input signal data?

I’m attaching analog input signal data samples of 200Hz with sampling rate of 400Hz and 1000Hz.

For sampling rate 400 Hz, the peak detection is 198.4Hz
For sampling rate 1000Hz, the peak detection is 497.23Hz.

Thanks for your help

400 Hz.txt (13 KB)

1000Hz(200Hz).txt (13 KB)

both data files look similar. both look under-sampled.
both files have 2048 samples. what is the duration (time) of each file?

I’m capturing 1024 samples.

for 400 Hz sampling rate, for every (1024/400 = 2.56s) 2.56s new data will be updated.
for 1000Hz sampling rate, for every (1024/1000 = 1.024s)1.024s new data will be updated.

I’m uploading once again data files with 1024 samples for both sampling rate.

400 Hz.txt (6.5 KB)

1000Hz(200Hz).txt (6.5 KB)

What exactly are you trying to do?

If you are after measuring the frequency of the input signal then an FFT is not very accurate. This is because it splits a signal into a number of bins, and each bin corresponds to a range of frequencies, not an actual one.

If you signal is always going to be a sin wave then you can simply measure the time between successive zero crossings.

This seem to be an X-Y Problem

My end application will be acquiring vibration signals and finding major frequency peaks.

But the data acquisition right now is happening through SPI protocol using External ADC.
I’m verifying the code reliability by inputting known signals such as sinusoidal signals (using function generator) ranging from 10Hz to 500Hz.

still looks undersampled.
can you capture timestamps at the beginning/end of your capture process to partially verify sampling period

I used below code in the main code to capture timestamp but its not capturing the timestamp properly.
Is the below code correct method to capture time stamp? Pls let me know

unsigned long sampleTimer = 0;
unsigned long sampleInterval = 1; //1 ms = 1000Hz rate or 2.5ms for 400Hz

void setup()
{
 Serial.begin(115200);
SPI settings;
}
void loop()
{
 unsigned long currMillis = millis();
 if(currMillis - sampleTimer >= sampleInterval)  
 {
   sampleTimer = currMillis;

   Serial.println(sampleTimer);
 }
}

What’s wrong with it?

like this

   unsigned long msec0 = millis();

    captureSamples ();

    unsigned long msec1 = millis();

    Serial.print   ("capture interval ");
    Serial.println (msec1 - msec0);

Serial Monitor output for 400 Hz sampling rate

capture interval 4481
Peak frequency is: 106.76
Iteration completed
capture interval 9816
Peak frequency is: 106.76
Iteration completed
capture interval 15151
Peak frequency is: 106.76
Iteration completed

Serial Monitor output for sampling rate 1000Hz

capture interval 4320
Peak frequency is: 247.19
Iteration completed
capture interval 7917
Peak frequency is: 247.19
Iteration completed
capture interval 11519
Peak frequency is: 247.89
Iteration completed

it looks like you performed 3 separate captures at each rate. why is the capture interval growing?

1024 sample captured at 1000 Hz should take 1.024 sec.

assuming the first value in each case is somewhat representative, 1024 samples captured in 4320 msec suggests the sampling rate is 4.3 msec/sample or 232 Hz

i don't understand your code

  • when capturing data, any processing should be deferred. store raw data from the device
  • if there are 8 channels, can you minimize sampling time by only capturing one channel

So I made some tweaking in saveinarray() section, now the code is working for 1kHz sampling rate and upto 500 Hz input signal , the FFT peak is detected properly. This is working well for one channel of ADC.

But now I again I ran into the same problem, when I modify the same code for 3 channel data acquisition.

For 1KHz sampling rate and 1024 samples with 3 channel, the FFT peak is not detecting properly.

Any idea what could be the reason?

Single channel code

#include <SPI.h>
#include <arduinoFFT.h>

#define cs 5 // chip select
#define rdy 25 // data ready, input
#define rst 26 // may omit

#define SPISPEED 2500000   // Teensy 3.2 @120 mhz
#define SAMPLES 1024
#define SAMPLING_FREQUENCY 1000

float value1;
float value2;
float value3;


float x;

#define DEBUG 1

arduinoFFT FFT = arduinoFFT();

unsigned int sampling_period_us;
unsigned long microseconds;

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

int i;

double xaxis[SAMPLES];

void setup()
{
  Serial.begin(115200);
  pinMode(cs, OUTPUT);
  digitalWrite(cs, LOW); // tied low is also OK.
  pinMode(rdy, INPUT);
  pinMode(rst, OUTPUT);
  digitalWrite(rst, LOW);
  delay(1); // LOW at least 4 clock cycles of onboard clock. 100 microseconds is enough
  digitalWrite(rst, HIGH); // now reset to default values
  delay(100);
  SPI.begin(); //start the spi-bus
  delay(100);
  while (digitalRead(rdy)) {}  // wait for ready_line to go low
  SPI.beginTransaction(SPISettings(SPISPEED, MSBFIRST, SPI_MODE1)); // start SPI
  digitalWrite(cs, LOW);
  delayMicroseconds(100);
  SPI.transfer(0xFE);
  delay(5);

  byte status_reg = 0x00 ;  // address (datasheet p. 30)
  byte status_data = 0x01; // 01h = 0000 0 0 0 1 => status: Most Significant Bit First, Auto-Calibration Disabled, Analog Input Buffer Disabled
  //byte status_data = 0x07; // 01h = 0000 0 1 1 1 => status: Most Significant Bit First, Auto-Calibration Enabled, Analog Input Buffer Enabled
  SPI.transfer(0x50 | status_reg);
  SPI.transfer(0x00);   // 2nd command byte, write one register only
  SPI.transfer(status_data);   // write the databyte to the register
  delayMicroseconds(100);
 
  byte adcon_reg = 0x00; //A/D Control Register (Address 02h)
  //byte adcon_data = 0x20; // 0 01 00 000 => Clock Out Frequency = fCLKIN, Sensor Detect OFF, gain 1
  byte adcon_data = 0x00; // 0 00 00 000 => Clock Out = Off, Sensor Detect OFF, gain 1
  //byte adcon_data = 0x01;   // 0 00 00 001 => Clock Out = Off, Sensor Detect OFF, gain 2
  SPI.transfer(0x50 | adcon_reg);  // 52h = 0101 0010
  SPI.transfer(0x00);              // 2nd command byte, write one register only
  SPI.transfer(adcon_data);        // write the databyte to the register
  delayMicroseconds(100);

  byte drate_reg = 0x03; //DRATE: A/D Data Rate (Address 03h)
  byte drate_data = 0xF0; // F0h = 11110000 = 30,000SPS
  SPI.transfer(0x50 | drate_reg);
  SPI.transfer(0x00);   // 2nd command byte, write one register only
  SPI.transfer(drate_data);   // write the databyte to the register
  delayMicroseconds(100);

  SPI.transfer(0xF0);     
  delay(100);
  digitalWrite(cs, HIGH);
  SPI.endTransaction();
sampling_period_us = round(1000000*(1.0/SAMPLING_FREQUENCY));
}

void loop()
{
saveinarray();
plotfftx();
Serial.println("Iteration completed");
delay(10);
}


void test()
{
  unsigned long adc_val[1] = {0}; // store readings in array
  byte mux[1] = {0x08};
  int i = 0;
  SPI.beginTransaction(SPISettings(SPISPEED, MSBFIRST, SPI_MODE1)); // start SPI
  digitalWrite(cs, LOW);
  delayMicroseconds(2);
 
  for (i=0; i <1; i++){         // read all 8 Single Ended Channels AINx-AINCOM
  byte channel = mux[i];             // analog in channels #
  while (digitalRead(rdy)) {} ;                         
  SPI.transfer(0x50 | 0x01); // 1st Command Byte: 0101 0001  0001 = MUX register address 01h
  SPI.transfer(0x00);     // 2nd Command Byte: 0000 0000  1-1=0 write one byte only
  SPI.transfer(channel);     // Data Byte(s): xxxx 1000  write the databyte to the register(s)
  delayMicroseconds(2);

  //SYNC command 1111 1100                               // ********** Step 2 **********
  SPI.transfer(0xFC);
  delayMicroseconds(2);

  SPI.transfer(0x00);
  delayMicroseconds(250);   // Allow settling time

  SPI.transfer(0x01); // Read Data 0000  0001 (01h)       // ********** Step 3 **********
  delayMicroseconds(5);
 
  adc_val[i] = SPI.transfer(0);
  adc_val[i] <<= 8; //shift to left
  adc_val[i] |= SPI.transfer(0);
  adc_val[i] <<= 8;
  adc_val[i] |= SPI.transfer(0);
  delayMicroseconds(2);
  }                                // Repeat for each channel ********** Step 4 **********
 
  digitalWrite(cs, HIGH);
  SPI.endTransaction();

  //The ADS1255/6 output 24 bits of data in Binary Two's
  //Complement format. The LSB has a weight of
  //2VREF/(PGA(223 − 1)). A positive full-scale input produces
  //an output code of 7FFFFFh and the negative full-scale
  //input produces an output code of 800000h.

  for (i=0; i <1; i++)
  {   // Single ended Measurements
  if(adc_val[i] > 0x7fffff)
  { 
    adc_val[i] = adc_val[i]-16777216; //do 2's complement
  }
 
float  Read_Data = adc_val[i] *0.0000002980232;
value1 = adc_val[0] *0.0000002980232;
value2 = adc_val[1] *0.0000002980232;
value3 = adc_val[2] *0.0000002980232;
x = (value1 - 0.5)*5;

//  Serial.print(Read_Data);   // Raw ADC integer value +/- 23 bits
//  Serial.print("      ");
// Serial.println(x);
}
}

void saveinarray()
{
  for( i=0; i<SAMPLES; i++)
  {
    microseconds = micros();
    test();
    k[i]=x;
    Serial.println(k[i]);
    while(micros() < (microseconds + sampling_period_us)){
        }
  }
 
}

void plotfftx()
{
   for (uint16_t i = 0; i < SAMPLES; i++)
  {
   microseconds = micros();
    vReal[i] = k[i] ;
    vImag[i] = 0.0; //Imaginary part must be zeroed in case of looping to avoid wrong calculations and overflows
 
    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);
   double peak = FFT.MajorPeak(vReal, SAMPLES, SAMPLING_FREQUENCY);

   Serial.print("Peak frequency is: ");
   Serial.println(peak);
}

Any idea what could be the reason?

That code doesn’t seem to try and take samples from three different inputs.

post the data and collection interval (start and stop)