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 ShiftIn


Here you can find out how Arduino shiftIn works and how fast it is. The main use for the  function to receive serial input from a parallel to serial chip e.g. 74HC165 (8 bits). This allows you to increase the number of inputs to the processor using only two processor pins (you can daisy chain chips for even more inputs).

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

Arduino uno shiftIn() 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) get data from the device, one bit at a time.

Differences between SPI and Arduino shiftIn

  • 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.
  • shiftIn is slow.
  • shiftIn can only receive data.
  • shiftIn can work from any digital pins.
  • shiftIn can be applied to multiple pins.
TIP: You can have multiple instances of shiftIn used on different pins.

How ShiftIn Works

Arduino ShiftIn() uses two signal pins (a digital output pin, and a digital input pin - i.e. almost any of the arduino pins) and generates a clock signal on the output, and receives data on the input, using the digitalRead() function.

Source code for shiftIn

The source code for Arduino shiftIn 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.

uint8_t shiftIn(uint8_t dataPin, uint8_t clockPin, uint8_t bitOrder) {
	uint8_t value = 0;
	uint8_t i;

	for (i = 0; i < 8; ++i) {
		digitalWrite(clockPin, HIGH);
		if (bitOrder == LSBFIRST)
			value |= digitalRead(dataPin) << i;
		else
			value |= digitalRead(dataPin) << (7 - i);
		digitalWrite(clockPin, LOW);
	}
	return value;
}

Parameters to shiftIn()

There are three parameters :

  1. The data pin (Arduino pin number).
  2. The clock pin (Arduino pin number).
  3. Bit order (either LSBFIRST (0) or MSBFIRST (1) ).

The function returns the 8 bits of data from the device as a byte (uint8_t).

Note: ShiftIn() assumes data is not ready until a rising edge is supplied.

The basic operation is to loop through each bit using the for-loop.

In the loop the first action is to raise the clock signal output to high.

Then input value from digitalRead() is shifted left by the current loop value (i) and ORed into the variable 'value'. After this, the clock signal is set low.

In this way the data line is read each time after the clock is set high. Each input bit is placed into the 'value' variable, in its bit shifted position, until 8 bits are retrieved. Then the function returns the variable 'value'.

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).

    00000001B

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

    00000010B

This repeats 6 more times
   
    00000100B
    00001000B
    00010000B
    00100000B
    01000000B
    10000000B 

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: For MSBFIRST, code is slower as a 8 x minus operations occur.

Extracting the bit value

Since the variable 'value' is initialised to zero at the start of the routine, each incoming data bit is ORed into place in the variable.

This is different to shiftOut(), where AND was used. This is because ORing adds the bits into the same variable (leaving the others unaltered), whereas ANDing isolates each bit from the rest (for output).

How fast is Arduino shiftIn()?

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

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

Example Program for testing Arduino shiftIn()

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 shiftIn
int MARK = 7;
int SERCLK = 6;
int SERDATA = 5;

void setup() {

   pinMode(MARK, OUTPUT);
   pinMode(SERDATA, INPUT);
   pinMode(SERCLK, OUTPUT);
   noInterrupts();
}

void loop() {
byte d;

   digitalWrite(MARK, HIGH);
   d = shiftIn(SERDATA, SERCLK, MSBFIRST);
   digitalWrite(MARK, LOW);

   digitalWrite(SERDATA, LOW);   //  Stop scope output flicker.
   delay(10);
}

The oscilloscope output marker signal 120us (longest signal). The period of the clock signal is: 14.37us (~69.6kHz).

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 yellow line shows the clock signal on pin 6
    The next is the marker signal (blue) on pin 7.

Arduino uno shiftIn() speed - timing diagram

The timebase is 10us and the amplitude is 2V/div.


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:
To Visit Click Here


Recent Articles

  1. Digispark Attiny85 Easy IDE install and setup

    Digispark ATtiny85: Essential information on setting up and using this tiny, but powerful, chip

    Read more

  2. Magnetometer tilt compensation

    How to make magnetometer tilt compensation work for a magnetometer such as a QMC5883L using an ADXl345 accelerometer.

    Read more

  3. 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

  4. Arduino absolute value - abs() - secrets revealed...

    Secrets of Arduino absolute value abs() - Why it might fail, Why it may cause problems...and how to fix it.

    Read more

  5. Arduino Analog Output...Easy analog output generation

    Arduino Analog Output: How to create the most accurate PWM analog ouput and how to create analog PWM sine waves.

    Read more

  6. ACS758 secrets...

    Using the ACS758 to measure very high current

    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

SUPERB and FANTASTIC."

- Ranish Pottath

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

- Milan

bursach<at>gmail.com<

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


- Matt
matt_tr<at>
wolf359.cjb.net


Learn Microcontrollers

"Interested in
Microcontrollers?"

Sign up for The
Free 7 day guide:

FREE GUIDE : CLICK HERE


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


- Dave

de_scott<at>bellsouth.net

"Your site is a great
and perfect work.
congratulations."


- Suresh

integratredinfosys<at>
yahoo.com

"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.
Regards."


- Anon

Back to Top