The arduion http://www.arduino.cc/en/Reference/ShiftOut command is great. But it is only 8 bits, and has no control over speed. Some hardware can not cope with even a slow 8 bit AVR speed.

Thus my code below. It not only accepts any number of bits (well currently 1 to 16), and has an optional delay, and it is backwards compatible with the old version:

It takes advantage of the fact that C++ allows optional parameters, but only at the end. Thus you can have default values too.

// License GNU Lesser General Public License 2.1 original material copyright David A. Mellis, changes copyright Scott Penrose
// New shiftOut, but backwards compatible, accepts
//	shiftOut( dataPin, clockPin, bitOrder, val);
//	shiftOut( dataPin, clockPin, bitOrder, val, bits);
//	shiftOut (dataPin, clockPin, bitOrder, val, bits, delayMicroSeconds);
void shiftOut(uint8_t dataPin, uint8_t clockPin, uint8_t bitOrder, int val, uint8_t bits = 8, uint8_t del = 0)
{
  uint8_t i;
  for (i = 0; i < bits; i++)  {
    if (bitOrder == LSBFIRST)
      digitalWrite(dataPin, !!(val & (1 << i)));
    else    
      digitalWrite(dataPin, !!(val & (1 << ((bits - 1 - i)))));
    digitalWrite(clockPin, HIGH);
    delayMicroseconds(del);
    digitalWrite(clockPin, LOW);            
  }
}

Tested on 12 bit DAC - (ref)

Issues

  • Which is it read on LOW or HIGH - may need to do LOW, HIGH on clock
  • Value may need to be inverted