Pages: [1] 2   Go Down
Author Topic: 1 Microsecond pulses  (Read 3504 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Newbie
*
Karma: 0
Posts: 5
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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.


 
Logged

Massachusetts, USA
Offline Offline
Tesla Member
***
Karma: 203
Posts: 8720
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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:

Code:
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.
Logged

Send Bitcoin tips to: 1L3CTDoTgrXNA5WyF77uWqt4gUdye9mezN
Send Litecoin tips to : LVtpaq6JgJAZwvnVq3ftVeHafWkcpmuR1e

Brunsbüttel, SH, F.Rep.GERM
Offline Offline
God Member
*****
Karma: 4
Posts: 596
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Code:
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: smiley
PORTD = 1<<4;
PORTD = 0;

EDIT: oops - its not faster... but it makes sure that the pulse goes into the right direction... smiley-red
« Last Edit: October 04, 2012, 01:35:04 pm by RIDDICK » Logged

-Arne

Switzerland
Offline Offline
Faraday Member
**
Karma: 108
Posts: 5144
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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:

Code:
__asm__("nop\n\t");

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

Offline Offline
Newbie
*
Karma: 0
Posts: 5
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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:

Code:
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.
Logged

Brunsbüttel, SH, F.Rep.GERM
Offline Offline
God Member
*****
Karma: 4
Posts: 596
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

What exactly is this code saying?  I like to know what I am doing so I can learn from this.
http://arduino.cc/en/Reference/PortManipulation
furthermore the datasheet of ur ATMEL mcu explains it in detail (search for "Toggling the Pin")...
« Last Edit: October 04, 2012, 07:01:42 am by RIDDICK » Logged

-Arne

Switzerland
Offline Offline
Faraday Member
**
Karma: 108
Posts: 5144
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

This code

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:

Code:
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.

Logged

Massachusetts, USA
Offline Offline
Tesla Member
***
Karma: 203
Posts: 8720
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Code:
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: smiley
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:
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.
Logged

Send Bitcoin tips to: 1L3CTDoTgrXNA5WyF77uWqt4gUdye9mezN
Send Litecoin tips to : LVtpaq6JgJAZwvnVq3ftVeHafWkcpmuR1e

Offline Offline
Newbie
*
Karma: 0
Posts: 5
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I am getting a sawtooth pattern decay with this pulse?

Logged

Switzerland
Offline Offline
Faraday Member
**
Karma: 108
Posts: 5144
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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?
Logged

0
Offline Offline
Shannon Member
****
Karma: 200
Posts: 11740
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I am getting a sawtooth pattern decay with this pulse?



You have set it as an OUTPUT?
Logged

[ I won't respond to messages, use the forum please ]

0
Offline Offline
Shannon Member
****
Karma: 200
Posts: 11740
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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.

Code:
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 () ;
}
Logged

[ I won't respond to messages, use the forum please ]

Switzerland
Offline Offline
Faraday Member
**
Karma: 108
Posts: 5144
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

@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:

Code:
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.
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 5
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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.
Logged

0
Offline Offline
Shannon Member
****
Karma: 200
Posts: 11740
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

@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:

Code:
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]
« Last Edit: October 04, 2012, 05:38:28 pm by MarkT » Logged

[ I won't respond to messages, use the forum please ]

Pages: [1] 2   Go Up
Jump to: