Welcome! Log In Create A New Profile

Advanced

digitalwritefast, digitalwrite, and direct port manipluation

Posted by jamesdanielv 
digitalwritefast, digitalwrite, and direct port manipluation
July 12, 2011 02:11AM
just thought i would point out that digitalWriteFast is easy to use fairly safe, and implement in firmware and increases pin speed dramatically. the code works on arduino/sanguino/mega. no changes are needed other than recompiling.


a few things about using it. here [www.arduino.cc]

this method is also a lot safer that direct manipulation, because some safeguards are in place for pwm pins, and pins are verified to see if they change or are hardwired from #define

digitalWriteFast improves performance around 20 times!

a few things to note about digitalWriteFast. the operations are not completed in 1 instruction so disabling interrupts during a pin change is necessary in some conditions. Also some registers on mega are not directly accessible, and therefore will require an additional instruction. and also be aware of conditional statements else, if, while that normally would be one line, but when changing the compiler needs to have all conditional statements enclosed with {} that contain it.

another issue is with changing pin states rapidly. sometimes when changing several pins on the same port within less than a (time measure) micro second time, noise can cause a miss read of the port pin, and when the pin is changed it can be wrong. most the time this is not an issue. the speed increase allows more code to be completed, and i/o speed to be improved where practical.

I have included a modified version of digitalwritefast.h that can be included in your ide program directory, and all that is needed to add to your code to run it is a include such as

#include "digitalWriteFast.h"

and add the following to your ide program folder download digitalWriteFast.h



to change a pin normally we would do this
if (statechange) digitalWrite(pinumber,lowOrHigh);

doing digitalwritefast do it this way

if (statechange) {digitalWriteFast(pinumber,lowOrHigh);} // added brackets

digitalReadFast is the same but it reads faster rather than the normal read.

Edited 1 time(s). Last edit at 07/12/2011 06:49PM by jamesdanielv.
Quote
jamesdanielv
if (statechange) {digitalWriteFast(pinumber,lowOrHigh);} // added brackets

Here is a classic preprocessor trick you may want to try:
#define some_macro(parameters) do { statement; statement; ... } while (0)
Notice that the do/while statement is incomplete because there is NO semicolon at the end. Then, when you use the macro like this:
some_macro(parameters);
it becomes a single complete statement, instead of the semicolon becoming an extra empty statement. With this trick, you can write
if (condition) some_macro(actual_parameter);
else something_else();
and it works as intended.
Re: digitalwritefast, digitalwrite, and direct port manipluation
September 08, 2012 12:40AM
This is an old post.

I don't think that after compilation there is any speed increase from the method mentioned in the last post.

digitalWriteFast is a preprocessor anyway.

Needless to say, the community pretty much agreed to use fastio.h

Here is it implemented in sprinter firmware.
[github.com]

It has toggle, which only takes 2 clock cycles. Rest of I/O takes 3 clock cycles.
It's not about speed, it's about being able to use the macro like it it were a function, without needing extra braces. C.f. Swallowing the Semicolon in the cpp doc.

And thanks for the link to fastio.h!
Sorry, only registered users may post in this forum.

Click here to login