cancel
Showing results for 
Search instead for 
Did you mean: 

Constant Fraction Discriminator

Sax
Associate III

I have 2 arrays, one is inverted and scaled and the other remains positive and with original size. Now I have to delay the positive one by half the rise time. Then I have to find zero crossing. Finally, I have to find the maximum or determine an object detection. 

I have an array after the ADC. I inverted that. Now I'm thinking about how I can take the next steps to create a constant fraction discriminator.

Finally, I have to turn on 1 LED when an object comes closer to my sensor and 2 LEDs when this object comes even closer to the sensor.
The LEDs are connected to 2 pins and need ground on these pins because they are connected to the voltage source from one side.

I would be very grateful if someone could help me write a C code with explanation.

7 REPLIES 7
Johi
Senior III

This forum can help you with your project and I it will. But in essence, you need to be willing to help yourself first. Therefor tell us what you have, show your code and you cannot imagine what kind of help the forum can give.

If you have your ADC running and you have the data in an array already, the rest should be within reach.

Sax
Associate III

Thanks for the feedback. Here's the code part where I can't go any further:

 

//here a Hilbert transformation is made to get an analytical signal

arm_fir_f32 (&fir_instance, *&adc_buffer, *&fir_out_arm, 1024);

 

 

for (int j = 0; j<= adcBufferSize; j++)

{

// amplitude is made up of the real part and the imaginary part

amplitude[j] = sqrt(pow(adc_buffer[j],2) + pow(fir_out_arm[j],2));

//Angles are calculated, but not necessarily. With the amplitude you can usually continue with constant fraction discriminator

angle[j] = atan((fir_out_arm[j]/adc_buffer[j])*(PI/180));

// Analytical signal in complex form

analytical_signal[j] = amplitude[j]*cexp(angle[j]);

 

 

// Delay Signal (But I don't know delay value, I have to calculate from half the slope time of the positive amplitude. I still have no idea how)

// I don't think this loop is correct either, but that's my first idea

 

delayed_signal[j] = analytical_signal[j]*(j>=delay);

 

 

// Invert signal

inverted_signal[j] = -analytical_signal[j];

 

// Fusion of positive and negative amplitude in new array named processed_signal

// Here is also not correct I think, here must be other logic

if (j%2==0)

{processed_signal[j] = delayed_signal[j];}

if (j%2 !=0)

// scale signal

{processed_signal[j] = fraction*inverted_signal[j];}

 

 

// find max and min in the signal

if (processed_signal[j]>max_value)

{

max_value = processed_signal[j];

max_index = j;

}

if (processed_signal[j]<min_value)

{

min_value = processed_signal[j];

min_index = j;

}

}

// Determine zero crossing now

previous_value = min_value;

 

// processd_signal scan starting with the lowest point and ending with maximum

for (int m = min_index; m<=max_index; m++)

{

// Approximate Zero Crossing

if (previous_value*processed_signal[m] <= 0)

{

zero_cross = processed_signal[m];

zero_cross_index = m;

printf("Zero crossing of the Fkt: ", zero_cross);

break;

}

previous_value = processed_signal[m];

}

// here I am also missing the correct initialization in cube IDE

HAL_GPIO_WritePin(GPIOF, GPIO_PIN_3,GPIO_PIN_SET);

HAL_GPIO_WritePin(GPIOF, GPIO_PIN_5,GPIO_PIN_SET);

 

// I didn't get any further

I am not familiar at all with DSP but do have some mathematical background, so therefore this question.

arm_fir_f32 (&fir_instance, *&adc_buffer, *&fir_out_arm, 1024);

* @defgroup FIR Finite Impulse Response (FIR) Filters => this is a function that transfers signals from the time domain to the time domain but filtered if I understand the documentation correctly.

In its simplest form you can use it to build a first order filter. The filter uses state space technology. But seems not to be transferring to the complex Fourier or to the Hilbert domain. (I am not a specialist)

There is a function void arm_chilbert_f32() converts to the Hilbert domain. Maybe I am mistaken but the documentation does provide clarification for your code.

Could be that Hilbert given its phase shift for negative frequencies (?) is suitable implementing the challenge but this is not my field of expertise?

 

Second related to your IO control:

To control an output using HAL_GPIO_WritePin(GPIOF, GPIO_PIN_3,GPIO_PIN_SET); can be done by opening the .IOC file in STM32CUBEIDE (assuming you use this IDE). After right clicking on the IO you can used the dialog to give it a name (user label).

Johi_0-1704012746612.png

You select PF3, click right and then select GPIO-OUTPUT. When you save and compile you will find the defines generated in main.h.

Johi_1-1704012793253.png

By including main.h in your main.c, you will have access  to these defines.

HAL_GPIO_WritePin(PF3_TESTBIT_GPIO_Port, PF3_TESTBIT_Pin,GPIO_PIN_SET);

 

 

Sax
Associate III

Thanks for the info, I appreciate that. I didn't have any problems with the Hilbert transformation. I've got them
in such a way that I generated filter coefficients in Matlab and implemented them with the help of FIR filters.

My problem starts with the implementation of Constant Fraction Discriminator.

Then you get a smaller amplitude on the negative side.

The positive amplitude should be delayed by the increase time of the positive amplitude.

Then you have two amplitudes, one on the negative side and smaller ones on the positive side, the original size.

Then zero crossing must be determined and a maximum must be determined as an object detection.

From here, I'm trying to implement Constant Fraction Discriminator:

delayed_signal[j] = analytical_signal[j]*(j>=delay);

 

Hello Sax,

Thank you for the answer: maybe I did not understand the question to well but shifting and adding the inverse array can be done as below: (or you could to both operations in 1 loop).

 

 

 

for (int i=0;i<array_size;i++)
{
   if (i-delayInCountedInSamples >= 0)
   {
     delayed_signal[i] = 0.5 * analytical_signal[i-delayInCountedInSamples ];
   }
   else
   {
      delayed_signal[i] = analytical_signal[0];
   }
}

for (int i=0;i<array_size;i++)
{
   result_signal[i] =  analytical_signal[i] + delayed_signal[i];  
}

 

 

Then you need to define the increase time: but in real world I would assume there is some chatter on the incoming signal and therefor determining the period seems (to me) something to be extracted from the frequency spectrum and not to be done by manipulating the array values? Do you have any mathematical insights in how to extract this value from the result of the transformation?

Sax
Associate III

Hi Johi, thank you very much for the valuable info. The increase time from the frequency spectrum I don't have any mathematical experience yet. I only trasformed signals Fourier and FFT. 

Johi
Senior III

I still wonder what the right approach to the challenge you are facing is?

I could program the whole thing without any transformation (as far as I can see).
But can you be a bit more specific why you are using the transformation anyway?

Maybe share the data array, if I am in a good mood, I give it a try, but normally that is not the idea on this forum.