Go Down

Topic: Maximum number of SN74HC165N (Read 2430 times) previous topic - next topic

Herodes

How many SN74HC165N can multiplex with one Arduino Mega 2560?

Jobi-Wan

You can chain them together:

Connect all latch pins (/PL, 1) together, connect all clock pins (CP, 2) together,
Connect the Q7 pin (9) of each chip into the DS pin (10) of the next chip, and the Q7 pin (9) of the last one into an input pin on your Arduino.

This way you only need 3 pins on your Arduino regardless the number of chips.

There is no logical limit on how many you can chain.
Maybe at some point the cumulative propagation delay becomes more than half a clock, so it would also depend on the clock speed then, but I'm not even sure that is a factor. Or at some point you need driver circuitry to drive large numbers of latch and clock pins.

I realise that 'at some point' is not a very exact number, and I don't have the knowledge or experience to make an educated guess. So my uneducated guess is that you can chain at least a few dozen without special considerations.

PaulRB

#2
May 13, 2018, 06:24 pm Last Edit: May 13, 2018, 06:25 pm by PaulRB
You may be able to connect perhaps 20 chips in a daisy chain, maybe more depending on the quality and length of the wires or PCB tracks. If you add some buffer chips to the clock and latch lines as mentioned above, you can probably extend this to 40, 60, 80... chips.

But this sounds like a classic "X-Y problem". What is your project and why do you believe you need so many '165 chips?

Herodes

It is a train layout and I use this for receive signal about where the trains are, with reed sensors. I have 20 HC165 and with lib Shift.in only works 8.

PaulRB

Quote
I have 20 HC165 and with lib Shift.in only works 8.
I don't understand what you are saying. Are you saying that a library that you are using only works with 8 shift registers? What library? Can you post a code example?

Herodes

#5
May 14, 2018, 08:58 am Last Edit: May 14, 2018, 10:55 am by Herodes Reason: Sorry, UKHeliBob, I have fixed it.
Thank you for your answers.

Below I paste my code, which combines the inputs with 74HC165 chips with outputs, with 74HC595. It is a test code. It only serves to check if Arduino recognizes the pulsations of the input switches, through the 74HC165 chip.

On this page, which talks about the ArduinoShiftIn library (see API), it is written that no more than 8 chips are supported. My question is: is this limitation of the chips or is it that library, specifically? I have made the connections as indicated in the figure of that Web page.

As for the outputs by 74HC595 I have not had any problem: all are recognized.

The code works perfectly, except that from chip 9, included, it does not recognize the pulsations: a pulse on a switch connected to chip 9 (and successive) is not reflected in the Serial Monitor. Is this a limitation of the library used or is it a limitation of the 74HC165 chips?

Here is the code:

Code: [Select]
//____________________________________________
//74HC595=====================================
int SER_Pin = 5;   //pin 14 on the 75HC595
int RCLK_Pin = 6;  //pin 12 on the 75HC595
int SRCLK_Pin = 7; //pin 11 on the 75HC595

//How many of the shift registers - change this
#define number_of_74hc595s 20

//do not touch
#define numOfRegisterPins number_of_74hc595s * 8

boolean registers[numOfRegisterPins];

////////////////////////
int estado00 = 0;
////////////////////////

//____________________________________________
//74HC165=====================================
#include <ShiftIn.h>
// Init ShiftIn instance with one chip.
// The number in brackets defines the number of daisy-chained 74HC165 chips
// So if you are using two chips, you would write: ShiftIn<2> shift;
ShiftIn<20> shift;

//////////////////////////////////////////////
//////////////////////////////////////////////
void setup(){
//____________________________________________
//74HC595=====================================
  pinMode(SER_Pin, OUTPUT);
  pinMode(RCLK_Pin, OUTPUT);
  pinMode(SRCLK_Pin, OUTPUT);

  //reset all register pins
  clearRegisters();
  writeRegisters();
//____________________________________________
//74HC165=====================================
  Serial.begin(9600);
  // declare pins: pLoadPin, clockEnablePin, dataPin, clockPin
  shift.begin(8, 9, 11, 12);
}

//____________________________________________
//74HC595=====================================
void clearRegisters(){
//set all register pins to LOW
for(int i = numOfRegisterPins - 1; i >=  0; i--){
     registers[i] = LOW;
  }
}

void writeRegisters(){
//Set and display registers
//Only call AFTER all values are set how you would like (slow otherwise)
  digitalWrite(RCLK_Pin, LOW);
  //for(int i = numOfRegisterPins - 1; i >=  0; i--){
  for(int i = numOfRegisterPins; i >=  1; i--){
    digitalWrite(SRCLK_Pin, LOW);
    int val = registers[i];
    digitalWrite(SER_Pin, val);
    digitalWrite(SRCLK_Pin, HIGH);
  }
  digitalWrite(RCLK_Pin, HIGH);
}

void setRegisterPin(int index, int value){
//set an individual pin HIGH or LOW
  registers[index] = value;
}

//____________________________________________
//74HC165=====================================
void displayValues() {
  for(int i = 0; i < shift.getDataWidth(); i++)
    Serial.print( shift.state(i) ); // get state of button i
  Serial.println();
//  Serial.print( shift.state(0) );
}

//////////////////////////////////////////////
//////////////////////////////////////////////
void loop(){
//____________________________________________
//74HC595=====================================
////////////////////////
  //estado = digitalRead(7);
  estado00 = ( shift.state(0) );
////////////////////////

//Serial.println(boton01);
  if(estado00 == 0) {
    setRegisterPin(80, HIGH);
    digitalWrite(13, HIGH);
  }
  else {
    setRegisterPin(80, LOW);
    digitalWrite(13, LOW);
  }
////////////////////////

  writeRegisters();  //MUST BE CALLED TO DISPLAY CHANGES
  //Only call once after the values are set how you need.

//____________________________________________
//74HC165=====================================
  if(shift.update()) // read in all values. returns true if any button has changed
    displayValues();
  delay(1);

}

UKHeliBob

Code: [Select]
no_code_tags = mangled_code;
if (mangled_code)
{
  Serial.println("Difficult to help");
}
Please do not send me PMs asking for help.  Post in the forum then everyone will benefit from seeing the questions and answers.

Herodes

Code: [Select]
no_code_tags = mangled_code;
if (mangled_code)
{
  Serial.println("Difficult to help");
}


:smiley-eek:  :smiley-eek:  :smiley-eek:

Jobi-Wan

:smiley-eek:  :smiley-eek:  :smiley-eek:
UKHeliBob is asking you to put the code you posted in post #5 inside code-tags. (Use the </> button.)
It makes puts your code in a scrollable box with fixed width font, preserves every character and does not render as smileys.

For example:

void clearRegisters(){
//set all register pins to LOW
for(int i = numOfRegisterPins - 1; i >=  0; i--){
     registers = LOW;
  }
Presumably, your actual code says "registers[ i ] = LOW;" but without code-tags, the [ i ] is not displayed and instead makes the rest of the text italic.



As for your question...


Instead of using that library, you can 'do it yourself', in much the same way you do with the 595 chips, except your serial data pin would be an input pin you read from instead of an output pin you write to.


Herodes

Fixed my post # 5. I am so sorry.

Sorry for my clumsiness, Jobi-Wan and UKHeliBob, but I'm very new to Arduino and I'm learning.

You mean do not use any library? Can you tell me where can I find an example where no library is used?

I have not found it but, certainly, I have always thought that this type of chips would require a library.

UKHeliBob

Quote
You mean do not use any library? Can you tell me where can I find an example where no library is used?
Not strictly without a library, but using SPI

See http://forum.arduino.cc/index.php?topic=409739.0
Please do not send me PMs asking for help.  Post in the forum then everyone will benefit from seeing the questions and answers.

Jobi-Wan

An example is in your code. You can handle the 74HC165 in almost the same way you handle the 74HC595.
With only little change, you can turn your writeRegisters() function into a readRegisters() function.

When you write to the 595, you control the clock and you set the data. So the data pin is an output pin.
When you read from the 165, you control the clock, but it sets the data that you then read. So the data pin is an input pin.


Here is another example:
https://playground.arduino.cc/Code/ShiftRegSN74HC165N
The read_shift_regs() function is where it happens. Note how it looks kind of similar to your writeRegisters() function. Except it uses a digitalRead() instead of digitalWrite() on the data pin.

There are some differences. Mainly, this example uses 1 bit per pin instead of 1 byte per pin; it stores the state of 16 buttons into one unsigned 16 bit int. (Where it says: "Set the corresponding bit in bytesVal".)

I believe you can just tie the /CE pin low.

Herodes

It does not work, I do not get it...

UKHeliBob

It does not work, I do not get it...
What hardware and software combination doesn't work and what exactly is the problem ?
Please do not send me PMs asking for help.  Post in the forum then everyone will benefit from seeing the questions and answers.

Herodes

The problem is, exactly, the one I described earlier, in post # 3. With the Shift.in library, I manage to make 8 chips work, but I have 20 chips... and only 8 work.

I have tried the code of the example that Jobi-Wan proposes in his post # 11 and with that code, only 4 chips worked of the 20 that I have.

Are you sure you can chain as many 74HC165 chips as you want? Will not the number of 74HC165 chips that can be chained be limited to 8?

Go Up