What exactly is PINB | = 0b00000001;

Wow. That’s a lot to take in. Thanks for the detail and explanation. After more reading, it sounds like digitalWriteFast could be a better option for me at this stage of my understanding of direct port manipulation especially switching boards? I didn’t see a speed but I saw comments of “close to” direct port manipulation without the complexities or “maybe 10x faster” than digitalWrite. I definitely have a better understanding of what is going on thanks to the helpful replies here.

digitalWriteFast has the same limitations I mentioned above since there is only so much you can with the limitations of the AVR instruction set and the current API semantics.
i.e. digitalWriteFast will only offer an increased speed and atomicity if the pin and the value parameters are both constants.

There are some issues with using digitalWriteFast.
The main one being if the value parameter is not a constant, it does not call digitalWrite() which means it does a non atomic register update operation so it can and will corrupt the register if interrupts are being used and the ISR code is also modifying the same register.
So while it can offer faster operations when using a constant pin number and a variable value parameter, it should not be used if there is an ISR that modifies the same register as there will be register corruption.

digitalWriteFast also does not use the Arduino board variant pin mapping tables as it hard codes its own pin mappings. While hard coding pin mappings is definitely faster than looking them up, it can end up doing incorrect pin mappings if you are not using same board type that code assumed.

A better solution is to re-write the digital i/o code so that it is smarter and faster.
This is what Paul Stroffegen did in his Teensy AVR core.
If you use a Teensy AVR board which uses his Teensy AVR core, then you get the much faster code automatically when using the standard digital i/o API functions like digitalWrite() with no need to use the digitalWriteFast hack.
Since he implemented it in the core, you also don't have the risk of incorrect pin mappings and you will never have a case of non atomic register updates.
Paul offered this code to the Arduino.cc developers many years ago, but unfortunately they didn't want to use it and in fact rejected the offer several times.

One thing that I always thought was really dumb in the digitalWriteFast code is that they didn't create macros to remap the digital i/o functions to the faster functions.
This is really really dumb, since, as is, you have to modify your code to use it.
With just a few simply macros, you could include the header and make not other changes to your code.
And to revert simply comment out the include of the header.

--- bill

1 Like

Where did you see that comment, it is very stupid. Direct port manipulation is the fastest way possible of changing bits. So there is no way any code can be 10X faster.

I believe he was referring to the speed of digitalWriteFast vs digitalWrite.
digitalWriteFast was the context of the sentence just prior to what he said about digitalWrite.

--- bill

Maybe, but he did say "faster than direct port manipulation"

Yeah, I was probably editing the sentence when you saw it, I realized I got in a hurry and added another thought that made the sentence incorrect. It is fixed now. Totally understand direct port is the fastest and smallest. But as mentioned in other places it’s much more prone to novice mistakes. The speed references referred to digitalWriteFast vs digitalWrite.

Just wanted to add a clarification on what I said about the atomicity of digitalWriteFast() when using a non constant value.
It depends on where you get the code. I've just looked around a bit and have seen different implementations.

While most do check for the value parameter being constant, some don't.
So be careful and look at the actual digitalWriteFast macro for the one you are using to make sure it checks for the value parameter to be a constant.

--- bill

I see that now.
I only saw the edited/updated version and didn't see the original that you saw.
--- bill

digitalWriteFast uses direct port i/o
That is how it gets its increased performance.
But.... you must remember that it only does direct port i/o when possible due to the AVR instruction set and h/w register limitations.
So if your pin and your value arguments are not constants, you will still be calling digitalWrite() so you will see no increase in speed.

--- bill

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.