ShiftIn function

Trying to understand this, I have it working normally but not when I put it in a function:

byte shiftIn(int indataPin, int inclockPin, int inloadPin) {

  int i = 0;
  boolean state = false;
  byte outByte = B00000000;

  //capture bit states
  digitalWrite(inloadPin, 0);
  digitalWrite(inloadPin, 1);

  for(int i=0; i<=7; i++){
    digitalWrite(inclockPin, 0);
    state = digitalRead(indataPin);
    outByte |= (state << i); 
    digitalWrite(inclockPin, 1);
  }

  return outByte;
}


void setup() {
  Serial.begin(9600);
}

void loop() {
  Serial.println(shiftIn(9, 10, 12), BIN);
  delay(1000);  
}

Any ideas anyone?

J

I'm a little confused. Your code IS in a function. Is the code you show working or not working? What does it do when it works and what does it do when it doesn't?

Pins default to inputs. You haven't set the clock or load pins as outputs.

Of cousre! HOW embarrassing...

A shift in (shiftIn) function:

byte shiftIn(int indataPin, int inclockPin, int inloadPin) {

  int i = 0;
  byte outByte = 0;

  //capture bit states
  digitalWrite(inloadPin, 0);
  digitalWrite(inloadPin, 1);

  //collect bits
  for(int i=0; i<=7; i++){
    digitalWrite(inclockPin, 0);
    outByte |= (digitalRead(indataPin) << i); 
    digitalWrite(inclockPin, 1);
  }

  return outByte;
}

void setup() {
  pinMode(10, OUTPUT);
    pinMode(12, OUTPUT);
  
  Serial.begin(9600);
}

void loop() {
  Serial.println(shiftIn(9, 10, 12), BIN);
  delay(1000);  
}

If you wanted to nail it, there's no reason not to put the "pinMode"s inside "shiftIn"

byte shiftIn(int indataPin, int inclockPin, int inloadPin) {

  int i = 0;
  byte outByte = 0;

  pinMode (inLoadPin, OUTPUT);
  pinMode (inclockPin, OUTPUT);
  pinMode (indataPin, INPUT);
  //capture bit states
  digitalWrite(inloadPin, 0);
  digitalWrite(inloadPin, 1);

  //collect bits
  for(int i=0; i<=7; i++){
    digitalWrite(inclockPin, 0);
    outByte |= (digitalRead(indataPin) << i);
    digitalWrite(inclockPin, 1);
  }

  return outByte;
}

Of course, if you still wire it up wrong... :-?

This is probably a good idea! Though if you were to call this function a lot - would those pinMode give much/any overhead?

Can anyone give me any ideas on how to find out a single bit in a byte? My next function needs to query the byte that is returned for a specific bit. Like queryBit(a byte, a specific bit in the byte like 4th) - so... queryBit(B00000001, 8) returns true.

James

static inline uint8_t isBitSet(uint8_t byte, uint8_t bitnum) {
  return (byte & (1<<bitnum)) ? 1 : 0;
}

Bit numbers are usually numbered from 0 on the right (the LSB) to higher numbers on the left. So your example would better be written as "isBitSet(B10000000, 7) is true".

Wow - amazing - thanks.

Also found this:

Useful! Thanks...

That's a neat bitwise tutorial.

Can anyone give me any ideas on how to find out a single bit in a byte?

http://arduino.cc/en/Reference/BitRead

Why did he delete his post??? :o

Can anyone give me any ideas on how to find out a single bit in a byte?

If you want to determine if no more than one bit is set in a word:

#define pow2(x) (!((x)&((x)-1))&&(x))

Will return 1 if only one bit is set in "x" (i.e. if "x" is an integer power of two), zero otherwise.

I want to check if a bit is true - each bit represents a button input... so I want to say "if button 5 is pressed"

The post before looked good - but is now deleted - why didn't I copy and paste!

Bit twiddling:

http://www.scribd.com/doc/2348626/Bit-Twiddling-Hacks

Sorry AWOL - I can't find the right section :frowning:

It'll be in the section on determining log base 2 of a number.

For a byte, it would be something like: (uncompiled, untested)

unsigned byte log2 (unsigned byte x) {
  unsigned byte result = (x & 0xAA) != 0;
  result |= ((x & 0xf0) != 0) << 2;
  result |= ((x & 0xcc) != 0) << 1;
  return result;
}

BUT! this will incorrectly return zero for a value of "x" of zero, so check first!
And it is correct only if there is a single bit set.

You just need to create a bitmask to pick out the bit you want.

E.g. if you want to examine bit 5 in Byte A, you create a bitmask B.

B = (1<<5)
if (A & B) { ... }

Cheers Mike... :slight_smile:

That should work ok.

I just need to integrate the current byte with some sort of debounce code now.

James

There's debounce examples in the Playground.

i'm confused. People are talking about a deleted post, but of course if it's deleted, I can't see what it was.

Since Mike Mc was the first to mention it, and his post was the first one after mine, I'll assume it was mine that disappeared.

Also, I noticed today that mine was still editable, which is very unusual this long after the post. This adds to my suspicion that mine was somehow the missing one. It is possible that I used the Forward and Back buttons on my browser and that somehow created a "pending" situation in YaBB.

My original reply was a link to the Arduino reference page for reading a bit at http://arduino.cc/en/Reference/BitRead.

Apologies if this ends up being a double post if my analysis of this situation is wrong. Just trying to help out.