Double Pulse Generation

I want to create a double pulse with initial delay of 50us. 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.

Please tell how to generate it with these decimal microseconds time periods.

You should start and make a Basic Engineering task to find an Arduino controller that meets your timing requirements fully.

2 Likes

possibly a ESP32, RPi pico or a Teensy 4
otherwise build some hardware

2 Likes

How accurate do these times need to be?

I ask because you can use direct port manipulation to get close to the times you specify, but if you are using an Arduino with a 16MHz clock frequency then all delays will be a multiple of 1/16µs or 62.5ns.

For your 1.2µs delay you could have 1.1875µs (19 clock cycles) or 1.250µs (20 clock cycles).
For your 0.7µs you would get 0.6875µs (11 clock cycles) and for your 0.6µs you would get 0.625µs (10 clock cycles).

Are these times close enough for you?

Also what is used to start the initial delay?, and are the two pulses both on the same pin, or two different pins?

3 Likes

For your 1.2µs delay you could have 1.1875µs (19 clock cycles) or 1.250µs (20 clock cycles).
For your 0.7µs you would get 0.6875µs (11 clock cycles) and for your 0.6µs you would get 0.625µs (10 clock cycles). -- This much accuracy is fine for me. Thanks! What would be rise and fall times of the pulses?

Two pulses on the same pin like a PWM. Initial delay is the Power-up Delay Time for the Gate Driver IC. This double pulse will go to the Gate Driver IC.

using a Raspberry Pi Pico running

// Raspberry Pi pico pulse generator

//  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

void setup() {
  gpio_init(5);
  gpio_set_dir(5, GPIO_OUT);
  while (1) {
    nSdelay(20);
    pulse(18);
    nSdelay(6);
    pulse(7);
  }
}

inline void pulse(byte delay) {
  gpio_put(5, 1);
  volatile byte i = delay;
  while (i--) ;
  gpio_put(5, 0);
}

inline void nSdelay(byte delay) {
  volatile byte i = delay;
  while (i--) ;
}

void loop() {}

gives
image

consider using a FPGA?

Using direct port manipulation, I've generated the delays by adding the required number of no operations. Each NOP adds one clock cycle delay.

There may be more elegant ways of generating the delays.

// https://docs.arduino.cc/hacking/software/PortManipulation

#define NOP __asm__("nop\n\t")

int inputPin = 8;             //Used to monitor power to gate driver
int outputPin = 12;           // Output to gate driver

int inputState = 0;
int lastInputState = 0;

void setup() {
  pinMode(inputPin, INPUT);
  pinMode(outputPin, OUTPUT);
}

void loop() {

  inputState = digitalRead(inputPin);
  if (inputState != lastInputState) {
    if (inputState == HIGH) {
      delayMicroseconds(50);          // 50 microseconds delay
      PORTB |= B00010000;             // output pin high
      NOP; NOP; NOP; NOP; NOP;        // add sufficient "no operations" to generate delay
      NOP; NOP; NOP; NOP; NOP;
      NOP; NOP; NOP; NOP; NOP;
      NOP; NOP;
      PORTB &= B11101111;             // output pin low
      NOP; NOP; NOP; NOP; NOP;
      NOP; NOP; NOP; NOP; NOP;
      PORTB |= B00010000;             // output pin high
      NOP; NOP; NOP; NOP; NOP;
      NOP; NOP; NOP;
      PORTB &= B11101111;             // output pin low
    }
  }
  lastInputState = inputState;
}

2 Likes

Thanks!
Can I check this on the IDE without the hardware connected on the serial plotter?

I would also disable interrupts to prevent "millis() handling" from disturbing the timing.

For that specific question, I'll refer you to the datasheet for the processor. I can't point you at one, because you didn't tell us which Arduino you're using, so look it up yourself.

After all, they're simply digital pins - set one as output, and see the specs for the details! Unless you capacitively load the signal too much, what you'll see is amply described in the datasheet.

1 Like

Unloaded the rise and fall times are 5ns or less. The loading of your circuit will make the times longer.


I've used a narrower pulse here to get both rise and fall on the same trace - this doesn't affect the risetime/falltime.

1 Like

Looks great ! Which arduino? @JohnLincoln

Its an Arduino Uno R3.

Can we have a calculation before hand from our load and the datasheet of the Arduino Uno R3? If yes, how? I did not find anything relevant from the datasheet about pulse rise and fall times. @camsysca @JohnLincoln

There is very little of relevance to your question in
Datasheet
I agree. However, not quite nothing.
If you search the doc for "rise"(13 hits), you'll find two items of note, the risetimes for I2C(irrelevant) and a risetime for SPI when master. Now I would infer that that is a specification for both clock, and MOSI signals. As far as I know, when used for SPI, there's nothing special about these pins, so I would infer that their characteristics might be applicable in the more general case. But there's no direct mention of the loading of that signal relative to that rise time.

There might be more of a hint in the "fall" search, specifically table 28.7, but I'm not sure what that capacitance calculation really suggests. Perhaps someone who knows more in this subject area is listening, though it seems unlikely.

After a really thorough dig through their website for other possibly applicable specifications, if I were really desperate to know more about this topic, approaching Microchip directly with the question would be reasonable. However, they will presumably want to know why you're asking.
Good luck!

I've measured the rise and fall times with a capacitor connected between the output and GND to degrade the rise/fall times.

I used a 47nF capacitor, and also 2 x 47nF in parallel.

The results are as follows:


47pf: rise time 8.22ns, fall time 6.82ns.


2 x 47pf: rise time 11.8ns, fall time 9.40ns

Summary:

additional capacitance rise time fall time
(pF) (ns) (ns)
0 4.54 5.04
47 8.22 6.82
94 11.8 9.4

Measured using a 200MHz oscilloscope.

1 Like

Thanks @JohnLincoln . Can I see this in the serial plotter in the Arduino Software?

#define NOP asm("nop\n\t")

int inputPin = 8; // Used to monitor power to gate driver
int outputPin = 12; // Output to gate driver

int inputState = 0;
int lastInputState = 0;

void setup() {
pinMode(inputPin, INPUT);
pinMode(outputPin, OUTPUT);

Serial.begin(115200); // Initialize serial communication
}

void loop() {
inputState = digitalRead(inputPin);
if (inputState != lastInputState) {
if (inputState == HIGH) {
Serial.println("High"); // Print "High" to Serial Monitor
delayMicroseconds(50); // 50 microseconds delay
PORTB |= B00010000; // output pin high
Serial.println(1); // Print '1' to Serial Monitor for Serial Plotter
NOP; NOP; NOP; NOP; NOP; // add sufficient "no operations" to generate delay
NOP; NOP; NOP; NOP; NOP;
NOP; NOP; NOP; NOP; NOP;
NOP; NOP;
PORTB &= B11101111; // output pin low
Serial.println(0); // Print '0' to Serial Monitor for Serial Plotter
NOP; NOP; NOP; NOP; NOP;
NOP; NOP; NOP; NOP; NOP;
PORTB |= B00010000; // output pin high
Serial.println(1); // Print '1' to Serial Monitor for Serial Plotter
NOP; NOP; NOP; NOP; NOP;
NOP; NOP; NOP;
PORTB &= B11101111; // output pin low
Serial.println(0); // Print '0' to Serial Monitor for Serial Plotter
}
}
lastInputState = inputState;
}

programmer not responding for this code..

Adding those Serial.println() statements plays havoc with the timings.

The 50µs delay has increased to 167µs.
The 1.2µs pulse width has increased to 35µs.
The 0.7µs delay has increased to 35µs.
The 0.6µs pulse width has increased to 42µs.

Ok so there is no way of seeing on the serial plotter?