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

  • Aziz
    replied
    Oh man,

    the AI says, we modify the Hilbert coefficients for band-pass functionality.
    Well this can be done as a separate function, which applies the filter to the ideal Hilbert coefficients. This is really minimal.

    This is the core of hilbert_init(). Variables might differ to my publication above. The principle is shown only.
    Code:
                // 1. Ideale Hilbert-Komponente
                double h_ideal = (1.0 - cos(M_PI * k)) / (M_PI * k);
                
                // 2. Bandpass-Komponente (Sinc-Differenz)
                double h_bp = 2.0 * (f_max / fs) * sinc(2.0 * f_max * k / fs) -
                              2.0 * (f_min / fs) * sinc(2.0 * f_min * k / fs);
                
                // 3. Hamming-Fenster
                double window = 0.54 - 0.46 * cos(2.0 * M_PI * n / (N - 1));
                
                coeffs[n] = h_ideal * h_bp * window;
    We have to include the h_bp factor to the Hilbert coefficients.
    There we have. Hilbert-Transform + band-pass.

    I should have asked this AI before. Well, I have to do it by hand now.

    Leave a comment:


  • Aziz
    replied
    What's next?

    Combining a band-pass filter with Hilbert-Transform. Realized and optimized for C code. With Hamming windowing. Double buffering. Avoiding modulo % operator. Optimized for light-speed.
    AI do this for me please! AI? AI? AI? WTF!
    Well, next time.

    Leave a comment:


  • Aziz
    replied
    Look,

    the google AI code for phase unwrapping in pure standard C implementation (max optimized).
    Code:
    #define TWO_PI 6.28318530717958647693
    #define INV_TWO_PI 0.15915494309189533577
    
    void unwrap1D_max_perf(double* restrict data, int n) {
        if (n < 2) return;
    
        // Lokale Kopien für Register-Caching
        double last_val = data[0];
        double cumulative_offset = 0.0;
    
        for (int i = 1; i < n; i++) {
            double current_val = data[i];
            double diff = current_val - last_val;
            
            // Schnellstes portables Rundungsverfahren ohne math.h
            // Nutzt die implizite Truncation beim Cast
            double ratio = diff * INV_TWO_PI;
            int shift = (int)(ratio + (ratio >= 0 ? 0.5 : -0.5));
            
            cumulative_offset -= shift * TWO_PI;
            
            // Update und Store
            last_val = current_val;
            data[i] = current_val + cumulative_offset;
        }
    }​
    Do we need a phase unwrapping tool? YES!

    The analytic signal (z) of the Hilbert-Transform delivers the phase Phi(t). This is the arg(z). arg(z) = atan(Q(t) / I(t)). t is the time variable.
    Before we make the first derivation of Phi(t), we need the phase unwrapping.
    We can calculate then the current frequency f(t) of the signal.
    f(t) = 1/(2*pi) * d Phi(t)/dt
    f(t) is the current frequency at time t

    This is how the frequency can be determined. The unwrapping of the phase is important. This part of the code goes to my library now.

    The AI has stolen code and knowledge from engineers. And I am stealing the AI code and knowledge back. ​

    Cheers,
    Aziz

    Leave a comment:


  • Aziz
    replied
    Hi all,

    BTW, the Hilbert-Transformation makes decay rate processing easily possible. A tuned PI coil with capacitor (defining a resonant circuit) and optional high damping resistor (additional fixed decay rate) will be ringing and decaying during off-time. It behaves like off-resonance principle. The envelope of the ringing decay can be demodulated easily. The processing can be done on the envelope decay. And we have the true "analytical signal" (it is called so, the quadrature form) of the decay ringing for further infos (frequency estimation, phase lag, etc.).
    Look at this paper:


    Who has said, that a ringing coil is bad?
    Aziz

    Leave a comment:


  • Aziz
    replied
    Hi all,

    here is a good explanation of the Hilbert-Transformation and its applications. Easy to read and understand.
    Link: https://medium.com/@RaghavKrishna25/...s-206edb017f2f


    The algorithm above is very useful to form a high-pass filter too. Just reduce the tap-size (filter size). So the low frequency EMI noise will be attenuated. And it also reduces spectral leakage effects due to inherent in-built Hamming windowing. The windowing doesn't cost extra CPU power, because the Hilbert coefficients are modified with the windowing coefficients.

    Note, that the Hilbert filter has some delay for both I (In-phase) and Q (Quadrature-phase) channels. Use the returned I and Q values from the hilbert_process() function. The function enables sample-by-sample real-time processing.
    Cheers

    Leave a comment:


  • Aziz
    replied
    Hi all,

    now look at this fine AI code for Hilbert transform (Allpass FIR Filter type III for quadrature signal generation). The AI has generated and optimized the code after doing an AI query.
    I have added assertion-codes, my own memory allocation function wrappers to detect memory leaks in the system and floating point typecast REAL. And I have optimized little things only.

    Code:
    #ifndef PI
    #define PI 3.14159265358979323846264338327950288419716939937510
    #endif
    ​
    typedef struct
    {
      int   N;           // Gesamtlänge (N), muss ungerade sein
      int   pos;         // Aktuelle Schreibposition
      int   nC;          // Anzahl der gespeicherten Koeffizienten
    
      REAL  *buffer;     // Double-Buffer für modulo-freie Faltung
      REAL  *coeffs;     // Nur ungerade, positive Koeffizienten
    
    } HilbertFilter;
    ​
    HilbertFilter* hilbert_init(int N, BOOL bHamming)
    {
      HilbertFilter *hf;
      int i, M, n;
      REAL hamming=1.0;
     
      if (N % 2 == 0)
        N++; // Sicherstellen, dass N ungerade ist
    
      hf = MALLOC(sizeof(HilbertFilter));
      ASSERT(hf);
    
      hf->N = N;
      hf->nC = (N - 1) / 4 + ((N - 1) / 2 % 2 != 0 ? 1 : 0); // Nur ungerade Indices
     
      hf->coeffs = MALLOC(hf->nC * sizeof(REAL));
      ASSERT(hf->coeffs);
    
      hf->buffer = CALLOC(2 * N, sizeof(REAL));
      ASSERT(hf->buffer);
    
      hf->pos = 0;
    
      M = N / 2;
      n = 0;
      for (i = 1; i <= M; i += 2)
      {
        // Hamming-Fenster (optional)
        if (bHamming)
          hamming = 0.54 + 0.46 * cos((2.0 * PI * i) / (N - 1));
    
        // Idealer Hilbert-Kern * Hamming-Fenster
        hf->coeffs[n++] = (2.0 / (PI * i)) * hamming;
     
      } // for i
    
      hf->nC = n;
     
      return hf;
    }
    
    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;
        // h(n) = -h(-n). Wir nutzen (x[M-n] - x[M+n]) * h(n)
        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;
    }
    
    ​void hilbert_free(HilbertFilter *hf)
    {
      ASSERT(hf);
      ASSERT(hf->buffer);
      ASSERT(hf->coeffs);
    
      FREE(hf->buffer);
      FREE(hf->coeffs);
      FREE(hf);
    }
    ​
    This part of the nice and fast code will be used in my project now. It replaces the slow FFT function for demodulating external signals (RX) with external reference sources (TXRef). Just like demodulating free running LC oscillator signals, where you don't know it's frequency usually. And the frequency isn't fixed (drift, change, etc).
    I had a good lecture lesson in AI prompting now.

    Aziz

    Leave a comment:


  • Aziz
    replied
    Hi all,

    unfortunately, the software sanity project is progressing very slowly. But I'm using AI generated code portions now.
    This is really fck'n nice and efficient.

    I have found a lot of "under construction" and todo parts in my code. Even features, which haven't been implemented yet. And I am bug fixing too (according to the todo list).
    I will very likely leave the old code section parts and add clean and lightweight new modules. This is the fastest way at the moment.
    Cheers

    Leave a comment:


  • Aziz
    replied
    Hi all,

    the proposal a) is by far enough. Instead of balancing, the balance resistor is used to limit the coil current. I don't need the balancing as the signal won't be amplified further or to behave like an IB RX-Coil.
    The sensitivity is not bad for the simple mono coil design. But the coil needs absolutely good shielding. The phase shift is more stable (1/1000 degree stable) and sensitive than the amplitude change (slightly more noise).
    Aziz

    Leave a comment:


  • Aziz
    replied
    Hi Carl,

    Originally posted by Carl-NC View Post
    I'm just suggesting the approach as a way to make an equivalent VLF detector with a mono coil. It otherwise has the same responses as an IB coil. The Go-Find version resonates the search coil and replaces the balancing coil with a resistor-equivalence by using matched anti-phase resonated coils, all stuffed into the coil housing.

    Click image for larger version

Name:	image.png
Views:	256
Size:	49.1 KB
ID:	444913​
    this is for sure a good KISS project destined for my software sanity project.

    Proposal a)
    This is like an LCR-measurement setup (Impedance measurement).

    Proposal b)
    This is more interesting as I can push more current to the TX coil. I like it.
    Coil1 and Coil2 should be realised as a variable inductance (screwable ferrite core inductor housing for both coils to match the search coil impedance).
    We can tap a TX reference signal on one side of the feed to make synchronous detection possible. Then the impedance change can be measured.

    I will try both versions to see the SNR and sensitivity. I like it due to mono coil design.
    Thanks
    Aziz

    Leave a comment:


  • Aziz
    replied
    Hi all,

    thank you for the interesting suggestions.
    I'll think of the ideas.

    The design priority has been changed to software coding for a while. I have to clean up all my metal detecting software code first. There is a lot of experimental code mostly implemented in quick & dirty style, must go now. (I know, I shouldn't do this as a software engineer. )
    A clean and lightweight version is the goal. So I can start different projects, which does not inhere with the other coding stuff. This is overdue.

    Cheers,
    Aziz

    Leave a comment:


  • Carl-NC
    replied
    I'm just suggesting the approach as a way to make an equivalent VLF detector with a mono coil. It otherwise has the same responses as an IB coil. The Go-Find version resonates the search coil and replaces the balancing coil with a resistor-equivalence by using matched anti-phase resonated coils, all stuffed into the coil housing.

    Click image for larger version

Name:	image.png
Views:	256
Size:	49.1 KB
ID:	444913​

    Leave a comment:


  • moodz
    replied
    The gofind uses an impedance bridge strategy as a means of reducing noise and simplifying coil topology over balanced DD or OOO coils. .... it was hardly your state of the art detector when marketed though being sold in the sub $200 bracket.
    Below is detail from the coil connection .... theres a cap across one of the coils ...RX maybe or is it in series ? ...
    The patent talks about impedance change and noise reduction but not really ground reduction / X cancellation.

    Click image for larger version  Name:	image.png Views:	0 Size:	322.0 KB ID:	444911​

    Leave a comment:


  • Qiaozhi
    replied
    Have a look at this thread from 2015 regarding Minelab's Go-Find -> https://www.geotech1.com/forums/foru...-go-find/page3
    You can skip a lot of the preamble by jumping to post #38.

    Leave a comment:


  • Carl-NC
    replied
    Proximity methods -- frequency shift, loading, and off-resonance -- are inherently less sensitive than IB methods or PI. In the mid-late 70s A.H. Electronics and Gardiner tried to stay competitive with TR and TR-Disc but could barely keep up, and when VLF motion detectors arrived it was game over for them. However, there is another mono coil method that gives IB-like results:

    Click image for larger version

Name:	image.png
Views:	239
Size:	30.9 KB
ID:	444875​
    Something similar was used in the Minelab Go-Find models.

    Leave a comment:


  • Aziz
    replied
    Hi all,

    there is still a way of using the off-resonance principle with mono coils. It's the advanced & complex solution however.
    Even the local LC oscillator is set to a stable (not critical) operating point with less noise and having X-response, all the information is there for DSP processing to cancel the X-response with software coding.

    The frequency shift around the resonant frequency is there. The amplitude change is there. And even the changing of emitter base control voltage of the transistors (node Vtap).
    A tricky software coding will solve the GB issue. No doubt.
    The Vtap node information could also help to increase the SNR of the amplitude signal. I am wondering, whether this could significantly improve the SNR.

    I have to look for stable and low noise operating points. Then check its sensitivy (SNR). If it is ok, it could still be worth to try it out.
    Let's think of it further.

    I like the mono coil idea.
    Cheers,
    Aziz

    Leave a comment:

Working...
X