Go Down

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

bserem

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
Quote

//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
  Serial.begin(9600);

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

}

void loop() {

  //Pulse the latch pin:
  //set it to 1 to collect parallel data
  digitalWrite(latchPin,1);
  //set it to 1 to collect parallel data, wait
  delayMicroseconds(100);
  //set it to 0 to transmit data serially 
  digitalWrite(latchPin,0);

  incoming = shiftIn(dataPin, clockPin, MSBFIRST);

  Serial.println(incoming, BIN);

  delay(500);

}



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:
Quote

////// ----------------------------------------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);
    delayMicroseconds(0.2);
    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(pinState);
    //Serial.print("     ");
    //Serial.println (dataIn, BIN);

    digitalWrite(myClockPin, 1);

  }
  //debuging print statements whitespace
  //Serial.println();
  //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!

bserem

The solution is here:
http://code.google.com/p/arduino/issues/detail?can=2&start=0&num=100&q=&colspec=ID%20Type%20Status%20Priority%20Milestone%20Owner%20Summary&groupby=&sort=&id=467

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

Go Up