cross correlation problem ?

hello everyone, i am working on a project called sound source localization by tdoa. i have two mics 15

cm apart . i read the data from both the mics and store them in two arrays the i cross correlated them

in order to find the time delay between the mics. after that i find the maximum in the cross correlation

and its index which indicate the time delay then i compute the angle of arrival using some trigonometry

but i always am getting positive index which always leads to you a positive angle .what i need to find is

like this for example as index [-9 -8 -7 -6 -5 -4 -3 -2 -1 0 1 2 3 4 5 6 7 8 9 ] and for each of the

index i will the angle. how can i do it ?

i will appreciate it any help

this is my code

#define mic1 A0
#define mic2 A15
#define asinf   asin
#define numreadings 11

 unsigned long int mic1_arr[numreadings];
  unsigned long int mic2_arr[numreadings];
  unsigned long int math[numreadings][numreadings];
 int i; 
 uint32_t biggest;
 uint32_t index_correlation;
 float distance_mics = 0.15;
uint16_t sound_speed = 344;
 uint32_t sample_frequency = 44100;
 float sampling_period = 1.0/(float)sample_frequency;

void setup() 
{
  
  Serial.begin(115200);
 pinMode(mic1,INPUT); 
pinMode(mic2,INPUT); 
}
void loop()
{
 fill_array();
//correlation();
 //delay(50);
}
void fill_array() 
{
Serial.println("---------------array-start---------------------------");
for( i = 0;i<numreadings;i++)// taking the value over in a for loop  and store them in two array
{
mic1_arr[i] = analogRead(mic1);
 mic2_arr[i] = analogRead(mic2);
 Serial.print( mic1_arr[i]);
  Serial.print(" ");
Serial.print(mic2_arr[i]);
   Serial.println("");
}
Serial.println("-------------------array-end-------------------");// printing the two array on the screen 
}
void correlation()
{
int maximum_lag = numreadings - 1;
int retard_Size = 2* numreadings - 1;  // The lenght of Cross correlation vector
int m = (retard_Size / 2) + 1;   
int counter = 0;
uint32_t  correlation_val[retard_Size];  // cross correlation val.
uint32_t correlation_vector[retard_Size];  // correlation coefficient val.
Serial.println("-----------------vector-start-------------");
for(int k = -maximum_lag; k <= maximum_lag; k++) 
{  
  uint32_t   correlated_value = 0;  // correlated value 

  for( i = 0; i < numreadings; i++)
  {
    int j = i + k;

    if(j>=0 && j < numreadings) 
    { 
      correlated_value += mic1_arr[i] * mic2_arr[j];     
    }
  }
    correlation_vector[counter] = correlated_value;     // cross-correlation value 
    Serial.print(correlation_vector[counter]);
    Serial.print(" ");
    counter++;
 }
Serial.println("");
Serial.println("-----------------vector-end-------------");
uint32_t biggest = correlation_vector[(retard_Size / 2)];
uint32_t index_correlation = 0;
 for(i=0;i<retard_Size;i++)
 {
    if (correlation_vector[i] > biggest)
    {
      
      biggest = correlation_vector[i];
      index_correlation = i;
    } 
 }
Serial.println("---------index-correlation-start----------------");
Serial.print("   ");
Serial.println(index_correlation);
Serial.print(" ");
Serial.println("----------index-correlation-end----------------");
Serial.print("      ");
Serial.println("----------biggest_start--------------");
Serial.print("  ");
Serial.println(biggest);
Serial.print(" ");
Serial.println("-----------biggest-end-------------------");
Serial.print(" ");
Serial.println("-------find-angle-start-------------");
float degree =  (float) index_correlation /sample_frequency* (float)sound_speed / distance_mics ;//*(PI / 180);
 float Degree = asin(degree)*( 180/ PI);
//double angle = Degree*(PI / 180);
  Serial.print("    ");
  Serial.println(Degree);
  Serial.println("--------find-angle-end-------------");
 }

i attache some of the result i get it.it is below

1.txt (780 Bytes)

2.txt (812 Bytes)

3.txt (771 Bytes)

When you use and store values in UNSIGNED integers and long integers, you get what you see.

Paul

Serial.println("---------------array-start---------------------------")Why do keep wasting so much time?

Paul_KD7HB:
When you use and store values in UNSIGNED integers and long integers, you get what you see.

Paul

yes

To answer your specific question, you're using the index to the vector in your calculation, but the zero lag correlation value is at "maximum_lag" so you should be using "index - maximum_lag".

To address some other issues.

  1. As Paul_KD7HB notes, you're correlating the mic reading including the DC offset. That doesn't add any information so you probably want to subtract the DC offset from the data before performing the correlation. Subtracting the DC offset will give a signed integer result.

  2. Your sample rate is wrong. Assuming you're using an AtMega AVR based board (e.g. Arduino Uno) the maximum sample rate for AnalogRead() is a bit less than 10 kHz. With the print statements in "fill_array" the sample rate will be much slower and will not be uniform.

  3. Physically, the baseline distance between microphones, the speed of sound, and the sample rate limit the number of useful lag products so it is computationally inefficient to compute the full vector of lag products.

MrMark:
To answer your specific question, you're using the index to the vector in your calculation, but the zero lag correlation value is at "maximum_lag" so you should be using "index - maximum_lag".

which line sir

MrMark:
2) Your sample rate is wrong. Assuming you're using an AtMega AVR based board (e.g. Arduino Uno) the maximum sample rate for AnalogRead() is a bit less than 10 kHz. With the print statements in "fill_array" the sample rate will be much slower and will not be uniform.

the sample rate analogread() is 6.6khz without delay and the sound frequency is up 20khz.My sample rate has

to be 40khz but with arduino it is possible to have sample rate like that? one of friend suggest me to do

research about arduino adc register read but i have done some research i couldn't find .could you help me ?