Welcome to SE.
digitalWrite()
takes a few microseconds to execute as well. There is also some overhead around the delayMicroseconds()
function.
I you need exactly 500 kHz, you would want to consider using a timer.
You can read up on how to set one up in the microcontrollers datasheet.
Unfortunately, I don't have access to an Arduino Leonardo, but here is an example code for the ATmega328P. The register names will be different, but you should be able to adapt the code to fit your Arduino.
// 500 kHz frequency
void setup() {
cli(); //Disable interrupt during setup
TCCR2A = 0;
TCCR2B = 0;
TCCR2B |= (1 << CS20); //Enable timer without prescaler
OCR2A = 15; //Do interrupt TIMER2_COMPA after reaching this counter value
TIMSK2 |= (1 << 1); //Enable TIMER2_COMPA interrupt
DDRD |= (1 << PORTD3); //Set Digital Pin 3 as Output Pin
sei(); //Enable interrupts again
}
ISR(TIMER2_COMPA_vect) { //If the counter has reached the point where the output needs to be low
TCNT2 = 0;
PIND |= (1 << PORTD3); //Toggle Digital Pin 3
}
void loop() {
//your looping code here
}
Explanation:
TIMER2
is an 8-bit timer, which means it will always count from 0 to 255, regardless of what the CPU is doing.
Normally, it counts up at the Arduino's clock frequency, like 16 MHz.
When the counter hits 15, a special code is immediately executed, called an "Interrupt Service Routine". In this code, we reset the timer and change the state of your outpin pin, resulting in a 500 kHz square wave on that pin.
We count to 15 since there are 16 steps in between "0" where the counter begins and 15, where we reset it.
16'000'000 Hz / 1 (no prescaler) / 16 (counter) / 2 = 500 kHz
The divisor of 2 comes from the fact that we need to change the pin state twice for every full square of the output signal.
delayMicroseconds
is actually much slower than that. Also theloop
has some overhead. Try putting the code insidewhile(true){ }
. Recent versions of the Arduino IDE have got better at making code faster, but if you want timing accuracy it is better to use low-level timer/counters of the AVR.