Alright, why not. I don't think anyone is going to read this, but here goes...
So apparently the digitalWrite() function in the Arduino library is slow, according to this. As the article states, PORTD |= _BV(2) and PORTD &= ~_BV(2) really are much faster; however, they are also more difficult to understand. So essentially we end up sacrificing code readability for performance. This isn't ideal. Is there a way to improve code readability? One way to do this is with macros:
Now we can write __digital_high(D, 2) instead of PORTD |= _BV(2). Not only does simplify the code, it also expresses intent; without reading any documentation __digital_high(D, 2) clearly sets a digital pin to high, while it isn't clear what PORTD |= _BV(2) does.
This is better, but the code can be further improved. The issue is with the pin mappings: the instruction __digital_high(B, 4) sets digital pin 12 to high. That is, (B,4) is mapped to pin 12. You can view the pin mappings here. Anyways, we can hard-code this information at compile time using traits classes. This, combined with a small helper function, allows us to write digital_write<12>(HIGH) instead of PORTD |= _BV(2).
Note that the preprocessor is used to generate the 13 classes for us. Writing 13 template specializations by hand would really suck.
All of the code can be found here: http://pastebin.com/f5769c4f1
So apparently the digitalWrite() function in the Arduino library is slow, according to this. As the article states, PORTD |= _BV(2) and PORTD &= ~_BV(2) really are much faster; however, they are also more difficult to understand. So essentially we end up sacrificing code readability for performance. This isn't ideal. Is there a way to improve code readability? One way to do this is with macros:
#define __digital_high(L, N) PORT ## L |= _BV(N);
#define __digital_low(L, N) PORT ## L &= ~_BV(N);
Now we can write __digital_high(D, 2) instead of PORTD |= _BV(2). Not only does simplify the code, it also expresses intent; without reading any documentation __digital_high(D, 2) clearly sets a digital pin to high, while it isn't clear what PORTD |= _BV(2) does.
This is better, but the code can be further improved. The issue is with the pin mappings: the instruction __digital_high(B, 4) sets digital pin 12 to high. That is, (B,4) is mapped to pin 12. You can view the pin mappings here. Anyways, we can hard-code this information at compile time using traits classes. This, combined with a small helper function, allows us to write digital_write<12>(HIGH) instead of PORTD |= _BV(2).
Note that the preprocessor is used to generate the 13 classes for us. Writing 13 template specializations by hand would really suck.
#define __digital_high(L, N) PORT ## L |= _BV(N);
#define __digital_low(L, N) PORT ## L &= ~_BV(N);
template <uint8_t Pin> class pin_traits;
#define PIN_TRAITS_GENERATOR(L, N, P) \
template <> class pin_traits<P> \
{ \
public: \
static void digital_write(boolean state) \
{ \
if (state == HIGH) \
__digital_high(L, N) \
else \
__digital_low(L, N) \
} \
};
All of the code can be found here: http://pastebin.com/f5769c4f1
I read your blog and im confused
Although your favourite drink does sound like a sad traffic accident. What is an Irish car bomb?