Pages: [1]   Go Down
Author Topic: Sortest pulse  (Read 1955 times)
0 Members and 1 Guest are viewing this topic.
Lanus
Offline Offline
Newbie
*
Karma: 0
Posts: 18
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi, I have an arduino nano with a ATmega328 and I can't make pulses shorter than 11microseconds. I'm using a 100MHz probe with a 250 bandwith oscilloscope. I have used the function delayMicrosecond but it doesn't works fine for periods shorter than 100microseconds, It seems "bad calibrated" the time that I measure it's not a linear function of the time that I put in the software. Using the __asm__("nop\n\t") I can't get pulses shorter than 11microseconds. I'm using the blink example in different pins but the same problem.

Thanks
Logged

Montreal
Offline Offline
Faraday Member
**
Karma: 29
Posts: 2591
Per aspera ad astra.
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Probably,  you have to replace digitalWrite with direct port manipulation. DigitalWrite / Read functions include some overhead to make safety check, and it takes some time of course, I'd expect ~5 / 7 usec that is pretty much in agreement what you have.
Logged

Global Moderator
Netherlands
Offline Offline
Shannon Member
*****
Karma: 217
Posts: 13739
In theory there is no difference between theory and practice, however in practice there are many...
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

- http://www.arduino.cc/en/Reference/PortManipulation -

by preparing the masks beforehand you can do quite fast pulsing

Code:
uint8_t HighMask;
uint8_t LowMask = 0

void setup()
{
DDRD |= B10000000;      // set pin 7 output
HighMask = PORTD | B10000000;  // set bit 7 high, rest unchanged
LowMask = PORTD & B01111111;  // set bit 7 low, rest unchanged
}

void loop()
{
PORTD = HighMask;
PORTD = LowMask;
}
Logged

Rob Tillaart

Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -
(Please do not PM for private consultancy)

Dallas, Texas
Offline Offline
God Member
*****
Karma: 31
Posts: 887
Old, decrepit curmugeon
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

- http://www.arduino.cc/en/Reference/PortManipulation -

by preparing the masks beforehand you can do quite fast pulsing

Code:
uint8_t HighMask;
uint8_t LowMask = 0

void setup()
{
DDRD |= B10000000;      // set pin 7 output
HighMask = PORTD | B10000000;  // set bit 7 high, rest unchanged
LowMask = PORTD & B01111111;  // set bit 7 low, rest unchanged
}

void loop()
{
PORTD = HighMask;
PORTD = LowMask;
}

The above will give you the fastest frequency possible with the Arduino at a given clock, then you just need a basic delay such as can be found in http://www.nongnu.org/avr-libc/user-manual/group__util__delay__basic.html to provide the short delays you need.  Maybe even just a few asm nop's
Logged

New true random number library available at: http://code.google.com/p/avr-hardware-random-number-generation/

Current version 1.0.1

Offline Offline
Edison Member
*
Karma: 19
Posts: 1041
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

- http://www.arduino.cc/en/Reference/PortManipulation -

by preparing the masks beforehand you can do quite fast pulsing

Code:
uint8_t HighMask;
uint8_t LowMask = 0

void setup()
{
DDRD |= B10000000;      // set pin 7 output
HighMask = PORTD | B10000000;  // set bit 7 high, rest unchanged
LowMask = PORTD & B01111111;  // set bit 7 low, rest unchanged
}

void loop()
{
PORTD = HighMask;
PORTD = LowMask;
}

The above will give you the fastest frequency possible with the Arduino at a given clock, then you just need a basic delay such as can be found in http://www.nongnu.org/avr-libc/user-manual/group__util__delay__basic.html to provide the short delays you need.  Maybe even just a few asm nop's

That's no way the fastest. Here's some ways to make it faster:
*disable interrupts
*Make your own loop (with a main function or putting it all in setup) to avoid function call overhead and the other check serial test thing.
*Unroll that loop
*Write to PIND to toggle
*Fill program space with PIND=0xff; so it rolls around, avoiding the two cycle rjmp call.
Logged

Global Moderator
Netherlands
Offline Offline
Shannon Member
*****
Karma: 217
Posts: 13739
In theory there is no difference between theory and practice, however in practice there are many...
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Good points!
do you have a code sample that does this all?
Logged

Rob Tillaart

Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -
(Please do not PM for private consultancy)

0
Offline Offline
Faraday Member
**
Karma: 24
Posts: 3487
20 LEDs are enough
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

You might want to read my blog: http://blog.blinkenlight.net/experiments/counting/fast-counter/ and if this is not fast enough http://blog.blinkenlight.net/experiments/counting/faster-counter/.

The only way to be even faster is to use the hardware timers / pwm capabilities of the Arduino. For software approaches I am very close to the speed limit. And I am definitely faster than the "obvious" approach


Code:
void loop()
{
PORTD = HighMask;
PORTD = LowMask;
}

Notice that my examples are deliberate attempts to push the limits and not examples for structured / layered / clean code. They use almost all (but not really all) tricks that I could think of. Anyone who has ideas to push my examples closer to the maximum is very welcome to explain them this to me. Preparing the stack to substitute subroutine calls by jumps is something I already thought of but the additional speed gains are negligible smiley-wink
Logged

Check out my experiments http://blog.blinkenlight.net

Pages: [1]   Go Up
Jump to: