Go Down

Topic: Sortest pulse (Read 2057 times) previous topic - next topic

nahuelv

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

Magician

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.

robtillaart

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

by preparing the masks beforehand you can do quite fast pulsing

Code: [Select]

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;
}
Rob Tillaart

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

wanderson


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

by preparing the masks beforehand you can do quite fast pulsing

Code: [Select]

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
New true random number library available at: http://code.google.com/p/avr-hardware-random-number-generation/

Current version 1.0.1

WizenedEE



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

by preparing the masks beforehand you can do quite fast pulsing

Code: [Select]

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.

robtillaart

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

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

Udo Klein

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: [Select]

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 ;)
Check out my experiments http://blog.blinkenlight.net

Go Up