Pages: [1] 2   Go Down
Author Topic: Two daisy chained 74HC165: Can’t detect several button presses at once  (Read 1273 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Newbie
*
Karma: 0
Posts: 33
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi,

I’m using the attached code to detect button presses. 16 buttons are connected to two daisy chained 74HC165. If I press one button at the time, each button gets detected and everything works fine. Also if I press multiple buttons that are connected to the first 74hc165 (the one that is connected to the arduino) I can detect several button presses at once.

But as soon as I press several buttons that are connected to the second 74HC165, the output is wrong. The output circles through different values & shows me presses of buttons that aren’t pressed.

Has anyone an idea why this happens?

Thanks!

Code:
//define where your pins are
int latchPin = 44;
int dataPin = 45;
int clockPin = 42;

//Define variables to hold the data
//for shift register.
//starting with a non-zero numbers can help
//troubleshoot
byte switchVar1 = 72;  //01001000
byte switchVar2 = 159; //10011111



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

  //define pin modes
  pinMode(latchPin, OUTPUT);
  pinMode(clockPin, OUTPUT);
  pinMode(dataPin, INPUT);
}

void loop() {
  digitalWrite(latchPin,0);
  delayMicroseconds(5);
  digitalWrite(latchPin,1);

  switchVar1 = shiftIn(dataPin, clockPin);
  switchVar2 = shiftIn(dataPin, clockPin);

  Serial.println("--------");
  Serial.println(switchVar1, BIN);  //Buttons attached to first 74HC165
  Serial.println(switchVar2, BIN); //Buttons attached to second 74HC165
  Serial.println("--------");

  for (int n=0; n<=7; n++)
  {
    if (switchVar1 & (0 << n) ){
      //If xy 0 then do something
    }
  }

//delay so all these print statements can keep up.
delay(250);

}

//------------------------------------------------end main loop

////// ----------------------------------------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;
}
« Last Edit: October 03, 2013, 12:15:24 am by flocked » Logged

West Yorkshire, UK
Offline Offline
God Member
*****
Karma: 17
Posts: 706
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Potential fix: try the standard shiftIn () function.

If that doesn't help, post your updated sketch and a schematic please. It can be hand drawn on paper and scanned or photographed.

Paul
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 33
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

i used the standard shift in function.

This is my connection:


if I connect the arduino only to the second 74hc165, I can also detect several button presses… Just if two 74hc165 are daisy chained, I can't detect several button presses on the second 74hc165.
Logged

NSW Australia
Offline Offline
Edison Member
*
Karma: 33
Posts: 2310
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Diagram looks fine (except that pin 10 on the second HC165 should be grounded, not left floating).

Your code shows a "Shiftin" function that reads byte values only so calling it twice would read the same byte data twice, and contains a variable called "pinState" which is set but never used.  I am surprised that it gives any output at all but since the logic is so strange it is difficult to tell what it is doing.
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 33
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I'm using the exact same shiftin function from the arduino example code.

pinState is for debugging. I removed the debugging code, but forgot to remove pinState.

And no, it isn't reading the same content twice. It detects button presses/bit changes of the first and the second HC165, even "simultaneously". But not, if I press more than one button connected to the second 74hc165. Then it outputs wrong and changing bit values for the second 165.
Logged

Valencia, Spain
Offline Offline
Faraday Member
**
Karma: 118
Posts: 4545
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Diagram looks fine (except that pin 10 on the second HC165 should be grounded, not left floating).

Your code shows a "Shiftin" function that reads byte values only so calling it twice would read the same byte data twice

Nope. You have to toggle the latch pin to restart the data stream.
Logged

No, I don't answer questions sent in private messages...

Valencia, Spain
Offline Offline
Faraday Member
**
Karma: 118
Posts: 4545
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

How are the buttons connected to the 74HC165s?

If it works fine when you press single buttons that indicates the software is OK.

If it starts to go 'random' when you press several buttons, that sounds like you're short-circuiting the system or something. Measure the voltage at Vcc, does it droop?


Logged

No, I don't answer questions sent in private messages...

Global Moderator
Boston area, metrowest
Offline Offline
Brattain Member
*****
Karma: 437
Posts: 23660
Author of "Arduino for Teens". Available for Design & Build services. Now with Unlimited Eagle board sizes!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Are there pullups on the shift register inputs so they consistently read high with no button push, and low with a button push?
You should also have 0.1uF caps from Vcc to Gnd on both parts.

I second the suggestion to use standard shiftIn() command.

Altho personally I would use SPI.transfer, avoid all the software nonsense. Got built in hardware, use it!
Code:
digitalWrite (latch, LOW);
digitalWrite (latch, HIGH); // clock the data in - or whatever the HC165 needs to capture the data
byte1 = SPI.transfer(0);  // send out dummy byte while reading in data at the same time
byte2 = SPI.transfer(0);

Logged

Designing & building electrical circuits for over 25 years. Check out the ATMega1284P based Bobuino and other '328P & '1284P creations & offerings at  www.crossroadsfencing.com/BobuinoRev17.
Arduino for Teens available at Amazon.com.

West Yorkshire, UK
Offline Offline
God Member
*****
Karma: 17
Posts: 706
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

i used the standard shift in function.
No, you may have got that code from the Aruino site, but the standard shiftIn() function has 3 parameters and is here:

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

However, I don't really think that is the problem, just that its so quick to try, its worth a go.

if I connect the arduino only to the second 74hc165, I can also detect several button presses… Just if two 74hc165 are daisy chained, I can't detect several button presses on the second 74hc165.

Strange... have you tried swapping over the 2 165s? Like Bob asks, you do have those pull-up or pull-down resistors on the 165's inputs?
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 33
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

How are the buttons connected to the 74HC165s?
If it starts to go 'random' when you press several buttons, that sounds like you're short-circuiting the system or something. Measure the voltage at Vcc, does it droop?
The buttons are connected how the should be connected (like on the schematic) . I'm sure that it isn't a hardware problem, because like I said there isn't any problem in detecting multiple buttons, if I connect the arduino only to the second oder first 74hc165 without daisy chaining.
But as soon as I daisy chain two 74HC165 I can't detect multiple buttons from the second 74HC165 that isn't directly connected to arduino.

@PaulRB: Ok, I changed the code and I'm now using the standard shiftIn functions:
  switchVar1 = shiftIn(dataPin, clockPin,MSBFIRST);
  switchVar2 = shiftIn(dataPin, clockPin, MSBFIRST);

I still get the exact same behavior.

I have 10k resistors between vcc, button and 74HC165 input.

Are there pullups on the shift register inputs so they consistently read high with no button push, and low with a button push?
You should also have 0.1uF caps from Vcc to Gnd on both parts.

Altho personally I would use SPI.transfer, avoid all the software nonsense. Got built in hardware, use it!
I don't want to use SPI. I also get a constant high with no button pushes and a 0 with a press, yes.

Here is an image:


If I press two buttons connected to the first 74HC165 the output is correctly:
11101011 // buttons connected to the first 74HC165, which is connected to the arduino.
11111111 // buttons connected to the second 74HC165, which is daisy chained to the first one.

If I press two buttons connected to the first 74HC165 and one button connected to the second the output is correctly:
11101011
11111011

If I press two buttons connected to the first 74HC165 and two button connected to the second the output is wrong:
11101011
11111011 or 11011011 etc. It cycles trough wrong values…
« Last Edit: October 03, 2013, 11:44:30 am by flocked » Logged

West Yorkshire, UK
Offline Offline
God Member
*****
Karma: 17
Posts: 706
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Did you try swapping the 165s like I suggested. Just lift them out of the breadboard & swap.
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 33
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Did you try swapping the 165s like I suggested. Just lift them out of the breadboard & swap.

Yes i swapped them and even used new ones. Still the same problem… :/
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 33
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Omg I'm so sorry for all the thinking… I found the failure. I forgot to add the ground for the second row of buttons (the ones that are connected to the second 74hc165).… … … … …
Thank you all! smiley
« Last Edit: October 03, 2013, 02:55:46 pm by flocked » Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 33
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Okay, there is now only one problem: One button changes the bit in the first byte even if it is connected to the second 74hc165 ( =second byte) and the button that should change the bit in the first byte isn't changing the bit at all.
this seems to be a shiftIn() problem… Why?
I tried this code and it hasn't this problem: http://playground.arduino.cc/Code/ShiftRegSN74HC165N

Edit: Okay it's a common problem between the 165 and the ShiftIn function. Including an
     digitalWrite(clockPin, HIGH);
before setting the latchPin LOW solves it.
« Last Edit: October 03, 2013, 03:01:34 pm by flocked » Logged

West Yorkshire, UK
Offline Offline
God Member
*****
Karma: 17
Posts: 706
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I've got an idea.

The shiftIn() function toggles the clock pin to retrieve each bit from the register. Its up to the programmer to set the clock either high or low before calling shiftIn() to ensure data is read on the correct rising/falling edge of the clock.

The example code you linked to sets the output of the clock pin before calling shiftIn(), your code doesn't...

Paul

Edit: you beat me to it!
Logged

Pages: [1] 2   Go Up
Jump to: