Skip to main content
Associate III
December 30, 2023
Question

Constant Fraction Discriminator

  • December 30, 2023
  • 2 replies
  • 3140 views

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.

    2 replies

    Johi
    Senior II
    December 30, 2023

    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.

    SaxAuthor
    Associate III
    December 30, 2023

    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

    Johi
    Senior II
    December 31, 2023

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

     

     

    Johi
    Senior II
    January 1, 2024

    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.