Go Down

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

Jobi-Wan

[...] I have 20 chips... and only 8 work.

[...] 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?
Each chip has no idea that it is part of a chain. It doesn't know whether its output goes to another 74hc165 or to your atmega. It just shifts on a clock pulse.

When you say it works with 4 of the 20 chips, what do you get for the other 16? All high? All low? Random values?


For me, this works:
Code: [Select]
const uint8_t pin_PL = 7; // to all pins 1
const uint8_t pin_CP = 5; // to all pins 2
const uint8_t pin_Q7 = 3; // to pin 9 of the 1st chip.
// pin 10 of each chip to pin 9 of next chip



void setup()
{
  Serial.begin(115200);

  pinMode(pin_PL, OUTPUT);
  pinMode(pin_CP, OUTPUT);
  pinMode(pin_Q7, INPUT);

  digitalWrite(pin_PL, HIGH);
  digitalWrite(pin_CP, HIGH);
}

void loop()
{
  // Latch data from input pins into shift registers
  digitalWrite(pin_PL, LOW);
  digitalWrite(pin_PL, HIGH);

  // Read all bits from all shift registers one by one
  for (int i = 0; i < 16; i++)
  {
    Serial.print("pin ");
    Serial.print(i);
    Serial.print(" is ");

    if (digitalRead(pin_Q7) == HIGH)
      Serial.println("HIGH");
    else
      Serial.println("LOW");

    // Clock pulse to shift to the next bit
    digitalWrite(pin_CP, LOW);
    digitalWrite(pin_CP, HIGH);
  }
  Serial.println();


  delay(1000);
}



I only have 2 of those chips laying around, so I can't test with more. See if this works for you for more than 32 pins.


Herodes

Great! Thanks! Your code works for me too, but only for 8 chips, no more.


When you say it works with 4 of the 20 chips, what do you get for the other 16? All high? All low? Random values?

Nothing. It doesn't print anything in Serial Monitor.

Up to chip 8, when I press I get a line of "0" and "1", where "1" corresponds to the switch pressed. Upon release, I get a line of "0", as befits the code you wrote from line 27.

But on chip 9, 10 ... I do not get anything, there is no answer. No line is displayed on the Series Monitor.

Jobi-Wan

#17
May 15, 2018, 06:44 pm Last Edit: May 15, 2018, 06:50 pm by Jobi-Wan
Great! Thanks! Your code works for me too, but only for 8 chips, no more.
If you change 16 to 160 in my sketch, surely it will display a value for all 160 pins. It does for me. Since I have only 2 chips, if I tie pin 10 of my 2nd chip low or high, that is what I get for pins 16 .. 159.

Edit to add...
Nothing. It doesn't print anything in Serial Monitor.
But on chip 9, 10 ... I do not get anything, there is no answer. No line is displayed on the Series Monitor.
That suggests that your code just doesn't process more than 64 pins. You can just read from pins and pulse other pins as often as you like regardless of what is connected to those pins.
Can you post the latest version of your code?

Grumpy_Mike

Quote
Are you sure you can chain as many 74HC165 chips as you want?
Yes

Quote
Will not the number of 74HC165 chips that can be chained be limited to 8?
No.

Quote
Your code works for me too, but only for 8 chips, no more.
So post the modifications to the code and let us see if you have incorporated them correctly.

Herodes

#19
May 15, 2018, 07:54 pm Last Edit: May 16, 2018, 10:05 am by Herodes
It works!!!! It works!!!! It works!!!! Great!!!! It works fine!!! You are my best friends and I have a great debt to you!!!

I modified the code a little (what I know...) to see more comfortably "1" and "0", in a line. I have also modified the speed to 9600, because at 115200 I saw strange symbols.

Here I leave it, for those who need it. I think there are a lot of people looking for something like that.

Certainly, I have a very great debt with you.

Many, many, many thanks!


Code: [Select]
const uint8_t pin_PL = 7; // to all pins 1
const uint8_t pin_CP = 5; // to all pins 2
const uint8_t pin_Q7 = 3; // to pin 9 of the 1st chip.
// pin 10 of each chip to pin 9 of next chip



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

  pinMode(pin_PL, OUTPUT);
  pinMode(pin_CP, OUTPUT);
  pinMode(pin_Q7, INPUT);

  digitalWrite(pin_PL, HIGH);
  digitalWrite(pin_CP, HIGH);
}

void loop()
{
  // Latch data from input pins into shift registers
  digitalWrite(pin_PL, LOW);
  digitalWrite(pin_PL, HIGH);

  // Read all bits from all shift registers one by one
  for (int i = 0; i < 80; i++)
  {
    //Serial.print("pin ");
    //Serial.print(i);
    //Serial.print(" is ");

    if (digitalRead(pin_Q7) == HIGH)
      Serial.print("1");
    else
      Serial.print("0");

    // Clock pulse to shift to the next bit
    digitalWrite(pin_CP, LOW);
    digitalWrite(pin_CP, HIGH);
  }
  Serial.println();


  delay(1000);
}

Herodes

#20
May 16, 2018, 03:39 pm Last Edit: May 17, 2018, 12:47 pm by Herodes
After advancing at 74HC165, it is time to act at 74HC595.

When I used the library, there was a command that served to know which switch was pressed. Now I do not have that command. In the loop, I know that if I press the switch 8, the character 8 is a 1, but then I did not finish: I did not just make an output in 74HC595 when I pressed a switch in 74HC165.

Can you think of something?

I paste here the complete code:

Code: [Select]
//____________________________________________
//74HC595=====================================
/* A continuación te pongo cómo tienes que conectar el primer chip
 * al Arduino. Ten en cuenta que los pines se numeran del 1 al 16
 * desde el inferior izquiero (1), en el sentido contrario al movi-
 * miento de las agujas del reloj, viendo la muesca del chip a la
 * izquierda, terminando así en el 16, en la esquina superior iz-
 * quierda, que es Vcc.
 */
int SER_Pin = 6;   //pin 14 on the 75HC595
int RCLK_Pin = 7;  //pin 12 on the 75HC595
int SRCLK_Pin = 8; //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 estado000 = 0;
////////////////////////

//____________________________________________
//74HC165=====================================
/* A continuación te pongo cómo tienes que conectar el primer chip
 * al Arduino. Ten en cuenta que los pines se numeran del 1 al 16
 * desde el inferior izquiero (1), en el sentido contrario al movi-
 * miento de las agujas del reloj, viendo la muesca del chip a la
 * izquierda, terminando así en el 16, en la esquina superior iz-
 * quierda, que es Vcc.
 * El pin 15 lo he puesto a 9 y rula, así que así queda.
 */
const uint8_t pin_PL = 10; // to all pins 1
const uint8_t pin_CP = 11; // to all pins 2
const uint8_t pin_Q7 = 12; // to pin 9 of the 1st chip.
// pin 10 of each chip to pin 9 of next chip

//____________________________________________
//Pantalla20x4·I2C============================
/*Conecta los cables SDA a SDA y SCL a SCL, calamar.*/
  #include <Wire.h>
  #include <LiquidCrystal_I2C.h>
  LiquidCrystal_I2C lcd(0x27,20,4);


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

  //reset all register pins
  clearRegisters();
  writeRegisters();
 
//____________________________________________
//74HC165=====================================
  Serial.begin(115200);

  pinMode(pin_PL, OUTPUT);
  pinMode(pin_CP, OUTPUT);
  pinMode(pin_Q7, INPUT);

  digitalWrite(pin_PL, HIGH);
  digitalWrite(pin_CP, HIGH);
 
//____________________________________________
//Pantalla20x4·I2C============================
  //Iniciamos el fondo retroiluminado
  //lcd.backlight();
  lcd.noBacklight();
  //Iniciamos la pantalla
  lcd.init();
  //LCD.
  lcd.setCursor(0,0);
  lcd.print("   Universidad de   ");//Escribir en la LCD
  lcd.setCursor(0,1);
  lcd.print("     Salamanca      ");//Escribir en la LCD
  lcd.setCursor(0,2);
  lcd.print("   EPS de Zamora    ");//Escribir en la LCD
  lcd.setCursor(0,3);
  lcd.print("  Laboratorio TIT   ");//Escribir en la LCD
//  delay(1000);

}

//____________________________________________
//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;
}


//////////////////////////////////////////////
//////////////////////////////////////////////
void loop(){
//____________________________________________
//74HC595=====================================
////////////////////////
  estado000 = digitalRead(pin_Q7);
////////////////////////

//Serial.println(boton01);
  if(estado000 == 9) {
    setRegisterPin(9, HIGH);
//  digitalWrite(13, HIGH);
  }
  else {
    setRegisterPin(9, LOW);
//  digitalWrite(13, LOW);
  }
////////////////////////

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

//____________________________________________
//74HC165=====================================
  // Latch data from input pins into shift registers
  digitalWrite(pin_PL, LOW);
  digitalWrite(pin_PL, HIGH);


/* Aquí tienes también que intervenir. En el bucle tienes que
 * cambiar el parámetro "n" en "i < n". Tienes que poner el
 * número total de pines que quieres que se lean. Este número
 * será igual al número de chips x 8 (esto ya es para logsianos).
 */
  // Read all bits from all shift registers one by one
  for (int i = 0; i < 80; i++)
  {
    if (digitalRead(pin_Q7) == HIGH)
      Serial.print("1");
    else
      Serial.print("0");
   
  // Clock pulse to shift to the next bit
    digitalWrite(pin_CP, LOW);
    digitalWrite(pin_CP, HIGH);
  }
  //Serial.print(digitalRead(pin_Q7));
  Serial.println();
   
//____________________________________________
//Pantalla20x4·I2C============================
//  lcd.clear();//Limpiamos la LCD
//  lcd.print("Hola");//Escribimos en la primera linea
//  lcd.setCursor(0,1);//Saltamos a la segunda linea
//  lcd.print("mundo");//Escribimos en la segunda linea
//  lcd.setCursor(0,2);//Saltamos a la tercera linea
//  lcd.print("USAL");//Escribimos en la tercera linea
//  lcd.setCursor(0,3);//Saltamos a la cuarta linea
//  lcd.print("----");//Escribimos en la cuarta linea
 
  //Tiempo de espera para que reinicie el ciclo
  //delay(500);
  }

Jobi-Wan

#21
May 16, 2018, 05:44 pm Last Edit: May 16, 2018, 05:46 pm by Jobi-Wan
but then I did not finish: I did not just make an output in 74HC595 when I pressed a switch in 74HC165.
In your loop() function, you call writeRegisters(), so you are outputting to the 595s.
But your registers array is full of zeros.


Code: [Select]
    if (digitalRead(pin_Q7) == HIGH)
      Serial.print("1");
    else
      Serial.print("0");

At this point, you can add your logic to set or clear registers[] based on which inputs are high and low. As a first test, I would start with something simple, like setting each register to the same value as corresponding input.



Did you already test that your outputs are working? When you change your clearRegisters() function to set everything to HIGH instead of LOW, do all your outputs go high?

Herodes

The outputs are working. I do not know how I got output 1 to move a relay. But I have not managed other outputs to move relays. I do not know how to do it.

Jobi-Wan

The outputs are working.
How did you test this?


The outputs of your 595 chips can source/sink 35mA at absolute maximum. That is probably not enough to drive a relay directly. It could damage your 595.

Find the datasheet for your relay, and read it. Also post a link to it here.

Wiring up a 595 output to a relay should involve an NPN transistor, a current limiting resistor, a diode for the coil induction spike, maybe some capacitance. You should be able to find examples. Maybe you use a module that has all of this on board.




If you're going to drive 160 relays, you will need special considerations regarding power and noise.

PaulRB

#24
May 16, 2018, 08:26 pm Last Edit: May 16, 2018, 08:28 pm by PaulRB
When most newbies to the forum say "relay" what they actually mean is a relay module. Of course it's important to establish that is the case. Relay modules sometimes have opto-isolators, but mostly they have driver transistors, reverse voltage coil diodes and indicator LEDs. What most newbies don't realise, of course, is how old fashioned relays are (though they can still have a place) and more importantly how much current they draw to activate their coils. They don't realise that for switching DC voltages, a logic-level MOSFET is cheaper, easier, smaller, simpler, faster, quieter, longer-lasting and need almost no current to operate them.

Herodes

PaulRB: I have to admit that you are absolutely right: I am absolutely newbie. But sometime has to be the first. I have referred to a relay module, like this:



From what you tell me, I learn, and I thank you for your words. In fact, I have proposed this challenge to stumble and, stumbling, learn. I put relays because it was what I knew. Yes I had read about the MOSFET but nowhere with the concretion that you have expressed: thank you. In a future project I will use the MOSFETs that you indicate to me.

Nowhere else on the Internet have I learned as much as I am learning here. I have to thank you.

Jobi-Wan: I have powered the relays with a 5V separate Arduino source. But that is not the problem for now: now, my problem is to be able to transmit to the 595 what the 165 command. I can do it with LEDs and resistors, no problem.

I know other programming languages ​​but Arduino is new to me and, like all languages, has its peculiarities. What I do not master are the characteristic commands of this language. The rest, I'm familiar.

Tomorrow I will continue thinking about how to transmit the orders from 165 to 595. I do not think it is difficult. I think the most difficult thing, I've already done it. Or, better said, thanks to you, Jobi-Wan.


Jobi-Wan

Jobi-Wan: I have powered the relays with a 5V separate Arduino source. But that is not the problem for now: now, my problem is to be able to transmit to the 595 what the 165 command. I can do it with LEDs and resistors, no problem.
If you supply power from one Arduino and signal from another, then those two Arduinos should have their grounds connected together.

If you can do it with LEDs, but not with your relays, then your relay board is not wired up correctly.

How did you test and confirm that your outputs are working?

Can you explain in detail how your program works? Especially writeRegisters() and setRegisterPin()


Herodes

If you supply power from one Arduino and signal from another, then those two Arduinos should have their grounds connected together.
There are not two Arduinos: there is one Arduino Mega and a power supply of 5V and 50W. It gives enough intensity for both and effectively, they share negative and also positive.

If you can do it with LEDs, but not with your relays, then your relay board is not wired up correctly.
Both with LED and with relays, both work correctly.

How did you test and confirm that your outputs are working?

Can you explain in detail how your program works? Especially writeRegisters() and setRegisterPin()
I'm trying to reproduce what I did yesterday to check that the exits worked  ::)  :smiley-eek-blue:  :smiley-roll-blue:  :smiley-red: .

As soon as I have it, I paste the code.

UKHeliBob

Quote
they share negative and also positive.
Do you mean by that they are powered from a 5V pin on the Arduino or directly from the power supply ?  It sounds like the former and, if so, it is the wrong way to do it.
Please do not send me PMs asking for help.  Post in the forum then everyone will benefit from seeing the questions and answers.

Herodes

#29
May 17, 2018, 04:47 pm Last Edit: May 17, 2018, 04:48 pm by Herodes
Do you mean by that they are powered from a 5V pin on the Arduino or directly from the power supply ?  It sounds like the former and, if so, it is the wrong way to do it.
The relays and the Arduino are powered directly from the power supply. It can be said that the relays and Arduino are in parallel but Arduino governs the relays going through 595. Today they have been running like this all day and they do not smell like burning!  8)  :-[

I keep thinking about how I connected everything yesterday to check that the exits responded ... I've been here all day!!! I will find it!!! :smiley-sad-blue:

Go Up