1 Microsecond pulses

Hi,

I am new here and do not know much about programming, YET.

I am looking to control a gate two switch a HV supply to a transducer/receiver.

I need to control the gate with very short 5V pulses. Approximately 1.2microseconds. I hooked my arduino to a scope using the microsecond command, but the shortest pulse duration I can get is about 4 microseconds.

Does anyone know how to reduce this pulse duration down to 1.2 microseconds.

For my program:

Loop
30 microsecond (Low)
1.2 microsecond (High)
About a 10 second Delay
End Loop

If anyone can help me out with this short program I would very much appreciate it.

Thanks.

All the output pins are grouped in PORTs: PORTB, PORTC: PORTD. Each port has a corresponding PIN register: PINB, PINC, PIND. If you write a 1 to a bit in the PIN register the output pin will flip:

PIND = 0x10;  // Toggle Pin 4 (Port D bit 4)
PIND = 0x10;  // Toggle Pin 4  back (Port D bit 4)

This should cause a very short pulse on Pin 4.

johnwasser:

PIND = 0x10;  // Toggle Pin 4 (Port D bit 4)

PIND = 0x10;  // Toggle Pin 4  back (Port D bit 4)

2 clocks faster should b this pulse: :slight_smile:
PORTD = 1<<4;
PORTD = 0;

EDIT: oops - its not faster... but it makes sure that the pulse goes into the right direction... :blush:

Maybe two direct port manipulations in full speed is too fast for the OP. If you need the 1.2us, you can use assembler commands to let the processor wait:

__asm__("nop\n\t");

Such a simple nop uses a bit more than 60ns.

johnwasser:
All the output pins are grouped in PORTs: PORTB, PORTC: PORTD. Each port has a corresponding PIN register: PINB, PINC, PIND. If you write a 1 to a bit in the PIN register the output pin will flip:

PIND = 0x10;  // Toggle Pin 4 (Port D bit 4)

PIND = 0x10;  // Toggle Pin 4  back (Port D bit 4)




This should cause a very short pulse on Pin 4.

Thanks, I will try this today.

What exactly is this code saying? I like to know what I am doing so I can learn from this.

Lithanial:
What exactly is this code saying? I like to know what I am doing so I can learn from this.

furthermore the datasheet of ur ATMEL mcu explains it in detail (search for "Toggling the Pin")...

This code

PIND = 0x10;  // Toggle Pin 4 (Port D bit 4)
PIND = 0x10;  // Toggle Pin 4  back (Port D bit 4)

from johnwasser uses the feature of the PINx register to toggle the value of the selected bits (XOR, documented only in the datasheet 13.2.2).

The usual code for this is direct port manipulation:

PORTD |= 0x10; // Switch on pin 4
PORTD &= 0xEF; // Switch off pin4

It's almost the same as the code from RIDDICK but without affecting all other pins of the same port (pins 0-7).

Both code snippets just tries to switch on and off a single pin as fast as possible, probably faster than you want. That's why you may have to insert the NOP assembler statements to wait some time before toggling the pin back.

RIDDICK:

johnwasser:

PIND = 0x10;  // Toggle Pin 4 (Port D bit 4)

PIND = 0x10;  // Toggle Pin 4  back (Port D bit 4)

2 clocks faster should b this pulse: :slight_smile:
PORTD = 1<<4;
PORTD = 0;

Problem is that will also set all the OTHER pins in PORTD to 0/LOW. To avoid that you would normally use this code:

PORTD |= 0x10; // Switch on pin 4
PORTD &= 0xEF; // Switch off pin4

but they require two read-modify-write cycles which I expect will make them slower than the PIN register.

I am getting a sawtooth pattern decay with this pulse?

What did you expect? Rectangular pulses? That would mean you have absolutely no capacity on the line. How much of that is coming from your measurement equipment (a scope I guess)? Do you have the resolution to even see a rectangular signal if it was there?

Lithanial:
I am getting a sawtooth pattern decay with this pulse?

You have set it as an OUTPUT?

This gives about 1.2us pulses, and disables interrupts during the pulse output to stop them occasionally stretching.

Disabling interrupts also means that any calls to digitalWrite () for pins in the D port in interrupt routines aren't broken by our direct port manipulation.

void setup ()
{
  pinMode (4, OUTPUT) ;
  digitalWrite (4, LOW) ;  // or set to HIGH for low-going pulses.
}

void loop ()
{
  pulse () ;
  delayMicroseconds (5) ;
}

void pulse ()
{
  cli () ;
  PIND = 0x10 ;
  __asm__("nop\n\t");
  __asm__("nop\n\t");
  __asm__("nop\n\t");
  __asm__("nop\n\t");
  delayMicroseconds (1) ;
  PIND = 0x10 ;
  sei () ;
}

@MarkT: This gives you 4.2us pulses, try it out. delayMicroseconds() waits at least 4us even if the parameter is less than 4.

But you can change the code to:

void pulse ()
{
  cli () ;
  PIND = 0x10 ;
  __asm__("nop\n\tnop\n\tnop\n\tnop\n\tnop\n\t");
  __asm__("nop\n\tnop\n\tnop\n\tnop\n\tnop\n\t");
  __asm__("nop\n\tnop\n\tnop\n\tnop\n\tnop\n\t");
  __asm__("nop\n\tnop\n\tnop\n\tnop\n\tnop\n\t");
  PIND = 0x10 ;
  sei () ;
}

This should result in a pulse of 1.2us.

Thanks,

I finally got it. There is a bit of overshooting at the top and bottom of the pulsing, but I can work with this. Thanks.

pylon:
@MarkT: This gives you 4.2us pulses, try it out. delayMicroseconds() waits at least 4us even if the parameter is less than 4.

But you can change the code to:

void pulse ()

{
 cli () ;
 PIND = 0x10 ;
 asm("nop\n\tnop\n\tnop\n\tnop\n\tnop\n\t");
 asm("nop\n\tnop\n\tnop\n\tnop\n\tnop\n\t");
 asm("nop\n\tnop\n\tnop\n\tnop\n\tnop\n\t");
 asm("nop\n\tnop\n\tnop\n\tnop\n\tnop\n\t");
 PIND = 0x10 ;
 sei () ;
}




This should result in a pulse of 1.2us.

Try it out - I tested it with 100MHz scope and get 1.19us pulses. Am using the Arduino 1.0 software and avr-gcc 4.3.5
The code for delayMicroseconds has a comment saying that it is close to 1us when called with an argument of 1.

What version gives 4us then?

[edit: Arduino 1.0.1 and arduino-0022 give me 1.19us as well]

Hey Mark,

Yours also works.

I am curious, did you get any overshooting with your pulse? I was using a 60 MHz scope.

overshooting would need some inductance or capacitance...
i think both r very little inside the MCU...

maybe the wires to the oscilloscope did it?
i had that once with a 12V power cable that was connected to a capacitor via a FET... :stuck_out_tongue:

You always get ringing on an unterminated logic signal into a oscilloscope probe - add 100 ohm resistor in series with the probe to vastly reduce this. The inductance and capacitance are stray.

Which Arduino was used here?
I found out that the Due is faster than the Uno. Would this make a difference in this case?
I have a similar problem with producing microsecond pulses. Please consider checking out the new topic I made for this problem.

The OP has left this forum sometime between now and the 7.5 years ago when they asked this question.