Announcement

Collapse
No announcement yet.

Induction Balance Stuff - Single/Multi Frequency Response, GB, Disc, Measurements, Ideas, Fun, etc.

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • moodz
    replied
    Originally posted by Aziz View Post
    Hi all,

    the Complex FIR-Bandpass-Filter design​ seems to be too complex for AI.
    I'm on the 7.th version of the AI code. It made lots of bugs.

    fir_process_block()
    fir_process_block_fixed()
    fir_process_block_optimized()
    fir_process_block_fixed_final()
    fir_process_final()
    fir_process_verified()
    fir_process_perfect()

    ​
    What's missing?
    fir_process_ultimate()?

    Enough for today.
    ...Aziz you are using the wrong AI. This demo took 2 minutes to build in javascript ( first attempt ) and generates C or python code outputs.

    Click image for larger version  Name:	image.png Views:	0 Size:	168.1 KB ID:	445145​

    Leave a comment:


  • Aziz
    replied
    Hi all,

    the Complex FIR-Bandpass-Filter design​ seems to be too complex for AI.
    I'm on the 7.th version of the AI code. It made lots of bugs.

    fir_process_block()
    fir_process_block_fixed()
    fir_process_block_optimized()
    fir_process_block_fixed_final()
    fir_process_final()
    fir_process_verified()
    fir_process_perfect()

    ​
    What's missing?
    fir_process_ultimate()?

    Enough for today.

    Leave a comment:


  • Aziz
    replied
    Hi all,

    it get's even better with a Complex FIR-Bandpass-Filter design (it is based on Hilbert-Transform of course).
    Both I/Q-channels will be bandpass filtered.

    I hope, the magic AI does not make any bugs in the coding. I will feed in magic input.
    Aziz

    Leave a comment:


  • Aziz
    replied
    Hi,

    I'm using the following basic phase unwrapping function (it was the first proposal of Google AI):

    Code:
    // Phase Unwrapping (Phase linearising)
    // [OUT] REAL *pOutput: Pointer to Output Phase Data (Radiants)
    // [IN]  REAL *pInput:  Pointer to Input Phase Data (Radiants)
    // [IN]  int n:         Number of Phase Data
    //
    void unwrapPhase1D(REAL *pOutput, REAL *pInput, int n)
    {
      REAL wrap_count, diff;
      int i;
    
      ASSERT(pOutput);
      ASSERT(pInput);
    
      if (n <= 0)
        return;
    
      wrap_count = 0;
      pOutput[0] = pInput[0];
    
      for (i = 1; i < n; i++)
      {
        // Current difference
        diff = pInput[i] - pInput[i-1];
    
        // Detection of phase jumps > pi or < -pi
        if (diff > PI) {
            wrap_count -= 1;
        } else if (diff < -PI) {
            wrap_count += 1;
        }
    
        pOutput[i] = pInput[i] + wrap_count * PI2;
    
      } // for i
    }
    PI2 is 2.0*PI

    It's not perfect but it works. I am able to calculate d Phi(t)/dt and therefore the instantaneous​ frequency of the demodulated signal. In this example above, the Franklin LC oscillator frequency. It is quite stable (+/- 1 Hz or less).

    Cheers,
    Aziz

    Leave a comment:


  • Aziz
    replied
    Hi all,

    The Google AI isn't perfect. The posted code for unwrapping the phase doesn't work. I have taken another (simple) solution, which works.

    This is the reason, why we urgently need the phase unwrapping, before we can calculate the d Phi()/dt correct.
    You can see below, that the phase ist switching between pi (Umax-Level) and -pi (-Umax). This is the input of the LC Franklin oscillator. With I/Q channels, Envelope(t) and Phase(t).
    The Oscillator is running at appr. 9.2 kHz.
    If we take all the linear phase lines and put them together, we would get a very long straight line. This is what phase unwrapping does.

    Click image for larger version

Name:	UnwrappingPhaseRequired.png
Views:	165
Size:	41.9 KB
ID:	445123

    Aziz

    Leave a comment:


  • Aziz
    replied
    Hi all,

    the Hilbert-Transform is one of the simplest approaches. There are by far better approaches, which can be adressed later.
    The Hilbert-Huang-Transformation (HHT)​


    For the ultra ultimate AI gizmo detector challanges.
    I find it very very interesting. You should have heard the name by now.​ Don't forget it.

    Leave a comment:


  • Aziz
    replied
    Hi,

    so what is so special on d Phi(t)/dt (change of Phi(t) over time period dt => 1. derivation of Ph(t) ) ?
    if d Phi(t)/dt = constant, the ringing frequency is constant (so it does not change).
    You know, that targets and hot ground will change the ringing frequency. So the d Phi(t)/dt will change due to this effects.

    At the same time, the evelope damping decay tells us about additional losses (either resistive or reactive).
    Both decoded infos are time-domain signals. We don't leave the time-domain section. All processed in the fast and efficient time-domain coding. Perfect for embedded µC/DSP projects with fast ADC channels.
    Aziz

    Leave a comment:


  • Aziz
    replied
    Hi all,

    I couldn't find prior art of the "pulsed damped ringing" metal detector, which is processing the damped envelope and d Phi(t)/dt as described above.
    This must be of course totally novel technique, if we can't find a prior art.

    Let me know, if you find something. Google AI does not know.

    Well, I can test my modules on the free running LC Franklin oscillator in off-resonance mode at the moment until I have designed an appropriate "pulsed damped ringing"​ detector controller.
    Aziz

    Leave a comment:


  • Aziz
    replied
    Hi again,

    so what are the benefits of the "pulsed damped ringing" pulse induction method?
    - modifying the PI method into VLF/LF method
    ​- reduction of the wide band response of the standard PI method to a sharp narrow band response
    - low noise due to sharp narrow band response (inherent Hilbert Filter)
    - processing TX reference and RX signal at the same time
    - still high current pulses possible for IB configuration (enough response on the RX coil)
    - off-resonance principle possible (low power mode)
    - mono coil design on TX coil only (processing only TX reference)
    - d Phi(t)/dt analysis for ground balance and target response (TX reference and RX signal)
    - decaying envelope analysis for ground balance and target response (TX reference and RX signal)

    We have the digital signal processing tools for now.

    Cheers,
    Aziz

    Leave a comment:


  • Aziz
    replied
    Hi all,

    this is the code:
    Hilbert Transform with band pass filter (optional) and Hamming window (optional).

    Code:
    #ifndef PI
    #define PI          3.14159265358979323846264338327950288419716939937510
    #endif
    
    #ifndef PI2
    #define PI2        (2.0*PI)
    #endif
    
    
    //-----------------------------------------------------------------------------
    // Data Types
    //
    
    typedef struct // Hilbert Filter Object Definition
    {
      int   N;           // Total Filter Size (N), must be odd (e.g. 15, 31, 63, ..)
      int   pos;         // Current Filter Position
      int   nC;          // Total Number of Stored Coefficients (0.0 and symmetry excluded)
    
      REAL  *buffer;     // Double-Buffer to avoid modulo indexing (linearized indexing)
      REAL  *coeffs;     // Hilbert Coefficients (odd, positive)
    
    } HilbertFilter;
    
    
    //-----------------------------------------------------------------------------
    // Functions
    //
    ​
    ​//-----------------------------------------------------------------------------
    // Initialize Hilbert Transformation and Hilbert Filter Object generation
    // [IN]  int N:          Filter size (must be odd size)
    // [IN]  DWORD dwSR:     Sample rate in Hz, if 0 -> apply no band pass filter (=allpass)
    // [IN]  REAL f_min:     Lower corner frequency for band pass filter in Hz
    // [IN]  REAL f_max:     Upper corner frequency for band pass filter in Hz
    // [IN]  BOOL bHamming:  1=apply Hamming-Windowing, 0=no windowing
    //
    // [OUT] HilbertFilter*: Pointer to Hilbert-Object or NULL if not enough memory available
    
    HilbertFilter* hilbert_init(int N, DWORD dwSR, REAL f_min, REAL f_max, BOOL bHamming)
    {
      HilbertFilter *hf;
      int i, M, n;
      REAL hamming=1.0;
      REAL bp=1.0;
      REAL hic;
      REAL bw_low;
      REAL bw_high;
    
     
      if (N % 2 == 0) // Make N odd if required
        N++;
    
      hf = MALLOC(sizeof(HilbertFilter));
      ASSERT(hf);
    
      hf->N = N;
      hf->nC = (N - 1) / 4 + ((N - 1) / 2 % 2 != 0 ? 1 : 0); // Nur ungerade Indizes
     
      hf->coeffs = MALLOC(hf->nC * sizeof(REAL));
      ASSERT(hf->coeffs);
    
      hf->buffer = CALLOC(2 * N, sizeof(REAL));
      ASSERT(hf->buffer);
    
      if (dwSR != 0)
      {
        bw_low  = PI2 * f_min / (REAL)dwSR;
        bw_high = PI2 * f_max / (REAL)dwSR;
      }
    
      hf->pos = 0;
    
      M = N / 2;
      n = 0;
      for (i = 1; i <= M; i += 2) // for all odd index i
      {
        // Ideal Hilbert Coefficients for index i (allpass)
        hic = 2.0 / (PI * i);
        
        // Hamming-Windowing Coefficients (optional)
        if (bHamming)
          hamming = 0.54 + 0.46 * cos((PI2 * i) / (N - 1));
    
        // Band Pass Filter Coefficients (optional)
        if (dwSR != 0)
          bp = cos(i * bw_low) - cos(i * bw_high);
    
        // Combined Hilbert Coefficients (all-in-one)
        hf->coeffs[n++] = hic * bp * hamming;
    
      } // for i
    
      hf->nC = n;
     
      return hf;
    }
    
    //-----------------------------------------------------------------------------
    // Perform a Hilbert Transformation and get I/Q channel results for the input sample
    // [IN]  HilbertFilter *hf: Pointer to Hilbert Object
    // [IN]  REAL  input:       Input sample (one sample)
    // [OUT] REAL *quadrature:  Quadrature output (one sample)
    //
    // [OUT] REAL               Inphase output (one Sample)
    
    REAL hilbert_process(HilbertFilter *hf, REAL input, REAL *quadrature)
    {
      int i, n, N, M;
      REAL q, inphase, *window;
    
      ASSERT(hf);
      ASSERT(quadrature);
    
      N = hf->N;
      M = N / 2;
    
      // Lese-Basis für das älteste Fenster
      window = &hf->buffer[hf->pos];
     
      // Double Buffering: Sample an zwei Positionen schreiben
      window[0] = input;
      window[N] = input;
    
      q = 0.0;
     
      // Symmetrie-Optimierung: Nur ungerade n nutzen
      for (i = 0; i < hf->nC; i++)
      {
        n = 2 * i + 1;
        q += hf->coeffs[i] * (window[M + n] - window[M - n]);
    
      } // for i
     
      *quadrature = q;
      inphase     = window[(N - 1) / 2]; // Delayed center sample
    
      hf->pos = (hf->pos + 1) % N; // Modulo nur für den Pointer, nicht pro Multiplikation
     
      return inphase;
    }
    
    //-----------------------------------------------------------------------------
    // Hilbert Objekt freigeben
    // [IN] HilbertFilter *hf: Zeiger auf Hilbert-Objekt
    // [OUT] none
    
    void hilbert_free(HilbertFilter *hf)
    {
      ASSERT(hf);
      ASSERT(hf->buffer);
      ASSERT(hf->coeffs);
    
      FREE(hf->buffer);
      FREE(hf->coeffs);
      FREE(hf);
    }
    A very nice code.
    Cheers

    Leave a comment:


  • Aziz
    replied
    Hi all,
    I have tested the Hilbert-Transform with Hamming window and bandpass feature using my software platform. It is working like a charm. It's magic.

    This is a nice tool and enables us much more real-time processing power, feature extraction and to realise totally new ideas like the "damped ringing" method.
    I will change the interface function and the data structure and post the ultimate solution here.
    Stay tuned..

    Leave a comment:


  • Aziz
    replied
    Originally posted by ivconic View Post
    Aziz, here is something you've always dreamed about!

    https://www.aliexpress.com/item/1005...origin_prod%3A

    No more magnetic field calculations.
    I didn't know this tool. Nice. Thanks.

    Leave a comment:


  • ivconic
    replied
    Aziz, here is something you've always dreamed about!

    Leave a comment:


  • Aziz
    replied

    From the Hilbert filter coefficients:

    a) h_ideal = (1.0 - cos(PI * k)) / (PI * k), from above code
    vs.
    b) h_ideal = (2.0 / (PI * k)), from the optimized code

    What is wrong?
    Wolframalpha failed to solve this. Google AI made it correct.

    k is >=1 and odd (1, 3, 5, 7, ..)

    What happens to the term cos(PI*k) for k=1, 3, 5, ...
    cos(PI*1)=-1,
    cos(PI*3)=-1,
    cos(PI*5)=-1
    and so on.. = -1

    The formula a) simplifies to
    h_ideal = (1 - (-1)) / (PI * k)
    h_ideal = 2 / (PI*k)

    which is the formula b).

    I thought, that the AI made a mistake perhaps. Nope! It's fully correct. If you don't ask for optimization, you get more complex and inefficient formulas or solutions.
    Next time, I will ask the AI the optimized question with infinity entropy for the answer 42!

    Leave a comment:


  • Aziz
    replied
    Originally posted by Aziz View Post
    Well, I have to do it by hand now.
    F! me!
    The AI even makes the changes for me.

    Leave a comment:

Working...
X