In my code I need to set five pins to output mode. I have the pinMode() statements in my setup.
I am trying to make my Arduino code run a bit faster, and I came across a tutorial which swaps digitalWrite() for PORTB &= _BV(PB6) (high), and makes it run ~25 times faster.
I'm wondering if there's a similar type of substitution I can do for pinMode(), that will make it run faster as well? Or is pinMode() already a fast command, so I shouldn't worry about it?
Thanks
-
3Things inside the setup are only done once, so optimizing those is rarely worth the trouble, replacing digital writes and reads (which are done often) will have more effect overall.ratchet freak– ratchet freak2017年08月29日 22:22:33 +00:00Commented Aug 29, 2017 at 22:22
3 Answers 3
It isn't worth it for something done once, if you only do it in setup
. However if you need to toggle the mode frequently yes it can be done. You sadly haven't said which pins, but assuming they are D2 to D6 (digital pins 2 to 6) on a Mega you can do this to set output mode:
DDRE |= bit(PE3) | bit(PE4) | bit(PE5); // D5, D2, D3
DDRG |= bit(PG5); // D4
DDRH |= bit(PH3); // D6
For input mode you have to "and" in the ones-complement of the bits like this:
DDRE &= ~(bit(PE3) | bit(PE4) | bit(PE5)); // D5, D2, D3
DDRG &= ~(bit(PG5)); // D4
DDRH &= ~(bit(PH3)); // D6
The exact register names are in the datasheet, and the mappings to the pins on your board are in the schematic (available from the Arduino site). The relevant part is this:
The bit numbers are in grey on the left (eg. PE4) and the board pin numbers are in green on the right (eg. 2 is digital pin 2).
The bit
macro works similarly to the _BV
one you mentioned in your question. It shifts 1
left the required number of bit positions to be in the right place.
A somewhat simpler and more portable solution is to use the digitalWriteFast library which you can download from:
https://github.com/NicksonYap/digitalWriteFast
This uses various compiler tricks to detect if you are using a constant for pinMode
and digitalWrite
and converts them into the appropriate register manipulation. You just install the library and add Fast
to the function names, eg.
pinModeFast (2, OUTPUT);
digitalWriteFast (2, HIGH);
The Arduino reference manual has all you need to know:
The register you need is the DDRx
register (Data DiRection X). Set a bit to 1 for output and 0 for input.
yeah. the corresponding registers are DDRx.
with a little bit of coding, you can easily convert pinMode() to your own, say, mypinMode() that operates on the DDRx directly.
the datasheet is your best friend, as always.