Go Down

Topic: ShiftIn from Reference doesn't work. ShiftIn from Tutorial works! (Read 1 time) previous topic - next topic


I have ordered a bunch of shift registers (CD4021B) in order to play with them on the arduino while trying to find ways to read more inputs with fewer pins.

I wired everything up, correctly (I quadriple checked) and fired the code using http://arduino.cc/en/Reference/ShiftIn

//define where your pins are
int latchPin = 8;
int dataPin = 9;
int clockPin = 7;

//Define variables to hold the data for shift register.
//starting with a non-zero numbers can help troubleshoot
byte incoming = 254;

void setup() {
  //start serial

  pinMode(latchPin, OUTPUT);
  pinMode(clockPin, OUTPUT);
  pinMode(dataPin, INPUT);


void loop() {

  //Pulse the latch pin:
  //set it to 1 to collect parallel data
  //set it to 1 to collect parallel data, wait
  //set it to 0 to transmit data serially 

  incoming = shiftIn(dataPin, clockPin, MSBFIRST);

  Serial.println(incoming, BIN);



It seemed to work, but it behaved wrong. I had another arduino acting as input (lowering and highering some pins on the shift register) and my data didn't match.
After a few hours of pondering I tried the code given in the tutorials section (http://www.arduino.cc/en/Tutorial/ShiftIn).

In the tutorial, the author declares his own shiftIn() function:

////// ----------------------------------------shiftIn function
///// just needs the location of the data pin and the clock pin
///// it returns a byte with each bit in the byte corresponding
///// to a pin on the shift register. leftBit 7 = Pin 7 / Bit 0= Pin 0

byte shiftIn(int myDataPin, int myClockPin) {
  int i;
  int temp = 0;
  int pinState;
  byte myDataIn = 0;

  pinMode(myClockPin, OUTPUT);
  pinMode(myDataPin, INPUT);
//we will be holding the clock pin high 8 times (0,..,7) at the
//end of each time through the for loop

//at the begining of each loop when we set the clock low, it will
//be doing the necessary low to high drop to cause the shift
//register's DataPin to change state based on the value
//of the next bit in its serial information flow.
//The register transmits the information about the pins from pin 7 to pin 0
//so that is why our function counts down
  for (i=7; i>=0; i--)
    digitalWrite(myClockPin, 0);
    temp = digitalRead(myDataPin);
    if (temp) {
      pinState = 1;
      //set the bit to 0 no matter what
      myDataIn = myDataIn | (1 << i);
    else {
      //turn it off -- only necessary for debuging
     //print statement since myDataIn starts as 0
      pinState = 0;

    //Debuging print statements
    //Serial.print("     ");
    //Serial.println (dataIn, BIN);

    digitalWrite(myClockPin, 1);

  //debuging print statements whitespace
  //Serial.println(myDataIn, BIN);
  return myDataIn;

and incorporates his shiftIn in the example he provides (http://arduino.cc/en/Tutorial/ShftIn11).

With the second shiftIn, the one provided in the tutorial, everything works fine.
What are the differences between the two? Is this a bug in the software or is the CD4021B incompatible with arduino's shiftIn?

I would like to sort this out so that we can update the reference page.

Thanks in advance ;)

ps: first post here, being messing with arduino for two-three months now, I love it!


The solution is here:

I believe this patch should be applied in the next release!

Go Up

Please enter a valid email to subscribe

Confirm your email address

We need to confirm your email address.
To complete the subscription, please click the link in the email we just sent you.

Thank you for subscribing!

via Egeo 16
Torino, 10131