Output pulse / accurate Timing using micros

How can i get more accurate Timing using micros output pulse.
here is my code.
when testing the pulse is not accurate..

output pulse timing
50.5us
58.3us
60.2us
48.5us
62.1us

unsigned long currentMicros, Micros;
int HILO = 0;
int DELAY = 50;
void setup() 
{
 DDRD |= 1 << 5; // SET D5 AS OUTPUT
 cli();   //  Disable global interrupts while we make our changes.
 TIMSK0 &= ~(1 << TOIE0);   //  Disable Timer 0.
 sei();    //  Enable global interrupts.
 currentMicros = micros();
 Micros = currentMicros; 
}
void loop() 
{
 currentMicros = micros();
 if(currentMicros - Micros > DELAY && HILO == 0) { PORTD |= 0B00100000; HILO = 1; Micros = currentMicros; } // SET D5 HIGH
 if(currentMicros - Micros > DELAY && HILO == 1) { PORTD &= 0B00000000; HILO = 0; Micros = currentMicros; } // SET D5 LOW
}

s1.JPG

You can't, really. What do you need it for? If you just need to generate a pulse train, use a timer.

it takes time to cycle through loop (), this is where some time discrepancy is coming from, a while ago i did measure it on a due, it was microseconds if i remember, on a 328 you can times that by at least 4. you could try putting it in a while loop and see the difference.

more is coming from the 2 ifs, try an if else, so only one condition gets checked each time

but you seem to be familiar with register access, set up a pwm output, or a timer counter interrupt. then it will be accurate to clock cycles not microseconds

thinks ill try a while loop. i will be using it to send bits to a RX module when i get the timing accurate

Also you don't need to perform the test on currentMicros twice. You're wasting time there.

i dont know much about communication. but i imagine the timing would have to be fairly accurate. you wont get that with a polling approach. you havent even added any other code, once you do your timing goes out the window

use an interrupt

I tryed this it is better but still not accurate//

unsigned long currentMicros, Micros;
int HILO = 0;
//////////////////////// SEND BIT 0
int DELAYHI0 = 262;
int DELAYLO0 = 418;
//////////////////////// SEND BIT 1
int DELAYHI1 = 471;
int DELAYLO1 = 209;
////////////////////////
void setup() 
{
 DDRD |= 1 << 5; // SET D5 AS OUTPUT

 currentMicros = micros();
 Micros = currentMicros; 
}
void loop() 
{
 PULSE();
}

void PULSE()
{
 while(1)
  {
  currentMicros = micros();
  /////////////////////////////////////////////////////////////////////////////////////////////////////////////// SEND BIT 0
  if(currentMicros - Micros > DELAYLO0 && HILO == 0) { PORTD |= 0B00100000; HILO = 1; Micros = currentMicros; } // SET D5 HIGH FOR 262us
  currentMicros = micros();
  if(currentMicros - Micros > DELAYHI0 && HILO == 1) { PORTD &= 0B00000000; HILO = 2; Micros = currentMicros; } // SET D5 LOW  FOR 418us
  /////////////////////////////////////////////////////////////////////////////////////////////////////////////// SEND BIT 1
  currentMicros = micros();
  if(currentMicros - Micros > DELAYLO1 && HILO == 2) { PORTD |= 0B00100000; HILO = 3; Micros = currentMicros; } // SET D5 HIGH FOR 262us
  currentMicros = micros();
  if(currentMicros - Micros > DELAYHI1 && HILO == 3) { PORTD &= 0B00000000; HILO = 0; Micros = currentMicros; } // SET D5 LOW  FOR 418us
  }
}

joeblogs:
i dont know much about communication. but i imagine the timing would have to be fairly accurate. you wont get that with a polling approach. you havent even added any other code, once you do your timing goes out the window

use an interrupt

how??

s2.JPG

Wow. I tell you you don't need to do it twice, now you're doing it four times! :slight_smile:

https://forum.arduino.cc/index.php?topic=223286.0

vmansmx5:
How can i get more accurate Timing using micros output pulse.

It is much easier to read code when there is one item on each line like

if (currentMicros - Micros > DELAY && HILO == 0) {
    PORTD |= 0B00100000; 
    HILO = 1; 
    Micros = currentMicros; 
}

This will be a little more accurate if you change the last line to

    Micros += DELAY;

as it will eliminate accumulating errors

For an explanation read Several Things at a Time

However micros() increments in steps of 4 and if that is too coarse then you need to use a HardwareTimer to manage the timing.

...R