Close

Knock-off pro mini

A project log for Digital out signals over 100kHz

Experiments using Arduino compatible boards to generate signals 100kHz to 2MHz

bobubobu 02/18/2021 at 23:100 Comments

Next steps:  Try a knock-off pro mini board running ATMEGA328P.  This board is a 3.3V, so clock is only 8MHz.  This is worst case for trying to make signals above 100kHz.

- The tone() function was awful.  The square waves have periodic jitters at any frequency tried.  It seems the default tone() function is software driven. 

- There are timer libraries that use one of the 3 timers in the ATMEGA328P chip.  I tried one that uses Timer2.  This worked great.  No jitter, since it's running the peripheral timer.  This timer hardware is locked to specific pins, OC2A and OC2B.  These map out to pins 15 and 1 of the chip.  These show up as D11 and D3 in Arduino digital I/O numbering.

- Timer 2 is only 8 bits, so that limits resolution.  The function is setup to make square waves.  This seems to run in "Phase Correct PWM Mode"  This is described on the ATMEGA328P data sheet.  Anyway, the divisor resolution is limited because it is counting up and down to make a symmetrical square wave.  The count up and count down is effectively a divide by 2 from the peripheral clock.  The Timer 2 peripheral and this library was able to make a square wave as high as 500kHz in 1 microsecond steps.

- Now the goal is to make 455kHz in 1kHz steps.  For example consider 455kHz and 456kHz.  The period difference between these frequencies is only 4.8 nanoseconds.  To generate these frequencies by direct division, the clock would need a period of 4.8 nanoseconds.  This would require a peripheral clock over 200MHz.  Clearly a simple ATMEGA won't do this.  The ARM M0 won't do this either.  Something else is needed.  A FRACTIONAL divider is needed to get these in between frequencies.

This could be:

  1. Some special peripheral inside the chip.  Some chips have NCO (numerical controlled oscillator) functions.  Do more research on this.
  2. The Silicon Labs Si5351A can do this.  I tried it and will write about that later.  The problem is in the I2C interface is too slow.  The frequencies come out correctly, but a sweep is very slow.  There's a Si5350 part with fast SPI, but this isn't available on a hobbyist break-out board.
  3. The SAMD21 has a fractional PLL clock.  I don't think this is used by the normal Arduino libraries. Unfortunately, this clock is difficult to configure and requires more research.  I can't find examples in internet searches, so I would have to figure this out myself.  That could take days of experimentation.  It would be a cool solution to the problem.  The FDPLL96M can generate a clock frequency between 48 MHz to 96 MHz. This PLL can then be set to a integer multiple of the desired output frequency.  This seems nice, but the 8-way clock distribution in SAMD21 requires too much thought.
  4. External PLL device.  I am certain that a 74HC4046 PLL chip can do this job.  These parts have been around for years and are useful for making low frequency synthesizers.  I plan to get some parts and try this.  A 6 bit ripple counter can be used with the PLL to make a x64 frequency multiplier.  This will setup a n/64 fractional frequency divider.  This should allow fine frequency steps.  A 16 bit timer will be needed for "n".  In ATMEGA328P, only Timer1 is 16 bits.  The ARM M0 has many more timer options.

More information to follow.

Discussions