Subscribe to Make Magazine Today!

Good Instructable for the advanced folks out there, your code won’t be portable, but you’re advanced, so whatever :) RazorConcepts writes-

Arduino is slow? What? This instructable will show just how slow a part of Arduino is, and how to fix it. It’s true – more specifically, Arduino’s digitalWrite command takes a considerable amount of time. If you are just switching on a LED once or something, you won’t be able to notice it. However, I realized how slow it was while I was trying to use a TLC5947 PWM driver. That requires the microcontroller to shift in 288 bytes each time! Each byte required about 12 digitalWrites, for a total of 3456 digitalWrites each time I wanted to shift in new data to the TLC5947. How long did that take? 30 seconds of just digitalWrite! But there is a solution – using “true c” style commands, or what the AVR GCC (GNU C Compiler) uses. The brains behind Arduinos are ATMega168s or ATMega328s. The AVR community typically uses “true c” commands to program these c

  • Dale Wheat

    The instructable does a great job of explaining the mapping of digital and analog pins in Arduino-speak to the ports and bits of the underlying chip. Good job!

    The “bit value” functions _BV(), etc., have always seemed clumsy to me. Once upon a time, the AVR GCC compiler supported “Set Bit in I/O register” and “Clear Bit in I/O register” macros called sbi(port, bit) and cbi(port, bit). These emulated the AVR machine language instructions SBI and CBI, respectively. The macros were smart enough to tell when the I/O register was beyond the limited SBI and CBI address space and would substitute appropriate read+modify+write instruction sequences, which were not as fast as a single SBI or CBI instruction but still a LOT faster than the digitalWrite() Arduino function.

    Alas, these macros were deprecated a few years ago, mostly for being “non-portable”, which is true. The _BV() functions are portable and, to some, more self-explanatory in their function.

    For me, not so much. I re-wrote my own macros for SBI and CBI like this:

    #define sbi(port, bit) (port) |= (1 << (bit))
    #define cbi(port, bit) (port) &= ~(1 << (bit))

    Now I can set or reset a bit without having to either remember which logical operators to use or do the math in my head every time. I just have to remember where I keep these macro definitions… :D

    The next step is inline assembly programming, but the AVR porters of the GCC tools did not make this easy for us. They tried, bless their hearts, they tried.

blog comments powered by Disqus

Related Supplies at Maker Shed