74HC595 and relays

Hello friends,

I again abuse your patience with me to ask a question:

I have a Mega 2560 connected as indicated on this website:

But instead of connecting LEDs, I connect relays of this type:

Well, when I run the code shown in the previous Web as "Hello world" (which I hit below), the relays do not move.

Should not they move, and do what the LEDs do when the LED circuit is done?

Is there anything I should keep in mind with the relays that make their behavior different from the behavior of the LEDs?

//**************************************************************//
//  Name    : shiftOutCode, Hello World                                
//  Author  : Carlyn Maw,Tom Igoe, David A. Mellis 
//  Date    : 25 Oct, 2006    
//  Modified: 23 Mar 2010                                 
//  Version : 2.0                                             
//  Notes   : Code for using a 74HC595 Shift Register           //
//          : to count from 0 to 255                           
//****************************************************************

//Pin connected to ST_CP of 74HC595
int latchPin = 8;
//Pin connected to SH_CP of 74HC595
int clockPin = 12;
////Pin connected to DS of 74HC595
int dataPin = 11;



void setup() {
  //set pins to output so you can control the shift register
  pinMode(latchPin, OUTPUT);
  pinMode(clockPin, OUTPUT);
  pinMode(dataPin, OUTPUT);
}

void loop() {
  // count from 0 to 255 and display the number 
  // on the LEDs
  for (int numberToDisplay = 0; numberToDisplay < 256; numberToDisplay++) {
    // take the latchPin low so 
    // the LEDs don't change while you're sending in bits:
    digitalWrite(latchPin, LOW);
    // shift out the bits:
    shiftOut(dataPin, clockPin, MSBFIRST, numberToDisplay);  

    //take the latch pin high so the LEDs will light up:
    digitalWrite(latchPin, HIGH);
    // pause before next value:
    delay(500);
  }
}

How have you wired this up? Schematic please not words.
Can you post a link to these relays apart from a useless pretty picture.

Hello friend Grumpy_Mike,

Thank you so much for your answer. Before bothering again, I thoroughly reviewed the connections and there was an error that I have already corrected.

I am adding 74HC595 with blocks of relays and executing the examples of the Web https://www.arduino.cc/en/Tutorial/ShiftOut, to go verifying that everything works perfect.

When I finish connecting everything, my problem will be how to make a specific relay open or close with a button, which will be connected to a 74HC165.

Herodes:
When I finish connecting everything, my problem will be how to make a specific relay open or close with a button, which will be connected to a 74HC165.

You can use the shiftIn() function to read the buttons attached to the 74hc165. Alternatively you can connect the chain of 74hc595 and the chain of 74hc165 to the SPI pins and use SPI.transfer() to simultaneously read the buttons and set the relays.

You will need to study the "State Change" example sketch to learn how to toggle the relay output pins when a button is pressed.

In this thread

https://forum.arduino.cc/index.php?topic=547209.0

I was testing SPI and I think I remember that I found a limitation regarding the number of 74HC165. I think I need some more information about the shiftIn() function...

The limitation will be a hardware one, such as fan-out of the clock and latch signals. It has nothing to do with using SPI and using shiftIn() will make no difference to that.

Your link does not work. Please check your posts by clicking on any links and if they do not work, edit your post and fix them.

Why have you started a new topic/thread? You will get into trouble with the forum moderators because you are cross-posting.

Your link does not work.

Well it does if you copy and paste it. I suspect that he has not used the forum link tabs correctly.

This is the real link:-
https://forum.arduino.cc/index.php?topic=547209.0

PaulRB:
Why have you started a new topic/thread? You will get into trouble with the forum moderators because you are cross-posting.

I wouldn't like to get into trouble! I am only looking for some orientation.

The other thread was about 74HC165 and this is about 74HC595. 74HC165 is for input and 74HC595 is for output; they are different. That is why.

Thanks, Grumpy_Mike, that is correct.

74HC165 is for input and 74HC595 is for output; they are different.

Not very different, you only swap a serial input for a serial output otherwise they are the same. Apply the same techniques you did for the input.

Grumpy_Mike:
Well it does if you copy and paste it. I suspect that he has not used the forum link tabs correctly.

I also did that, I agree.

Herodes:
The other thread was about 74HC165 and this is about 74HC595. 74HC165 is for input and 74HC595 is for output; they are different. That is why.

Let us hope that the moderators see that as a sufficiently good reason, because you did say that your design includes both chips in the other thread:

Herodes:
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.

Grumpy_Mike:
Not very different, you only swap a serial input for a serial output otherwise they are the same. Apply the same techniques you did for the input.

Ok, thanks, Grumpy_Mike.

PaulRB:
I also did that, I agree.Let us hope that the moderators see that as a sufficiently good reason, because you did say that your design includes both chips in the other thread:

:frowning:

Indeed, the code I pasted there combined the inputs with 74HC165 with outputs 74HC595, wanting to know if Arduino recognized the pulses in the switches connected to the 74HC165. But the code did not work. Finally, Jobi-Wan helped me and I could see the pulsations in the switches on the Serial Monitor.

But now the situation is different: now I want to see the pulsations in the switches reflected in the movement of a certain relay. Certainly, this thread started thinking that when going through the 74HC595 there would not be enough power to move the relay because I entered the code of the examples and the relays did not move. Maybe I rushed when it was time to open a new thread. As much as I reviewed the connections I did not see the failure. Sometimes it happens that you blind and do not see it until you let it rest. I let it rest, I went back to review ... et voilá !!! There was a bad connection.

Nothing is further from my intention than bother, PaulRB, and even less in a place where I have been given so much help. On the contrary: I am very grateful.

At first I thought about continuing on the old thread but I thought that what I was going to ask, although it was about the same project, corresponded to a different component: there I asked about 74HC165 and here about 74HC595. I thought of a new thread for not mixing. Sometimes you never know how to hit.

If, as Grumpy_Mike says, both are similar, I only have to apologize for my ignorance and, if the moderators consider that the thread should be closed or eliminated, it should be done like that.

Even so, I still can not make a 74HC165 switch move a particular 74HC595 relay. But I do not want to abuse more of your time, and I'll look for it.

Thank you very much for your advice and your time!

Even so, I still can not make a 74HC165 switch move a particular 74HC595 relay.

Then break it down into smaller steps do not try to do too much in one step. So forget the 165 for a moment and just use a single push button to set and clear a single bit in the 595. Use an led and resistor on one of the 595’s output pins and see if you can make that work first. The wiring is simpler and so is the code. Get that going first.

Yes, thank you, friend, I will do it. Now I'm going through all the connections again and checking that all the relays move. I have 160 relays and I think that in the last 64 I should have some bad connection.

As soon as I get results I'll put them here (although I think I'll take a little longer).

Hello friends,

Well, here I am again. As I told you, it would take me to go back, but I would go back. So here I am. In Spain it is said that "... it is well born to be grateful ...", and I am here to thank you for your help and share the solution, which I have been able to reach thanks to you. I think this solution may be interesting.

I paste the code with which my 74HC595 works with my 74HC165 in a new post because I exceed the number of characters in it. What this code does is increase the number of inputs and outputs of an Arduino. I have used an Arduino MEGA 2560 but I would expect the code to work on any Arduino model.

In the code I have "Spanishized" some functions, for my clarity. There is also a part relative to two screens. This part is not necessary.

The switches are connected to the 74HC165, as shown in the figure:

And I have connected relays to 74HC595, also as indicated in the figure, in which there are LEDs instead of relays.

With this code, each switch will send a relay (instead of an LED, as shown in the figure). I have connected 5 units of 74HC165, 5 units of 74HC595 and 40 relays.

Compilation of issues to consider:

  1. I have not used the Shift.in library because, as I put in this thread, it only supports 8 modules of 74HC165.

  2. If the output of the 74HC595 is overloaded (as it is in my case, with no less than 40 relays in the test that will end up being 160), it is necessary to feed that load separately, with 5V but sharing the negative with Arduino. I have used a 50W source that feeds Arduino in parallel with the relays. But the 74HC165 and the 74HC595 have to be powered with Arduino. I tried to feed them separately, with the same source of the relays, and the first ones (those that received more intensity of current) burned.

I'm very happy! I have achieved it and I have learned a lot!

Hope that helps!

And here is the code:

/* Juan Ramón Muñoz Rico
   Escuela Politécnica Superior
   Campus Viriato de Zamora
   Universidad de Salamanca
   http://dim.usal.es/eps/mmt
*/

/*
===================================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 izquierdo (1), en el sentido contrario al movimiento de las 
   agujas del reloj, viendo la muesca del chip a la izquierda, terminando así
   en el 16, en la esquina superior izquierda, que es Vcc.
*/
/* pin 12 (ST_CP) on the 75HC595                                           */
   int latchPin595 = 6; 
/* pin 11 (SH_CP) on the 75HC595                                           */
   int clockPin595 = 7; 
/* pin 14 (DS)    on the 75HC595                                           */
   int dataPin595 = 8;

/* How many of the shift 74hc595 - change this                             */
   #define number_of_74hc595s 5

/* do not touch                                                            */
   #define numeroDeReles number_of_74hc595s *8

   boolean rele[numeroDeReles];

/*
===================================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 izquierdo (1), en el sentido contrario al movimiento de las 
   agujas del reloj, viendo la muesca del chip a la izquierda, terminando así
   en el 16, en la esquina superior izquierda, que es Vcc
   El pin 15 lo he puesto a 9 y rula, así que así queda.
*/

/* pin 1 (PL) on the 75HC165                                               */
   const uint8_t pLoadPin165 = 10;
/* pin 2 (CP) on the 75HC165                                               */
   const uint8_t clockEnablePin165 = 11;
/* pin 9 (Q7) on the 75HC165                                               */
   const uint8_t dataPin165 = 12;
/* pin 15 (CE) on the 75HC165                                              */
/* const uint8_t clockPin165 = 9;                                          */

   int numeroderele;
   int valor0o1;
/*
   const uint8_t pin_CE(barra) = 15; // to pin 9 of the 1ast chip.
   pin 10 of each chip to pin 9 of next chip
*/
/*
==============================Pantalla 20x4·I2C==============================
   Conecta los cables SDA a SDA y SCL a SCL, calamar.
*/
   #include <Wire.h>
   #include <LiquidCrystal_I2C.h>
/* A continuación, el código para poner dos pantallas.                     */
   LiquidCrystal_I2C lcd0(0x27,20,4); /* LCD 0x27                          */
   LiquidCrystal_I2C lcd1(0x26,20,4); /* LCD 0x26                          */
/* Aquí originalmente ponía 0x24. Pues no. Hay que poner 0x3f y rula.      */
/*
   Nótese la diferencia: uno es 0x26 y otro, 0x27. Diferentes direcciónes
   I2C.
   Ver el vídeo https://www.youtube.com/watch?v=gBg0OR6Voc8&t=119s
   Si es sólo una pantalla, aquí originalmente ponía 0x24.
   Pues no. Hay que poner 0x3f y rula.
   Ésto último es lo que vale con el I2C que he soldado yo, como se indica en
   el vídeo.
*/

/*
=============================================================================
=============================================================================
*/

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

/*
===================================74HC595===================================
*/
   pinMode(dataPin595, OUTPUT);
   pinMode(latchPin595, OUTPUT);
   pinMode(clockPin595, OUTPUT);
   
/* reset all register pins                                                 */
   
   borra595();
   escribe595();
/*
===================================74HC165===================================
*/
   pinMode(pLoadPin165, OUTPUT);
   pinMode(clockEnablePin165, OUTPUT);
   pinMode(dataPin165, INPUT);

   digitalWrite(pLoadPin165, HIGH);
   digitalWrite(clockEnablePin165, HIGH);

/*
==============================Pantalla 20x4·I2C==============================
   Iniciamos el fondo retroiluminado.
*/
   lcd0.init();
   lcd0.backlight();
   lcd1.init();
   lcd1.backlight();
/* lcd.noBacklight();                                                      */
/* lcd2.noBacklight();                                                     */
/* Iniciamos las dos pantallas LCD.                                        */
   lcd0.setCursor(0,0);
   lcd0.print("  Morales del Vino  ");//Escribir en la LCD
   lcd0.setCursor(0,1);
   lcd0.print("Salidas: Expreso    ");//Escribir en la LCD
   lcd0.setCursor(0,2);
   lcd0.print("Destino: Salamanca  ");//Escribir en la LCD
   lcd0.setCursor(0,3);
   lcd0.print("Hora: 15:10         ");//Escribir en la LCD
   lcd1.setCursor(0,0);
   lcd1.print("     Candelario     ");//Escribir en la LCD
   lcd1.setCursor(0,1);
   lcd1.print("Llegadas: Mercancias");//Escribir en la LCD
   lcd1.setCursor(0,2);
   lcd1.print("Procedencia: Zamora ");//Escribir en la LCD
   lcd1.setCursor(0,3);
   lcd1.print("Hora: 04:50         ");//Escribir en la LCD
/* delay(1000);                                                            */
}

/*
=============================================================================
=============================================================================
*/

void loop()
{
/*
===================================74HC595===================================
*/
/* cambiaRele(10, LOW); Esto está puesto para probar; se puede borrar.     */

/*
===================================74HC165===================================
*/
/* Latch data from input pins into shift rele.                             */
   digitalWrite(pLoadPin165, LOW);
   digitalWrite(pLoadPin165, 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 74HC165 one by one.                        */
   
   for (int i = 1; i <= 40; i++)
   {
       if (digitalRead(dataPin165) == HIGH)
       {
           //Serial.print("1");
           numeroderele = i;
           valor0o1 = LOW;
           cambiaRele(numeroderele, valor0o1);
        }
        else
        {
/*         Serial.print("0");                                              */
           numeroderele = i;
           valor0o1 = HIGH;
           cambiaRele(numeroderele, valor0o1);
        }
/* Clock pulse to shift to the next bit                                    */

      digitalWrite(clockEnablePin165, LOW);
      digitalWrite(clockEnablePin165, HIGH);
   }
   Serial.println();
}

/*
=============================================================================
=============================================================================
*/

/*
===================================74HC595===================================
*/

void borra595()
{
/* 
   Set all register pins to HIGH/LOW.
   HIGH es que los relés están cerrados (luz apagada).
   LOW es que los relés están abiertos (luz encendida).
*/
   for(int i = 0; i <=  numeroDeReles - 1; i++)
       {
           rele[i] = HIGH;
           delay(50);
           escribe595();          
       }
}

/*
=============================================================================
*/

void escribe595()
{
/*
   Set and display 74HC595.
   Only call AFTER all values are set how you would like (slow otherwise)
*/
   digitalWrite(latchPin595, LOW);
   for(int i = 0; i <= numeroDeReles - 1; i++)
      {
          digitalWrite(clockPin595, LOW);
          int val = rele[i];
          digitalWrite(dataPin595, val);
          digitalWrite(clockPin595, HIGH);
      }
   digitalWrite(latchPin595, HIGH);
}

/*
=============================================================================
*/

void cambiaRele(int numeroderele, int valor0o1)
{
   rele[numeroderele-1] = valor0o1;
   escribe595();
      
/* MUST BE CALLED TO DISPLAY CHANGES                                       */
/* Only call once after the values are set how you need.                   */
}

Special thanks to Grumpy_Mike and Jobi-Wan for their help and, above all, for their enormous patience with me.

I am here again!

No very good news...

The code I pasted here one year ago works fine... but only when Arduino is plugged to the USB of the computer. Otherwise, the the relays go crazy... just like me, that I am going crazy too...

As a side note, 74hc595 outputs are only rated for 35 milliamps. I don't really understand the purpose of this circuit, but if it is powering the relays for an extended period of time you might want to drive it with IGBTs (transistors) Here is a circuit of how to set this up:

As a bonus it has a diode to attenuate the inductive spike. This will help preserve the transistor especially if it is turned on and off a lot.

Oops I forgot a 1k ohm resistor between the shift register and the IGBT.

No, driving the output of 74HC595 directly into the base of a transistor configured like that is a really bad idea. You need a base resistor.

Now your text speaks of using IGBTs . If that is what you intend then please use the right symbol.
Don't give me a lame excuse that Fritzing dosn't have the right symbol. If you are answering questions here do it like a pro and answer it properly, either make the symbol in Frtizing or ditch the pile of crap.

IGBT.png

IGBT.png

Mike, don't complain too much, at least NoraTD is using the schematic editor in Fritzing instead of the breadboard editor! I know how much you love those!

Anyway, who uses IGBTs to drive relays? What's wrong with BJTs or MOSFETs? Have we established if the OP is using a relay module with a transistor or opto-isolator rather than a bare relay? I can't remember.

Another mistake in NoraTD's schematic is the relay terminals shown connected. Hint: not the coil!

And the flyback diode is shorted out.