Delay doesn't work when using vars.

For some reason, when I typed up this program, the lasers did not flash as they should. The code is commented fairly well, so I don’t think it needs much explanation. The issue is in loop()

// These are the laser’s power pins.
unsigned long int redPin = 11;
unsigned long int bluePin = 12;
unsigned long int greenPin = 13;
// This should be hooked into the monitor’s sync signal
unsigned long int syncPin = 10;
// Put monitor Hertz here
unsigned long int hertz = 60;
unsigned long int timing = ((1/(hertz/3))*1000);
// Press this to sync to your monitor
unsigned long int syncSwitch = 2;
void setup ()

// Pin Settings
pinMode(redPin, OUTPUT);
pinMode(bluePin, OUTPUT);
pinMode(greenPin, OUTPUT);
pinMode(syncPin, INPUT);
// Setting interrupt pins
attachInterrupt(0, sync, RISING);
// Enabling Interrupts

void loop()
digitalWrite(redPin, HIGH);
digitalWrite(redPin, LOW);
digitalWrite(greenPin, HIGH);
digitalWrite(greenPin, LOW);

void sync()
if (digitalRead(syncPin) != HIGH);
void sync();
void loop();

The strange thing is, if I replace the variable in delay with a number, it works just fine! It’s okay for prototyping, but I would really like to have this work more automatically.

Why does your sync() ISR call loop() again? sync() will automatically return to the main loop when it completes.

The way it’s written I think what happens is sync() calls loop() before interrupts are re-enabled (because sync() is an ISR). Then when delay(timing) is encountered it waits forever… since interrupts are still disabled.

Test it out and let us know.

You have a case of unwanted integer value truncation.

The value: ((1/(hertz/3))*1000)

Goes to: ((1/(60/3))*1000)

Goes to: ((1/20)*1000)

Goes to: (0 * 1000) which is zero.

1/20=0? That doesn't seem quite right...I need that amount of specification for my project. Can you suggest a way to rewrite it so it will work?

1/20=0? That doesn't seem quite right

Well, it's a very good approximation. What does 1.0 / 20.0 give?

You can change this... ((1/(hertz/3))*1000)

to this... (1000/(hertz/3))

and you'll get a better answer. The piece of information you seem to be missing is that integer math (which is the default) doesn't generate fractional results. That is performing math on integers creates integer results.


try to do the multiplications first:

1000/(hertz/3)    [better]
(3*1000)/hertz   [even better!]

Integer arithmetic may require you to remember algebra to get the numbers you expect!

I'd do it with floating point calculation:

const float hertz = 60.0
const unsigned long int timing = (unsigned long int) ((1.0 /(hertz / 3.0)) * 1000.0);

So, floating point allows it to have an infinite decimal? That would be helpful in extremely precise situations, but this is just to determine a timing speed, so I think I'll use one of the others.

Thanks for all the useful comments!

Aww, heck. I even typed in the hertz manually, only leaving a x1000 function in. It still drops to 0! Why can't the arduino handle .05, at the very least? I guess I'll have to do it all manually....Oh well...

@west Interesting comment, as I'm in Algebra 2 Right now... :P

I did something handy this time. I added a serial output of the timing variable, to make sure it's not 0.

Oh, sorry I missed your comment, AWOL! Now, 60 works fine, but I really need it at 180, which comes out around 1.66666666666. This requires decimals, or it gets rounded to 1, which just doesn't do at all. :-[. I found a working Solution, however. Using float didn't work, as delay only takes integers, and I needed around 1.666. So I used delayMicroseconds instead. I am very happy with the result. Onward with progress! ;D ;D ;D ;D ;D

So, floating point allows it to have an infinite decimal?

If by "it" you mean delay time - it is not so. Delay works with integers and so a float with decimals will be truncated to a 32-bit integer before it is used. The delay function is not very precise for short intervals - a delay of 2 milliseconds may be anything from 0 to 2 milliseconds.

If you need precise short interval delays (a few milliseconds or less), you should look at the "delayMicroseconds" function.

which comes out around 1.66666666666. This requires decimals, or it gets rounded to 1

No, that's truncation, not rounding. If you want rounding, add 0.5.

So, truncation cuts off decimals without rounding? That's good to know. Hopefully, delaymicroseconds will be precise enough for what I'm doing.