Programing Hz

I am trying to achieve 14.035Hz.

This code should work, but when I check it with a multimeter it gives me 14.00Hz.

Whats wrong with it?

int led = 2;

void setup() {
  pinMode(led, OUTPUT);     
}
void loop() {
  digitalWrite(led, HIGH);
  delay(35);
  delayMicroseconds(625);
  digitalWrite(led, LOW);
  delay(35);
  delayMicroseconds(625);
}

The digitalWrite instructions take time. In fact they are quite slow (comparatively). Also looping take a small amount of time. So the first microsecond delay needs adjusting down a bit, and the second one by a slightly different amount to allow for the time it take to loop back. Probably best done by measuring.

Direct port access is somewhat faster, if you use that you should be closer to the theoretical figure.

On a 16 MHz Uno I measure the on pulse width as 35.706250 mS and the off pulse width as 35.697917 mS so that should give you your adjustment figures.

This got closer on my tests, it fluctuates slightly because of interrupts:

int led = 2;

void setup() {
  pinMode(led, OUTPUT);     
}
void loop() {
  digitalWrite(led, HIGH);
  delay(35);
  delayMicroseconds(625 - 81);
  digitalWrite(led, LOW);
  delay(35);
  delayMicroseconds(625 - 73);
}

The direct port access reduces the adjustment but not by a huge amount:

int led = 2;

void setup() {
  pinMode(led, OUTPUT);     
}
void loop() {
  PORTD |= 0x04;
  delay(35);
  delayMicroseconds(625 - 75);
  PORTD &= ~0x04;
  delay(35);
  delayMicroseconds(625 - 72);
}

I am trying to achieve 14.035Hz.

I hope you're not intending using your device on public roads.

Oh wow, the initial reference went over my head. But I see from Google why that frequency is so interesting. I can't help thinking if that is used in an unauthorized way you will soon draw some very obvious attention to yourself.

Nick,

why not merge ?

delay(35);
delayMicroseconds(625 - 81);

to just

delayMicroseconds(35625 - 81);

From the delayMicroseconds documentation:

Currently, the largest value that will produce an accurate delay is 16383. This could change in future Arduino releases. For delays longer than a few thousand microseconds, you should use delay() instead.

Straight delay uses the hardware timers. delayMicroseconds uses a timing loop. I would imagine the loop might drift (eg. with interrupts firing). So I think the combination would give a more accurate result.

Thanks, for reading the manual for me :blush: