Announcement

Collapse
No announcement yet.

VLF MD with digital signal processing : Bee-Buzz 1

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

  • Atul Asthana
    replied
    Originally posted by boilcoil View Post
    You can make fast samples with slow ADC, but you need to store the signals in buffer capacitors. Of course, the number of samples is limited, but the sampling speed is as fast as you want (it depends only on the time constant of the loading circuits).

    Something like this:
    [ATTACH]n432404[/ATTACH]

    Of course, this is a PI metal detector, but it illustrates the principle.

    PS: and costs $15​
    ​
    sample and hold !
    I recall using these with slow 8 bit adcs, some 35 years ago, using lf356 (as far as I can recall).
    Last edited by Atul Asthana; 01-04-2025, 11:19 PM.

    Leave a comment:


  • Atul Asthana
    replied
    Originally posted by Carl-NC View Post

    This represents about +/- 3.5% which isn't enough to make a difference in the target responses. MF detectors run a minimum of a 3x frequency ratio and preferably 5x. For 6kHz, you would want the second frequency to be 18kHz.

    It is possible to switch a resonated coil between 2 frequencies but it is a slow process. It takes some time for the coil oscillation to settle after switching frequencies. This is why all MF detectors use linear ramps instead of sinusoidal oscillations.
    I searched and found some oblique references to using first derivatives of smplitude and phase with frequency (slope) [d(amplitude)/d(frequency) and d(phase)/d(frequency) ] for estimating target depth, size and material identification, though it requires creating empirical formula to actually utilise this info. but none the less, it improves on the anslysis, though tecommendations are to use more frequencies.

    I was wondering if there are any patents on this, that I can refer to.

    Leave a comment:


  • Tinkerer
    replied
    Originally posted by ivconic View Post
    Carl continues to "annoy my vanity" with constant RTOS "slapping"!
    It's as if he knows that I'm weak here and that I haven't done it before!
    I'm going to have to get mad, sit down and learn it once and for all!
    But if I've already decided to start with Nucleo 144... then I don't need it too much!

    ​

    Leave a comment:


  • Marchel
    replied
    Now I see that the author of the mole metal detector also used the STM32H7 in the new version and writes that the detector achieves better results.

    Leave a comment:


  • boilcoil
    replied
    Ha, ha, the cost of the money transfer will be greater than the amount.
    But let's not spam Atul's topic.

    Leave a comment:


  • moodz
    replied
    Originally posted by boilcoil View Post
    You can make fast samples with slow ADC, but you need to store the signals in buffer capacitors. Of course, the number of samples is limited, but the sampling speed is as fast as you want (it depends only on the time constant of the loading circuits).

    Something like this:
    [ATTACH]n432404[/ATTACH]

    Of course, this is a PI metal detector, but it illustrates the principle.

    PS: and costs $15​
    ​
    Do we send the money to you or is it someone else's idea ?

    good tip though.

    Leave a comment:


  • boilcoil
    replied
    You can make fast samples with slow ADC, but you need to store the signals in buffer capacitors. Of course, the number of samples is limited, but the sampling speed is as fast as you want (it depends only on the time constant of the loading circuits).

    Something like this:
    PI_TLO82_PUBLICATE.rar

    Of course, this is a PI metal detector, but it illustrates the principle.

    PS: and costs $15​
    ​

    Leave a comment:


  • ivconic
    replied
    Carl continues to "annoy my vanity" with constant RTOS "slapping"!
    It's as if he knows that I'm weak here and that I haven't done it before!
    I'm going to have to get mad, sit down and learn it once and for all!
    But if I've already decided to start with Nucleo 144... then I don't need it too much!

    ​

    Leave a comment:


  • moodz
    replied
    Originally posted by Carl-NC View Post

    I suspect it will work just fine. I use STM processors for all my professional detector projects, and have used G0, L0, L4, and F7 families. Most of them running at 80Mhz and all running RTOS, no issues debugging. The ESP32 certainly has power to spare, but the F103 should do the job with no problem.
    The difference being that you are an experienced designer .. and you know ( presumably from knowledge and experience ) what works and does not so you can dimension the processor capbility to the code.
    Which is not the case with kickoff projects that start with "tell me what I need to know" ... which we ( Ivica ) did.

    Leave a comment:


  • Atul Asthana
    replied
    Originally posted by Carl-NC View Post

    This represents about +/- 3.5% which isn't enough to make a difference in the target responses. MF detectors run a minimum of a 3x frequency ratio and preferably 5x. For 6kHz, you would want the second frequency to be 18kHz.

    It is possible to switch a resonated coil between 2 frequencies but it is a slow process. It takes some time for the coil oscillation to settle after switching frequencies. This is why all MF detectors use linear ramps instead of sinusoidal oscillations.
    I agree that the difference in the frequencies is too small, but, hopefully we will be able to avoid some inband and synchronous noise and even look at outliers to reject them on doing statistical analysis.

    And I am pretty sure that more data points of amplitude and phase will be helpful in better target identification.

    please comment.

    Leave a comment:


  • Carl-NC
    replied
    Originally posted by moodz View Post
    However if you are going to get into developmental DSP you will need more powerful hardware than a blue pill for development work because there will be insufficient processing overhead for debugging code etc.
    I suspect it will work just fine. I use STM processors for all my professional detector projects, and have used G0, L0, L4, and F7 families. Most of them running at 80Mhz and all running RTOS, no issues debugging. The ESP32 certainly has power to spare, but the F103 should do the job with no problem.

    Leave a comment:


  • Carl-NC
    replied
    Originally posted by Atul Asthana View Post
    I was considering whether we could explore using 2–3 different TX frequencies interleaved in adjecent time slots, frrquencies being on either side of the main TX frequency.

    Our coils have a low Q and perform similarly good enough at 5800 Hz and 6200 Hz. With an op-amp filter bandwidth of ±400 Hz and precise control over the TX frequency, we can operate within these limits. Additionally, the signal processing in each TX slot is independent of the preceding or succeeding slots.

    This allows us to transmit and process different frequencies in separate time slots: Slot 1 at 5800 Hz, Slot 2 at 6000 Hz, and Slot 3 at 6200 Hz. The received signals from these slots can be analyzed using the Goertzel algorithm to extract amplitude and phase data for each frequency.
    This represents about +/- 3.5% which isn't enough to make a difference in the target responses. MF detectors run a minimum of a 3x frequency ratio and preferably 5x. For 6kHz, you would want the second frequency to be 18kHz.

    It is possible to switch a resonated coil between 2 frequencies but it is a slow process. It takes some time for the coil oscillation to settle after switching frequencies. This is why all MF detectors use linear ramps instead of sinusoidal oscillations.

    Leave a comment:


  • Atul Asthana
    replied
    Originally posted by moodz View Post
    Ok I can see I am upsetting you .. and I apologise for that. But there have been many projects started and not finished on this forum ( dont worry me included ... but I am easily distracted and procrastination so I have at least 60 or 70 projects . not all metaldetectors on the go ) The goals were set out in a very clear way and you asked for advice ... so I gave you some. Obviously not everyone thinks the same way but one thing is that if you research then you will find quite a few VLF detector projects and the one you propose is really not aspiring to any new "breakthrough" so its a YAVLF project ... Yet Another VLF project and since you already nominated the hardware before knowing the "system solution" ie if the system ( ie code ) that will eliminate most people on this forum as they will not have the hardware / development environment and so the commentary will be less informed than you as the project lead / director would like. Some would call this armchair commentary.
    For instance I use LTSPICE to simulate analogue ccts before I build them in most cases ... and this saves time .. but also if you publish the simulation on forums like this then others can also run the simulation and comment more effectively as they can easily run the sim and provide more meaningful commentary.
    So I was essentially trying to advise you that if you want a fully digital VLF detector then just develop the code ( signal flow solution ) that does that unconstrained by any hardware consideration THEN select the appropriate hardware that MATCHES the requirements set by your code. So that was my advice not trying to shut you down or anything. If you choose to go the other way its a free world.

    PS ... the blue pill uses its VDD as the ADC reference voltage rather than a bandgap reference so its a poor choice for frontend ADC if noise is a concern.
    I am not annoyed.

    I was expecting comments on this project, specially how to improve the performance, the adc with vdd as reference. thats the reason that I am trying to average out the noise over many points, many times.

    some times, knowing the limitations, and still trying to find a way can be useful.

    even with these limitations, this machine should work close to the best of the analog detectors and have a construction cost of around usd 30 or less, if you build the coils and the housing, which is far less than usd 600.

    I am interested in deploying my 30 years old knowledge of signal processing with the modern low cost, general purpose processors by direct sampling. which even 80486 + low frequency low resolution adcs was not achievable some 30 years ago.

    so let us see, what we can acheve.

    after all, the project details are available, and the software methodology of the system is so generic that it can be implemented on any sufficiently powerful processor/development board.

    but for the present, my aim is clear snd that is to stick to blue pill board.

    I will later look at more capable processors. one of my friends has imx7d boards with an rtos and will try to port my methodology onto it, after its done on bluepill.
    Last edited by Atul Asthana; 01-04-2025, 05:09 AM.

    Leave a comment:


  • ivconic
    replied
    My natural born altruism (lol-Paul) dictates that I see the job through.
    So here is a ready solution for STM32.
    That's all from me for now.
    I'm going to continue reading the book... much to learn yet.


    Code:
    // Piece of code for metal detector with adjustable TX frequency (6-18kHz, - lets make this more interesing !!!) and synchronized dual ADC
    // Fast dual analog reading with DMA and continuous scan mode
    // Hardware:
    // - VREF (LM336-2.5) on PA0 (ADC1_IN0) // - VREF Out to PA0
    // - RX processed baseband sampled signal 1 on PA1 (ADC1_IN1) - "X" derivative
    // - RX processed baseband sampled signal 2 on PA2 (ADC1_IN2) - "R" derivative
    // - TX output on PA8 (TIM1_CH1) - TX clock, goes to TX driver
    // - VREF GND to Blue Pill GND
    // - VREF VDD through current limiting 2.2kΩ resistor to Blue Pill 3.3V
    // - 0.1µF bypass cap between positive and negative​
    
    #define ADC_BUFFER_SIZE 3
    #define PWM_FREQ_MIN 6000   // 6kHz  - lets make this more interesing !!!
    #define PWM_FREQ_MAX 18000  // 18kHz - lets make this more interesing !!!
    
    volatile uint16_t adc_values[ADC_BUFFER_SIZE];
    volatile uint32_t current_freq = 10000; // Start at 10kHz
    
    void timer_pwm_init(uint32_t frequency) {
        // Enable TIM1 and GPIOA clocks
        RCC->APB2ENR |= RCC_APB2ENR_TIM1EN | RCC_APB2ENR_IOPAEN;
        
        // Configure PA8 as alternate function output (TIM1_CH1)
        GPIOA->CRH &= ~(GPIO_CRH_MODE8 | GPIO_CRH_CNF8);
        GPIOA->CRH |= GPIO_CRH_MODE8_1 | GPIO_CRH_MODE8_0 | GPIO_CRH_CNF8_1;
        
        // Calculate PWM parameters for 72MHz clock
        uint32_t period = (72000000 / frequency) - 1;
        
        TIM1->PSC = 0;            // No prescaler
        TIM1->ARR = period;       // Auto-reload value
        TIM1->CCR1 = period / 2;  // 50% duty cycle
        
        // PWM mode 1, preload enable
        TIM1->CCMR1 = TIM_CCMR1_OC1M_1 | TIM_CCMR1_OC1M_2 | TIM_CCMR1_OC1PE;
        
        // Enable output compare
        TIM1->CCER = TIM_CCER_CC1E;
        
        // Enable counter and main output
        TIM1->CR1 = TIM_CR1_CEN;
        TIM1->BDTR = TIM_BDTR_MOE;
    }
    
    void adc_dma_init(void) {
        // Enable clocks
        RCC->APB2ENR |= RCC_APB2ENR_IOPAEN | RCC_APB2ENR_ADC1EN;
        RCC->AHBENR |= RCC_AHBENR_DMA1EN;
        
        // Configure analog pins
        GPIOA->CRL &= ~(GPIO_CRL_MODE0 | GPIO_CRL_CNF0 |
                        GPIO_CRL_MODE1 | GPIO_CRL_CNF1 |
                        GPIO_CRL_MODE2 | GPIO_CRL_CNF2);
        
        // DMA configuration
        DMA1_Channel1->CCR = 0;
        DMA1_Channel1->CPAR = (uint32_t)&ADC1->DR;
        DMA1_Channel1->CMAR = (uint32_t)adc_values;
        DMA1_Channel1->CNDTR = ADC_BUFFER_SIZE;
        DMA1_Channel1->CCR |= DMA_CCR_CIRC | DMA_CCR_MINC |
                             DMA_CCR_PSIZE_0 | DMA_CCR_MSIZE_0;
        
        // Enable DMA
        DMA1_Channel1->CCR |= DMA_CCR_EN;
        
        // ADC configuration
        ADC1->CR1 = 0;
        ADC1->CR2 = 0;
        
        // Configure for external trigger from Timer1
        ADC1->CR2 |= ADC_CR2_EXTTRIG |    // External trigger enable
                     (4 << 17) |          // Timer1 CC1 event as trigger
                     ADC_CR2_DMA |        // Enable DMA
                     ADC_CR2_ADON;        // Enable ADC
        
        // Scan mode configuration
        ADC1->CR1 |= ADC_CR1_SCAN;
        ADC1->SQR1 = ((ADC_BUFFER_SIZE - 1) << 20);
        ADC1->SQR3 = 0 | (1 << 5) | (2 << 10);
        
        // Sample times
        ADC1->SMPR2 = (7 << 0) |   // VREF: 239.5 cycles
                      (4 << 3) |   // AN1: 41.5 cycles
                      (4 << 6);    // AN2: 41.5 cycles
        
        // Calibrate
        delay_ms(1);
        ADC1->CR2 |= ADC_CR2_CAL;
        while(ADC1->CR2 & ADC_CR2_CAL);
        
        // Start ADC
        ADC1->CR2 |= ADC_CR2_ADON;
    }
    
    typedef struct {
        float voltage1;
        float voltage2;
    } analog_readings_t;
    
    analog_readings_t get_latest_voltages(void) {
        analog_readings_t results;
        uint16_t vref = adc_values[0];
        
        results.voltage1 = (adc_values[1] * 2.5f) / vref;
        results.voltage2 = (adc_values[2] * 2.5f) / vref;
        
        return results;
    }
    
    void set_frequency(uint32_t new_freq) {
        if(new_freq >= PWM_FREQ_MIN && new_freq <= PWM_FREQ_MAX) {
            current_freq = new_freq;
            timer_pwm_init(new_freq);
        }
    }
    
    void main(void) {
        analog_readings_t readings;
        
        // Initialize systems
        timer_pwm_init(current_freq);
        adc_dma_init();
        
        while(1) {
            readings = get_latest_voltages();
            
            // Process readings here
            // They are automatically synchronized with the TX signal
            
            // Example: Adjust frequency based on some condition
            // set_frequency(new_frequency);
        }
    }​
    ​

    Leave a comment:


  • ivconic
    replied
    Ok, the "scenario" is slowly folding itself, I don't know if you understand all this Atul?
    Let's agree on the STM32 bluepill, ok?
    You chose STM32 and that's ok. But you have to follow the conditions as they are.

    1) The chosen platform is STM32 bluepill
    2) The only sensible choice is baseband sampling with this platform.
    3) Use an external voltage reference.
    a) cheapest choise is LM336.
    b) very good choice is LT1461.
    ...

    Look!
    The code is written by itself!


    Code:
    // Configure ADC to use external VREF with two analog inputs
    // Hardware setup:
    // - VREF chip (like LM336-2.5) output connected to PA0 (ADC1_IN0)
    // - First analog input on PA1 (ADC1_IN1) - "X"
    // - Second analog input on PA2 (ADC1_IN2) -"R"
    // - VREF GND to Blue Pill GND
    // - VREF VDD through current limiting 2.2kΩ resistor to Blue Pill 3.3V
    // - VREF Out to PA0
    // - 0.1µF bypass cap between positive and negative​
    
    void adc_init_external_vref(void) {
        // Enable GPIOA and ADC1 clocks
        RCC->APB2ENR |= RCC_APB2ENR_IOPAEN | RCC_APB2ENR_ADC1EN;
        
        // Configure PA0 (VREF), PA1 (analog1), PA2 (analog2) as analog inputs
        GPIOA->CRL &= ~(GPIO_CRL_MODE0 | GPIO_CRL_CNF0 |
                        GPIO_CRL_MODE1 | GPIO_CRL_CNF1 |
                        GPIO_CRL_MODE2 | GPIO_CRL_CNF2);
        
        // ADC configuration
        ADC1->CR2 = 0;                   // Reset CR2 register
        ADC1->CR2 |= ADC_CR2_ADON;       // Enable ADC
        
        // Wait for ADC to stabilize
        delay_ms(1);
        
        // Calibrate ADC
        ADC1->CR2 |= ADC_CR2_CAL;        // Start calibration
        while(ADC1->CR2 & ADC_CR2_CAL);  // Wait for calibration
    }
    
    // Structure to hold both readings
    typedef struct {
        float voltage1;
        float voltage2;
    } analog_readings_t;
    
    analog_readings_t read_dual_voltages(void) {
        uint16_t vref_reading, signal1_reading, signal2_reading;
        analog_readings_t results;
        
        // Read VREF on PA0
        ADC1->SQR3 = 0;                  // Select channel 0 (PA0)
        ADC1->CR2 |= ADC_CR2_ADON;       // Start conversion
        while(!(ADC1->SR & ADC_SR_EOC)); // Wait for conversion
        vref_reading = ADC1->DR;
        
        // Read first analog input on PA1
        ADC1->SQR3 = 1;                  // Select channel 1 (PA1)
        ADC1->CR2 |= ADC_CR2_ADON;       // Start conversion
        while(!(ADC1->SR & ADC_SR_EOC)); // Wait for conversion
        signal1_reading = ADC1->DR;
        
        // Read second analog input on PA2
        ADC1->SQR3 = 2;                  // Select channel 2 (PA2)
        ADC1->CR2 |= ADC_CR2_ADON;       // Start conversion
        while(!(ADC1->SR & ADC_SR_EOC)); // Wait for conversion
        signal2_reading = ADC1->DR;
        
        // Calculate actual voltages using VREF reading
        // Assuming VREF chip outputs 2.5V (for LM336-2.5)
        results.voltage1 = (signal1_reading * 2.5f) / vref_reading;
        results.voltage2 = (signal2_reading * 2.5f) / vref_reading;
        
        return results;
    }
    
    // Example usage in main
    void main(void) {
        analog_readings_t readings;
        
        // Initialize ADC with external reference
        adc_init_external_vref();
        
        while(1) {
            readings = read_dual_voltages();
            
            // Use the readings
            printf("Voltage 1: %.3fV\n", readings.voltage1);
            printf("Voltage 2: %.3fV\n", readings.voltage2);
            
            delay_ms(1000);  // Read every second
        }
    }
    ​

    "X" and "R" are derivative from both channels.
    As a result in the code you have "readings.voltage1" and "readings.voltage2" variables that contain samples from both channels.
    What will you do with them; it's up to you and your ideas about the filters you will apply.

    "delay_ms(1000); // Read every second"
    of course this is too slow and serves only as an example.
    You will adjust the sampling rate according to your needs.
    ...

    ​A much faster and better approach is analog readings using DMA.
    Among us Serbs, there is an old saying: "As much money - as much music"!

    ​​

    Leave a comment:

Working...
X