Let's Make Robots!

arduino Shift in, can anyone explain to me this function please ?

hello guys,

i am trying to make a shiftIn with a shift register, in which i connected 3 push buttons to the shift register and 3 Leds to the arduino

so i am trying to make this work but first can anyone please explain to me what does this function mean ?

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 (myDataIn, BIN);

    digitalWrite(myClockPin, 1);

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

AttachmentSize
circuit.jpg1.31 MB

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.

If your real-life setup matches the picture you show, then you tact switches are in sideways. 

no the thing is i always get confused when i use the pushbuttons of fritzing but in real life everything is good because every push button has just 2 pins not 4

No need to get confused. Left mouse click on the pin shows you the connections...

ah ok thanks i didn't know about that, well i consider it as 2 pins button not 4

The inputs of your shift register that do not have switches connected should be connected to ground.  You should NEVER leave inputs unconnected the way you have them.  If they are not connected to something they will read garbage, they will cause the chip to use more current, and they could damage the chip.

i did it and some shortcut happened and arduino off so i removed it for now

after i correct the codes you gave me which i was confused about, the LEDs now go on on their own when i upload the program and keeps on whitout any affection by the push buttons

by the way the codes i am using are from arduino shiftin example but i keep on making changes to those codes (the worst ever example of arduino examples !!)

here are my codes now  (please ignore the comments it's from arduino example and i kept it):

int latchPin = 4;
int dataPin = 6;
int clockPin = 2;

int ledRed = 10;
int ledYellow = 9;
int ledGreen = 8;

byte switchVar1 = B00000000;  //01001000

boolean button1 = LOW;
boolean button2 = LOW;
boolean button3 = LOW;

void setup() {
  //start serial
  Serial.begin(9600);

  //define pin modes
  pinMode(latchPin, OUTPUT);
  pinMode(clockPin, OUTPUT);
  pinMode(dataPin, INPUT);
 
  pinMode(ledRed, OUTPUT);
  pinMode(ledYellow, OUTPUT);
  pinMode(ledGreen, OUTPUT);

}

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(20);
  //set it to 0 to transmit data serially 
  digitalWrite(latchPin,0);

  //while the shift register is in serial mode
  //collect each shift register into a byte
  //the register attached to the chip comes in first
  switchVar1 = shiftIn(dataPin, clockPin);

  //Print out the results.
  //leading 0's at the top of the byte
  //(7, 6, 5, etc) will be dropped before
  //the first pin that has a high input
  //reading 
  Serial.println(switchVar1, BIN);


  //This for-loop steps through the byte
  //bit by bit which holds the shift register data
  //and if it was high (1) then it prints
  //the corresponding location in the array
  for (int n=0; n<=7; n++)
  {
    //so, when n is 3, it compares the bits
    //in switchVar1 and the binary number 00001000
    //which will only return true if there is a
    //1 in that bit (ie that pin) from the shift
    //register.
    if (switchVar1 & (1 << n) ){
      //print the value of the array location
      Serial.println("done");
    }
  }

//This following is a away to examine the whole
//byte at once and create combinations
//of settings.

//By passing the switchVar1 variable to
//a "switch" statement and comparing it against
//a set nemerical value (written in binary)
//you can create special cases

  if( switchVar1 & B00000100 )
 
  {
 
     digitalWrite(ledGreen, HIGH);
 
  }
 
  if( switchVar1 & B00000010 )
 
  {
 
     digitalWrite(ledYellow, HIGH);
 
  }
 
  if( switchVar1 & B00000001)
 
  {
 
     digitalWrite(ledRed, HIGH);
 
  }


//white space
Serial.println("-------------------");
//delay so all these print satements can keep up.
//delay(500);

}

byte shiftIn(int myDataPin, int myClockPin) {

//internal function setup
  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;
}


Your code has

switch( switchVar1){

case B10000000: ...

...

}

That will light an LED ONLY if bit 7 or bit 6 or bit 5 is high.  Your switches are connected to bits 2,1, and 0.  What you should have is 

if( switchVar1 & B00000100 )

{

   // light LED 2

}

if( switchVar & B00000010 )

{

   // light LED 1

}

if( switchVar & B00000001)

{

   // light LED 0

}

 

You may not need to debounce the buttons, depending on what you are doing.  If you need or want to debounce them it can easily be done in software.  That is how it is normally done.  There are lots of ways to do it.  One simple way is to take several readings and AND them together.  An AND operation is only a ONE if all the inputs are ONEs.  So if you read five times and AND them all together it will only give a ONE for each switch that was a ONE for all five reads.  Something like this:

byte my_buttons = 0xff;  // start with all ones

byte counter = 0;  // a BYTE is slightly more efficient than an int;

for(counter =0; counter < 5; ++counter)

{

   my_buttons = my_buttons & shiftin( data_pin, clock_pin);

}

// now check your buttons

// Any button that wasn't pressed all five reads will have a ZERO

// A button that was pressed all five reads will have a ONE

if the buttons make a ZERO when pressed, you can change it to start with all ZEROS

byte my_buttons = 0;

// and change the shiftin line to this

my_buttons = my_buttons | shiftin( data_pin, clock_pin);

// Then any button pressed all five times will be ZERO the others will be ONEs

 

i am really messed up and so confused

it's been 2 days trying to figure this out and nothing is working properly, what's happening is that the leds are all over, it's getting on by itself and off, check the circuit please in the attachement files up at the beginning of the thread, and if there is any wiring mistake in the buttons please ignore it because the real circuit is wired in the right way

so what i need to do is make every button light a LED or turn it off

i would appreciate your help if you make this code easy for me

here is the codes i got so far :

int latchPin = 4;
int dataPin = 6;
int clockPin = 2;

int ledRed = 10;
int ledYellow = 9;
int ledGreen = 8;

byte switchVar1 = B00000000;  //01001000

void setup() {
  //start serial
  Serial.begin(9600);

  //define pin modes
  pinMode(latchPin, OUTPUT);
  pinMode(clockPin, OUTPUT);
  pinMode(dataPin, INPUT);
 
  pinMode(ledRed, OUTPUT);
  pinMode(ledYellow, OUTPUT);
  pinMode(ledGreen, OUTPUT);

}

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(20);
  //set it to 0 to transmit data serially 
  digitalWrite(latchPin,0);

  //while the shift register is in serial mode
  //collect each shift register into a byte
  //the register attached to the chip comes in first
  switchVar1 = shiftIn(dataPin, clockPin);

  //Print out the results.
  //leading 0's at the top of the byte
  //(7, 6, 5, etc) will be dropped before
  //the first pin that has a high input
  //reading 
  Serial.println(switchVar1, BIN);


  //This for-loop steps through the byte
  //bit by bit which holds the shift register data
  //and if it was high (1) then it prints
  //the corresponding location in the array
  for (int n=0; n<=7; n++)
  {
    //so, when n is 3, it compares the bits
    //in switchVar1 and the binary number 00001000
    //which will only return true if there is a
    //1 in that bit (ie that pin) from the shift
    //register.
    if (switchVar1 & (1 << n) ){
      //print the value of the array location
      Serial.println("done");
    }
  }

//This following is a away to examine the whole
//byte at once and create combinations
//of settings.

//By passing the switchVar1 variable to
//a "switch" statement and comparing it against
//a set nemerical value (written in binary)
//you can create special cases

  switch (switchVar1) {
  case B10000000:
    digitalWrite(ledRed, HIGH);
    break;
  case B01000000:
    digitalWrite(ledYellow, HIGH);
    break;
  case B00100000:
    digitalWrite(ledGreen, HIGH);
    break;   
  default:
    // if nothing else matches, do the default
    Serial.println("Play It, Joe");
  }
 
 /* dBit = getBit(switchVar1, dBitNum);

  if (dBit) {
    Serial.println("D");
  }

//just validating a function (no new variable required)
 if (getBit(switchVar1, aBitNum)) {
    Serial.println("A");
  }*/

//white space
Serial.println("-------------------");
//delay so all these print satements can keep up.
//delay(500);

}

byte shiftIn(int myDataPin, int myClockPin) {

//internal function setup
  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;
}



The bar | is a bitwise or and the << is bitshift left. If I'm reading it right it's like saying "binary add myDataIn to a left shifted version of myDataIn."

Debounce is up to you to handle. I don't know how well software debounce would work.