Announcement

Collapse
No announcement yet.

Announcement

Collapse
No announcement yet.

Modified sketch for improved timing precision.

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

  • Teleno
    replied
    Now correct me if I'm wrong but C6 and R13 between TP6 and the input of the analog switches are totally wrong.

    C6/R13 turn the EF signal (which is constant within one period) into a decaying exponential. After efeSampleDelay the signal being subtracted at the differential integrator is not the EF signal level that's riding on the main sample, but a decayed version at a lower level, breaking the EF compensation scheme.

    In MOD3 (see /doc folder in the sketch distribution) I suggest removing C6 and shorting its pads, and removing R13. Then adjust the offset at TP6.

    Leave a comment:


  • SaltyDog
    replied
    Originally posted by Teleno View Post

    Here's the display code.

    Place this snippet at the beginning of the sketch

    PHP Code:
    #define USE_OLED

    #ifdef USE_OLED
    #include <Tiny4kOLED.h>
    #include <font16x32digits.h>
    const DCfont *largeFont FONT16X32DIGITS;
    const 
    DCfont *smallFont FONT8X16;
    uint8_t width 128;
    uint8_t height 32;
    #endif​ 


    This snippet at the beginning of setup()

    PHP Code:
    #ifdef USE_OLED
    oled.begin(widthheightsizeof(tiny4koled_init_128x32br), tiny4koled_init_128x32br);
    oled.setFont(smallFont);
    if (
    smallFont->width == 0) {
    oled.setSpacing(1);
    } else {
    oled.setSpacing(smallFont->spacing 1);
    }
    oled.on();
    oled.clear();
    oled.setCursor(02);
    oled.print("DELAY");
    oled.setCursor(00);
    oled.print("us");
    oled.setFont(largeFont);
    if (
    smallFont->width == 0) {
    oled.setSpacing(1);
    } else {
    oled.setSpacing(largeFont->spacing 1);
    }
    #endif​ 


    and this snippet in the loop()

    PHP Code:
    #ifdef USE_OLED
    oled.setCursor(700);
    oled.print(mainDelay);
    oled.print(" ");
    #endif​ 


    This is what you'll get

    Click image for larger version Name:	20240210_215145.jpg Views:	0 Size:	57.1 KB ID:	420154

    If you won't use the OLED comment out the "#define USE_OLED" line and rebuild. Otherwise Nano will wait forever for a display to be ready that doesn't exist.

    Install the following libraries in Arduino (using search box)

    Tiny4kOLED
    TinyOLED-Fonts

    The display is 0.91 inch OLED 128x32 based on controller SSD1306. Like this one: https://www.aliexpress.com/item/1005006431809403.html?
    Hi, I have just added the display and can now report the following findings:

    1. <= 20uS no targets found.
    2. 25uS all target metals found
    3. 70..75 uS Gold target disappears but other metals still found, Aluminium pull-tabs faint ...

    I can also report a session down at the beach scored one gold ring and "no" rubbish dug. As I hunted at 25uS, then confirmed target at 75uS.
    So I am a happy man.

    Different coils and dampening may give different numbers for you. But the above discrimination is possible.

    Leave a comment:


  • Teleno
    replied
    Above: Without syncing should be "With syncing", the screen shots are swapped.

    Leave a comment:


  • Teleno
    replied
    Originally posted by Teleno View Post

    There's a workaround. T1 and T3 can be made to share the same prescaler, then they can be synchronized and we can get 3 PWM outputs in pace.

    See registers GTCCR and PSSR.
    Example code to sync 16 bit timers Timer1 and Timer3 in LGT8F328P.

    PHP Code:
    /**
      * URL: https://dbuezas.github.io/arduino-web-timers/#mcu=LGT8F328P&timer=3&timerMode=PCPWM&clockPrescalerOrSource=256&FCPU_UI=16Mhz&OCnA_OutputPort=F1&CompareOutputModeA=clear-up%2C+set-down&OCR3A=85
      * Mode     : PCPWM
      * Period   : 31.875 us
      * Frequency: 31.37255 kHz
      * Outputs  :
      *  - F1: 33.33%, clear-up, set-down
      */
    void setup(){
      
    DDRB =   << DDB1;                 // Timer1 output pin 9 (D9)
      
    DDRF =   << DDF1;                 // Timer3 output pin 1 (TX)

      
    GTCCR << TSM << PSRSYNC;     // Freeze Timer1 and TImer3

      
    TCNT1 0;                           // Clear timer counts
      
    TCNT3 0;

      
    TCCR1A << COM1A1 << WGM10;   // Timer1 configuration
      
    OCR1A 85;

      
    TCCR3A << COM3A1 << WGM30;   // Timer3 configuration identical to Timer1
      
    OCR3A 85;

      
    TCCR1B << CS10;                  // Start timers with prescaler 1
      
    TCCR3B << CS30;

      
    GTCCR 0;                          // Release timers
    }
    void loop() {
      
    // put your main code here, to run repeatedly:
    }
    ​​​ 


    Without syncing

    Click image for larger version

Name:	20240212_114908.jpg
Views:	275
Size:	134.0 KB
ID:	420224


    With sync (GTCCR statements commented out)

    Click image for larger version

Name:	20240212_123124.jpg
Views:	231
Size:	134.1 KB
ID:	420225


    The difference is negligible taking into account that the efeSample delay is not critical. As long as the delay is constant. So we could do without the syncing.

    Leave a comment:


  • Teleno
    replied
    Originally posted by SaltyDog View Post
    Timer3 looks good for 3-phase motor control as well. Nice. Except, all 3 outputs are only available on the 40 pin Nano board, not the current 30 pin.
    There's a workaround. T1 and T3 can be made to share the same prescaler, then they can be synchronized and we can get 3 PWM outputs in pace.

    See registers GTCCR and PSSR.

    Leave a comment:


  • SaltyDog
    replied
    Timer3 looks good for 3-phase motor control as well. Nice. Except, all 3 outputs are only available on the 40 pin Nano board, not the current 30 pin.

    Leave a comment:


  • Teleno
    replied
    Originally posted by SaltyDog View Post

    Interesting, what onboard XTAL does it use 32MHz or 16MHz? Can it be a "drop in" replacement for this project, with tweaking for MHz?
    Mostly come with an external 16MHz crystal because they're sold as Arduino Nano's. Once the lgt8f boards are installed in Arduino IDE you can select the frequency in the menu: internal 32MHz, 16Mhz or external crystal 32Mhz or 16MHz.

    If you do a clock change you have to adjust the "#define US" in the sketch to the actual number of cycles per microsecond (32 or 16 for 32MHz or 16Mz respectively).
    Or better yet, replace "#define US 16" with "#define US ((byte) (F_CPU/1000000UL))" to adjust automatically.

    It's more that a drop in replacement, it has an extra 16bit TImer3 wth three independent PWM channels, so all three pulses (Tx, mainSample, efeSample) can be generated in hardware.

    PS: It's the one I've been using to develop this sketch

    Leave a comment:


  • SaltyDog
    replied
    By the way, I recommend this Nano clone with LGT8F328P mcu. This chip has all the instructions and registers of the Atmega328P and much more (extra 16bit timer, 12 bit ADC, 8 bit DAC, power pins, configurable gain amplifier, 16bit arithmetic and it runs at 32MHz).
    Interesting, what onboard XTAL does it use 32MHz or 16MHz? Can it be a "drop in" replacement for this project, with tweaking for MHz?

    Leave a comment:


  • Teleno
    replied
    Latest build.

    It includes all the code: PWM, FM+AM sound, OLED dislplay with current delay value

    Comment out unwanted features before building & uploading. Read carefully the instructions in the file. Links to the relevant posts regarding the PCB modifications are in the file.

    Arduino_PI_Teleno.zip
    Attached Files

    Leave a comment:


  • Teleno
    replied
    Originally posted by Gunghouk View Post

    That's why shifting right twice, as also suggested, to give 8bit resolution is preferred over simple masking.
    Well, I just say try both and find out which sound appeals to you. Test instead of speculate.

    By the way, I recommend this Nano clone with LGT8F328P mcu. This chip has all the instructions and registers of the Atmega328P and much more (extra 16bit timer, 12 bit ADC, 8 bit DAC, power pins, configurable gain amplifier, 16bit arithmetic and it runs at 32MHz).

    https://www.aliexpress.com/i/1005005854795426.html

    Install the core libraries here https://github.com/dbuezas/lgt8fx

    Then edit the file "C:\Users\....\AppData\Local\Arduino15\package s\lg t8fx\hardware\avr\2.0.7\cores\lgt8f\Arduino.h

    and comment out these lines at the bottoom of the file:

    PHP Code:
     #ifndef nop
     #define  nop() __asm__ __volatile__ ("nop" ::)
     #endif​ 

    This will prevent compilation errors, in particular with the Tiny4kOLED library.

    Leave a comment:


  • Gunghouk
    replied
    Originally posted by Teleno View Post
    For the frequency it doesn't matter. If we mask then the frequency will move in a few large steps like a cheap videogame sound. Let's try it first like this.
    That's why shifting right twice, as also suggested, to give 8bit resolution is preferred over simple masking.

    Leave a comment:


  • SaltyDog
    replied
    The input A1 has to work with is +5V - 1.3V - 0.6V; so the range for the ADC is 3,1V / 5V * 1024 = 635. This would be the maximum value of the "target" variable.
    Don't forget to subtract 0.6 for the diode drop. EDIT: Never mind, see it ..

    Leave a comment:


  • Teleno
    replied
    Originally posted by Gunghouk View Post
    Don't forget to mask, or shift right a couple of places, the 635 to loose the jittery bits.
    For the frequency it doesn't matter. If we mask then the frequency will move in a few large steps like a cheap videogame sound. Let's try it first like this.

    Leave a comment:


  • Gunghouk
    replied
    Don't forget to mask, or shift right a couple of places, the 635 to loose the jittery bits.

    Leave a comment:


  • Teleno
    replied
    Originally posted by SaltyDog View Post
    Hmm, doesn't the analog voltage at TP10 cover +-5v ? The A1 input of the uP will only except positive 0..5v, are you relying on the uP input protection diode clipping the negative?
    Yes I think I screwed it all up but I can't delete anything. I was trying to do too many mods at the same time.

    Max output voltage at TP10 is +5V - 1.3V. We just need a diode with the anode to TP10 and cathode to A1 plus a 100k or so resistor from A1 to GND.

    The input A1 has to work with is +5V - 1.3V - 0.6V; so the range for the ADC is 3,1V / 5V * 1024 = 635. This would be the maximum value of the "target" variable.

    The mapping code is then

    PHP Code:
    word freq map(target0635FREQ_MINFREQ_MAX); 

    The 120k resistor should be replaced by said diode. Then all is good.

    Click image for larger version  Name:	Mod-frequency.png Views:	0 Size:	508.5 KB ID:	420167


    If instead of TP10 we link TP6 to A1 then we can do direct sampling and DSP, that's another game.

    Leave a comment:

Working...
X