Go Down

Topic: Two daisy chained 74HC165: Can’t detect several button presses at once (Read 2 times) previous topic - next topic

flocked

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: [Select]
//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;
}

PaulRB

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

flocked

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.

Paul__B

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.

flocked

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.

fungus


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.
No, I don't answer questions sent in private messages (but I do accept thank-you notes...)

fungus

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?


No, I don't answer questions sent in private messages (but I do accept thank-you notes...)

CrossRoads

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: [Select]

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);


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.

PaulRB


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?

flocked


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…

PaulRB

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

flocked


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… :/

flocked

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! :)

flocked

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.

PaulRB

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!

Go Up