40 Hz Square wave with 8kHz tone

In my opinion this is the least accurate solution, but it is something to start with.
Using Arduino Uno.

unsigned long previousMicros;
const unsigned long interval = 12500;
bool active = false;

const int ledPin = 13;
const int outputPin = 2;

void setup() 
{
  pinMode( ledPin, OUTPUT);
  pinMode( outputPin, OUTPUT);  // not required for 'tone()'
}

void loop() 
{
  unsigned long currentMicros = micros();    // 4 microseconds accuracy on Arduino Uno

  if( currentMicros - previousMicros >= interval)
  {
    previousMicros += interval;      // special code to keep in sync with time

    if( active)
    {
      digitalWrite( ledPin, LOW);
      noTone( outputPin);
    }
    else
    {
      digitalWrite( ledPin, HIGH);
      tone( outputPin, 8000);
    }
    active = !active;
  }
}

You can see this in action in the Wokwi simulator:

The Wokwi simulator has a simulated Logic Analyzer which can capture the signals. It does not matter how slow or how fast your computer is, the generated signals are exactly as a real Arduino Uno board. That means you can measure the timing of the created VCD file in PulseView.

Just a few measurements at random places:
Timing of the 40Hz : 24.9856ms, 25.00096ms
Timing of the 8kHz : 8.00256kHz, 7.992327kHz
That is pretty good, but there is a interrupt running in the background (Arduino uses Timer0 interrupt), that has influence on the timing.

1 Like