Become a subscriber (Free)

Join 29,000 other subscribers to receive subscriber sale discounts and other free resources.
Don't worry -- youre-mail address is totally secure. I promise to use it only to send you MicroZine.

Arduino ShiftOut

Here you can find out how Arduino shiftOut works and how fast it is. You can use the function to control many different types of chips. For example control a serial device e.g. BMP280 or create more outputs e.g. 74HC595.

Arduino shiftOut is a purely software implementation of a serial output interface; The equivalent hardware interface is SPI (Although shiftOut() represents half of that interface i.e. the data output part).

Arduino uno shiftOut() speed - timing diagram

Many chips use a serial interface to reduce the number of physical pins, so instead of using a parallel processor bus to transfer data 8 or 16 bits at a time, two signals (clock and data) send data into the device, one bit at a time.

In the case of a 16bit device, "think of a 16 bit ADC", you save 14 pins. This can often mean a device will fit into a tiny surface mount package, so that you can fit more functions into the same area on a PCB.

Differences between SPI and Arduino shiftOut

  • SPI is fast.
  • SPI operates only from specific pins.
  • SPI accommodates different clock types e.g. normally high etc.
  • SPI transmits and receives data at the same time.
  • shiftOut is slow.
  • shiftOut can only transmit data.
  • shiftOut can work from any digital pins.
  • shiftOut can be applied to multiple pins.

Since the shiftOut function is not limited to specific pins you can have different devices attached to different pins.

TIP: You can have multiple instances of shiftOut on different pins.

How ShiftOut Works

Arduino ShiftOut uses two signal pins (any digital output pins - i.e. most of them!) and generates a clock signal and and a data signal using the digitalWrite() function.

Source code for shiftOut

The source code for Arduino shiftOut is contained in wiring_shift.c. The path is:

C:\Program Files\Arduino\hardware\arduino\avr\cores\arduino\wiring_shift.c

Note constants such as LSBFIRST are defined in Arduino.h, in the same directory.

void shiftOut(uint8_t dataPin, uint8_t clockPin, uint8_t bitOrder, uint8_t val)
	uint8_t i;

	for (i = 0; i < 8; i++)  {
		if (bitOrder == LSBFIRST)
			digitalWrite(dataPin, !!(val & (1 << i)));
			digitalWrite(dataPin, !!(val & (1 << (7 - i))));

		digitalWrite(clockPin, HIGH);
		digitalWrite(clockPin, LOW);

Parameters to shiftOut()

There are four parameters :

  1. The data pin (Arduino pin number).
  2. The clock pin (Arduino pin number).
  3. Bit order (either LSBFIRST (0) or MSBFIRST (1) ).
  4. The value : Of a type having 8 bits.

The basic operation is to loop through each bit using the for-loop. Then figure out a value for the current bit, and if set, then output high, or if reset, then output low. Then pulse the clock signal high, then low.

In this way the data line is set to the value of each bit in turn and the clock is pulsed. The receiving chip accepts the data line output (from the shiftOut dataPin) as an input. The data is transferred into this chip on the transition of the clock from low to high. You can use this type of process to drive the 74HC595 Serial-in-parallel-out chip.

How does the shifOut() code work?

The code works by using the bit shift operator '<<' which shifts all the bits in a variable one to the left.

Assume the bitOrder is LSBFIRST then for the first loop iteration i is zero and the term (1<<i) shifts a variable left by zero places i.e. it leaves the variable with the value 1.

Note: In C temporary variables are used to hold intermediate values.

Generating a walking 'one'

This is bit zero (b0).


The next time around the loop the variable holds the value 1 shifted left by one place:


This repeats 6 more times

In this way a walking '1' is created moving from b0 to b7.

For a bitOrder of MSBFIRST, the value of the index is manipulated to move from b7 to b0 for each value of i. So the walking '1' walks in the opposite direction, starting from bit 7.

Note: MSBFIRST, code is slightly slower as a 8 x minus operations occur.

Extracting the bit value

To figure out the bit value of val, this walking one value is 'ANDed' with val. This results in a different value for each bit. For example if bit 6 were set in val, then the value output would be pow(2,6) = 64. If it was not set then the value would be zero.

Purifying the bit value

The two exclamation marks look like a different maths operator but they are in fact just two inversion actions. The exclamation mark is a logical inversion operator, not a bit inversion operator.

The first invert action changes the result of the 'AND' operation into a true or false value. i.e  if result>0 then output false, and if result =0 output true.

At this point the logic is inverted so the second inversion operator '!' flips it back.

Signal Output

This value is then used by the digitalWrite() function to output the data value to the selected dataPin.

How fast is Arduino shiftOut()?

The function uses digitalWrite() so it should be of the order of the speed of digitalWrite() - in that link the pulse period (for an Arduino Uno) is 7us.

Since 8 pulses are needed, shiftOut() should take about 56us plus a bit more for bit manipulation and looping round the for-loop.  In fact the extra operations in shiftOut() double this time (see below for timings).

Example Program for testing Arduino shiftOut()

The following sketch outputs a marker signal on pin 7 (so you can trigger a scope on the start of the serial data) and alternates data with a pattern 0x55 and 0x99 - an alternating data pattern.

// Demonstration code for shiftOut
int MARK = 7;
int SERCLK = 6;
int SERDATA = 5;

void setup() {

   pinMode(MARK, OUTPUT);
   pinMode(SERDATA, OUTPUT);
   pinMode(SERCLK, OUTPUT);

void loop() {
static byte d = 0x55;

   digitalWrite(MARK, HIGH);
   digitalWrite(MARK, LOW);

   digitalWrite(SERDATA, LOW);   //  Stop scope output flicker.
   d = ~d;

The oscilloscope output that the time is actually 121us (lowest signal - marker). The period of the clock signal is: 15.2us (~66kHz).

When using LSB the width of the marker signal increases to 122us.

However you would normally use the marker signal as the chip select, so it is representative of the achievable timing (CS would normally be inverted so that it is active low).

    The top line shows the clock signal on pin 6
    The next is data output of x55 (MSB first) on pin 5.
    The next is data output of 0x99 (MSB first) on pin 5 (overlay of stored image).
    The next is the marker (trigger signal) on pin 7.

Arduino uno shiftOut() speed - timing diagram

Image showing cursors for clock timing.

shiftOut clock timing oscilloscope diagram

New! Comments

Have your say about what you just read! Leave me a comment in the box below.

Privacy Policy | Contact | About Me

Site Map | Terms of Use

Visit our Facebook Page:

   Click Here

  1. How to use the ADXL345 for movement sensing and more.

    With the ADXL345 acellerometer you can detect up to 16g! You can also find out how to use it for tap detection and more.

    Read more

  2. How the HMC5883L 3-axis digital magentomter works

    HMC5883L - How make a digital compass, Find out the differences between the HMC5883L and the QMC5883L and whether they are compatible.

    Read more

  3. ESP8266 Arduino IDE setup.

    Easily use an ESP8266 with the Arduino IDE and program your first sketch into the ESP8266

    Read more

  4. How to use the MCP4725, a versatile and tiny (SOT-23-6) analogue output device

    The MCP4725 chip is a 12 bit DAC with memory that outputs voltage that you can use for many dfferent purposes. Find out what they are in this page.

    Read more

  5. PCF8591: An 8 bit ADC you can easily connect using I2C

    PCF8591: A four input ADC with single DAC. How good is this 8 bit ADC, and should you use it in your next project?

    Read more

  6. How to use an arduno Nano as an ISP (In System Programmer)

    Arduino Nano ISP: How to program an ATmega328P using an Arduino Nano as the ISP programmmer. One common problem: Programming a sketch into the chip without a reset control - solved here.

    Read more

Readers Comments

"I wanted to thank
you so so so much
for all the information
you have provided in
your site it's


- Ranish Pottath

"This site really is
the best and my favorite.
I find here many useful
projects and tips."

- Milan


"Awesome site,
very, very easy and nice
to navigate!"

- Matt

Learn Microcontrollers

"Interested in

Sign up for The
Free 7 day guide:


"I am a newbie to PIC
and I wanted to say
 how great your
site has been for me."

- Dave


"Your site is a great
and perfect work.

- Suresh


"I couldn't find the correct
words to define
yourweb site.

Very useful, uncovered,
honest and clear.

Thanks so much for
your time and works.

- Anon

Back to Top