# Double pulse generation

I want to generate a double pulse with an initial delay of 50us (initial delay is power-up delay time for the gate driver IC.) The first pulse should be of 1.2 micro seconds and then off for 0.7 microseconds and then the second pulse for 0.6 microseconds then forever off. Can it be done with an Arduino Uno? It is the input for the gate driver.

Please tell how to generate it with these decimal microseconds time periods. 5% tolerance to the timings is fine.

• The initial delay is related to what? Do you need this sequence just once? What event triggers it? -- Independent from these missing details, consider to add "discrete" logic. Feb 20 at 7:35
• @thebusybee initial delay is Power-up Delay Time for the Gate Driver IC Feb 20 at 7:38
• Please add such important information to your question. In the comments it will not be read. -- Is the moment of the power-up known to the Uno? -- You might want to edit your question and add a schematic. -- While you're at it, please add also the acceptable tolerances of the times. Feb 20 at 7:41
• Thanks , I have done it. Moment of the power-up means? Feb 20 at 7:52
• Yes, the chip will be ready 40µs "typical" (ie you can't count on it) after both supplies have come up to the correct voltage, but how long does it take for both supplies to come up to the correct voltage? How do you detect it? Does your circuit have any control about it? What's the power up time of your isolated supply? Or is it already powered up at t=0 in your waveform plot? etc Feb 20 at 10:16

After collecting additional information, the answer to your question "Can it be done with an Arduino Uno?" is:

Generally, no; in certain cases, yes.

Why is this?

An Arduino Uno runs at 16 MHz, executing most instructions in 62.5ns. Even if you control an output pin with carefully crafted assembly, you cannot get finer resolution.

Your tolerance is 5%, used for the shortest time value of 0.6µs this gives 5% * 0.6µs = 5% * 600ns = 30 ns. This is less than the half of the possible resolution.

As you found out, you can reach the required times with some deviation:

Required time # of clocks Achieved time Deviation circa
0.6µs 10 0.625µs +4%
0.7µs 11 0.6875µs -2%
1.2µs 19 1.1875µs -1%

But this is quite coincidental, and I suspect the 5% to be hand-waved.

You might get away with hand-crafted assembly. Use nop and out P, r instructions, they take one clock each. If you like, you can alternatively use sbi P,b and cbi P,b, respectively, which take two clocks.

Additionally you require a power-up delay, but the Uno has no reference to the power-up. If you power the Uno together with the driver, please note that the start-up time of the Uno and its sketch is commonly much longer than 50µs.

This does not even take power rise time into account.

For a correctTM solution you need to invent another approach. Since there are many different ways to solve your task, which depend on more requirements we don't know, you are the one to research and check.

• Can I have 1.2µs delay with 1.1875µs (19 clock cycles) or 1.250µs (20 clock cycles). For 0.7µs - 0.6875µs (11 clock cycles) and for 0.6µs - 0.625µs (10 clock cycles) Feb 20 at 8:32
• @Andr7 Yes you can. But you need to be flexible here with you requirements, if you insist on doing it using Arduino. Well, the best way to do it is to use FPGA. Feb 20 at 11:26
• flexible as in? @ImGroot Feb 20 at 11:32
• flexibility in the timing requirements such as 1.2us can be somewhere between 1.1us and 1.3us etc. Feb 20 at 12:03

This is just rough estimate of how to do it and just to give you an idea of how much finer you can get with arduino. The best way to do it is to use the FPGA.

There is no built in function to provide a delay of less that one microsecond. So if you want fractional delay, you can use some processor operations to create the delay. On a 16 MHZ AVR, I believe each assembly language "nop" statement will give you 62.5 ns of delay.

void setup() {

digitalWrite(outPin, LOW);
delayMicroseconds(50);
digitalWrite(outPin, HIGH);
delayMicroseconds(1);
__asm__ __volatile__ (
//200ns approximately (3 * 62.5ns = 195ns)
" nop\n"
" nop\n"
" nop\n"
);

digitalWrite(outPin, LOW);
//700ns approximately (11 * 62.5ns = 687ns)
__asm__ __volatile__ (
" nop\n"
" nop\n"
" nop\n"
" nop\n"
" nop\n"
" nop\n"
" nop\n"
" nop\n"
" nop\n"
" nop\n"
" nop\n"
);

digitalWrite(outPin, HIGH);
//600ns approximately (9 * 62.5ns = 562ns)
__asm__ __volatile__ (
" nop\n"
" nop\n"
" nop\n"
" nop\n"
" nop\n"
" nop\n"
" nop\n"
" nop\n"
" nop\n"
);

digitalWrite(outPin, LOW);

}



The nop assembly language command means "do nothing" but in fact it takes a very short period to do that nothing, hence provides a very short delay before the code continues. Two nop commands in succession take twice as long to execute but the delay in code execution is still very small.

Update: Also you might have to do some calibrations (add/remove nops) if delay is longer or shorter. Also I have not included the delay of statements like digitalWrite.

• You forgot to take the time of digitalWrite() into account. Note, it is not documented. Feb 20 at 7:32
• Can I see the output on Tinkercad? Feb 20 at 7:39
• I actually have no idea about Tinkercad. Feb 20 at 11:26
• No need for hard coded NOPs. avr-gcc knows __builtin_avr_delay_cycles(n_cycles), __builtin_avr_nops(n_nops) and __builtin_avr_nop(). See AVR Built-in Functions and notice that the built-ins have more decorations than your asm has. Feb 20 at 12:00
• Noted. I was not aware of that. @Andr7 That might be a good alternate as well. Feb 20 at 12:05