Apr 182014
 

Today we’ll see how connect many 12V relays to Arduino board. The most visited article of this blog is the first one on connecting a 12V relay. Please read it for a refresh of the basic information. Please remember that here is a useful online calculator to calculate the resistor value at the base of the transistor. Today we’ll see the evolution of those items and we ask ourselves: how do we add other relays? And if I want to control 24 relays with a single Arduino can I do that? And if so, how? Now that we know what are the questions let’s start with the practice.

ULN2803

If we studied how to connect a single relay, we can easily expand it until up to 14,  the number of Arduino’s output digital ports, although to be honest we can also use the analogic ports to drive the transistors. If you remember, for each relay will serve a resistor, a diode and a transistor, in addition to the relay itself.

In the diagram above we see how even adding only 3 relays to the initial one, we have enough confusion with a significant increase of components and lines on the circuit. Let me be clear, this circuit is easily achievable, it is working and there is no particular reason to leave it out, if we exclude the number of connections  and the pcb overall size. But surely someone before me,  tried to reduce the repetition of this type of circuit and found a solution that can simplify our life. Yes, there are commercially available integrated circuits for our case: the ULN2803. What we can do with it? Simple, with a low cost single chip (<1€) we have eight independent channels already complete and ready for use, in the sense that it replaces, for each channel, resistor, diode and the transistor, also accepts voltages between 5V and 50V and loads up to 500mA per channel. The reality it a bit more complex than my usual simplification, but for the purposes of our article we just want to know that it can replace all of the components (excluding the relays) allowing currents up to 500mA per channel and voltages from 5 to 50V. The classic pinout is showed on the right side: we see that there are eight inputs and eight outputs, a ground and a power input pin. The connection is very simple, we have to connect the Arduino’s output pins to the ULN2803’s input pins, connect mass, power, and finally ULN2803’s output pins to relays.

The diagram is shown below: as you can see there is a considerable saving in components with obvious simplification of the circuit. Moreover, the fewest number of welds on the final circuit will determine a higher reliability of the same. Pay attention to the fact that the ULN manages activation or disconnection of the mass lines, not alimentation line. Another thing, I would point out, the masses of the Arduino and the external power supply must be joined together. For completeness, I put below a photo of a real working test on breadboard . You can see the connection of Arduino with the ULN and the latter with three relays. I have only three relays connected for reasons of practicality. On the right side of the photo you can see two crocodiles red and black, respectively, leading the VCC and ground of external 12V power supply.

But we can go over. Arduino has other free pins so we could add another ULN2803 to combine additional relays, even if we could not have advantage of all the outputs of the second integrated. But if we want to go over, for example by connecting 16 relays? Is it possible to do it? In fact, we might have the need to control 16 relays and the same number of inputs but at first glance it would seem necessary to use two Arduino boards because they do not have enough ports.

Shift Register 74HC595

The solution is the shift register, such as the 74HC595 which is a chip SIPO (Serial In Output Out). What it means? It means that it receives a serial input and provides a parallel output. Think about it. We already know what’s a serial transmission: a single character occupies 8 bits that are sent serially. A single byte may indicate the status of up to 8 outputs. The concept is just that. The individual bits are sent to the shift register, going in the eight memory cells of the shift register until the completion of the received bits

The first bit arrives into the shift register and it’s put in the first memory cell. When the second arrives, the first one will be shifted in the adjacent cell, and the first cell will be occupied by the new bit and so on until the end of the data. At this point, for completeness, we need to specify that there are two large families of shift registers, with or without latch. The latter, while they bits arrives, sets the corresponding outputs, while the others expects an additional “latch signal” to copy the data from the cells of the shift register in the appropriate cells of memory (storage) that activate or deactivate the various outputs. Obviously, we can not use a shift register without latch to control for example relays. Let’s take a simple example. If we send a first bit equal to 1 if the shift register that has not a latch mechanism, it is activated immediately. When a second bit equal to 0 arrives, the previous moves to the second cell memory turning on the second relay and turning off the first one (new bit is equal to 0). In this way we have a series of “switch on” and “switch off” as long as the data is not completed. This type of chip is therefore indicated when the target reads the output only when all the data has reached its destination , as the case may be of some LCD display, a topic that we will see in the future. If our chip has a latch mechanism we simply send the data and then provide a signal to copy the memory cells in the corresponding outputs . Some chips have a 74HC595 latch as the second activation mechanism , in fact, in addition to copy the memory cells as just seen , have a so-called enable pin ( OE : Output Enable ) which if not activated doesn’t permit the outputs abilitation even if the memory cells of the shift register are copied into the storage register ( latch ). Now we are going to investigate what has been said, the details that allow you to send the data in the cells of the shift register , copy them to memory storage latch and then set the outputs of the 74HC595 . Let’s see one by one the various pins of the 74HC595 chip.

DS (Serial Data) is the pin to which we send the incoming serial bits. Note one important thing. The first bit goes in the first memory cell, but then with the insertion of the second bit, the first one will be shifted (moved) in the second cell and so forth. Once inserted the eighth bit, the first bit inserted will be in position number 8, the second in position 7, and so forth. It is understandable, therefore, that we need to send the data in reverse, starting from the last to arrive at the first. ST_CP (also called latchPin) and SH_CP are respectively the STorage and the SHift clock pin. The shift is used to shift bits in the memory cells, instead the storage, when activated, copy the memory cells in the  latch storage. Their function is carried out when the signal in their pin goes from LOW to HIGH.

So in summary , we set out the DS using the bit value (LOW or HIGH). Once you’ve done we set th SH_CP to HIGH so our bits flowing inside of the memory cells. When we want to copy the values ​​of the cells of the shift register in the storage register, we set ST_CP to HIGH. OE (Output Enable) enables the pins when the signal is LOW. Therefore when the OE signal is LOW the contents of the storage register is transferred to the output pins , determining the opening or closing according to the stored values​​. Q0 – Q7 are the outputs: Note that Q0 is located on one side and the others on the other side , also note that Q0 is the first output Q7 and the eighth . Q7 has a different function, we’ll see after that, but it’s used to connected more then on 74HC595 togheter. GND and Vcc (3 to 5V) need no introduction. MR is the master reset that resets all outputs when the signal is LOW which is why we connect the +5 V (we do not want that remains perpetually zero) . Note: It is recommended to use a 1microfarad capacitor between the  ST_CP and ground. Now that we have the necessary information, lets see the schematic I propose below :

Obviously the outputs of ULN2803 must be connected to the relays (in the schematic there are couples of connectors 12V/Gnd instead the real relays) . Some notes : as you see the MR is directly connected to +5 V for this the outputs are never reset. OE is grounded , this means that when we store something  in the storage register its content is directly reflected on the outputs. Obviously if OE is grounded , we must necessarily control directly the ST_CP to decide when to copy the cells of the shift register in the storage register . In the end you can see that with only 3 pins of the Arduino we are able to drive 8 relays, but the good news is that we can combine more than one 74HC595 in series to go to 16,24,32 or over outputs simultaneously. To do this we simply connect Q7′ to the DS of the next chip. In the diagram below I show you how to do it. You can connect more than two chips in cascade.

Now you ask, where is the catch? The answer is speed, but only theoretically in our case. In fact, for comparison, our Arduino run at 16MHz while to these chips from 57 to 100MHz (there are several models), which may change the state of the shift register tens of thousands of times per second. It must be connected really many before being able to perceive a slowdown humanly recognizable. I did a test with 8 LEDs in place of the relay to turn on in series from top to bottom and then resume, removing any kind of delay, the speed is such that the LEDs seem to always on, you can not see with your eyes brightness variation. Even with 16 LEDs is not possible to distinguish by eye the timing of the lighting on and off.

One important thing that I forgot to say is that the outputs of the 74HC595 have a voltage equal to the source voltage (typically 5V but also works to 3) with a current that is lower than that of the outputs of the Arduino, typically 20mA . To be honest , you can use mixed artifices between hardware and software to reduce further the number of pins of Arduino, the downside is a further reduction in speed and an increase in the complexity of the software, but in some cases it may be an option to take into consideration , especially if instead of using Arduino, we use chips with a smaller number of pins (such as the ATtiny85) or there is the need to save pins for other uses. A typical case is the use of LCD in which there isn’t a need for real-time refresh , maybe in the future I might write an article about it because it’s a technique I’ve never tried and it might be interesting to compare it to the more classic schemes.
Now that we have seen the hardware we have to see the software that is actually very simple .

const int latchPin = 12;  //Pin connected to latch pin (ST_CP) of 74HC595
const int clockPin = 11;  //Pin connected to clock pin (SH_CP) of 74HC595
const int dataPin = 13;   //Pin connected to Data in (DS) of 74HC595

void setup() {
  pinMode(latchPin, OUTPUT);
  pinMode(dataPin, OUTPUT);  
  pinMode(clockPin, OUTPUT);
}

void loop()
{
 for (int i=0;i<8;i++) 
 {
  digitalWrite(latchPin, LOW);
  shiftOut(dataPin, clockPin, MSBFIRST, 1<<i);
  digitalWrite(latchPin, HIGH);
  delay(90); 
 }
}

With this code you will see the LED or what connected to the outputs, get open in sequence: first turn on, it turns off; then second turns on, it turns off, then the third turns on and so on. This source code manage the first 8 outputs, but take attention: When we sent the 8 bits, all memory cells of shift register are occupied. At this point, when we move to a new cycle and send a new bit , the last value the cells of the shif register go to Q7′ and then , if there are additional shift register connected in cascade , it will end in the second integrated. In fact what happens is that, sending always the same bit sequence, the two shift registers have outputs arranged in the same manner for which they form a kind of copy. The list above is very simple. First three constants are defined to store the number of pin used by 74HC595, this step is not mandatory, but it allows us to easily modify the list if we decide to modify the hardware. In the setup the pins are set as outputs. Then you go to the main loop where we inserted a for loop that switch on (or off) every single LED at a time. First of all we set the latch line to LOW, then we’ll do the shift using the Arduino’s shiftOut function. Last operation is to set the latch line HIGH to copy the shift registe bits to the real outputs. Remember that OE is always connected to ground so you do not have to worry about it from a software point of view. ShiftOut function takes as parameters the pin where to send serial data , clock SH_CP and two other parameters. The first one can be set to MSBFIRST or LSBFIRST , that indicates whether to send the data byte from the most significant bit or the less significant bit depending on how we made the hardware connections and how we want to use the software. The last parameter concerns the byte to shift inside the 74HC595. Remember you must use values between 0 (all outputs off) to 255 (all outputs on), using binary logic.

I used 1 << i which is the equivalent of 2 raised to i, so initially is 2 to the 0, which is 1 (only first output open), and then becomes 2,4,8,16,32,64 to finish 128. If trivially we sum these values, in case you have problems with binary math, you get the switch on of the correspondent outputs. The ShiftOut instruction sends only one byte at a time, so if for example you have two shift registers, you should use the function two times in succession. Please remember that the first byte goes to last shift register of the chain.

const int latchPin = 12;  //Pin connected to latch pin (ST_CP) of 74HC595
const int clockPin = 11;  //Pin connected to clock pin (SH_CP) of 74HC595	 
const int dataPin = 13;   //Pin connected to Data in (DS) of 74HC595	 	
void setup() {	 	
  pinMode(latchPin, OUTPUT);	 	 
  pinMode(dataPin, OUTPUT);  	 	 
  pinMode(clockPin, OUTPUT);	 	
}	 	
void loop()	 
{	 	
 for (int i=0;i<8;i++) 	 	
 {	 	
  digitalWrite(latchPin, LOW);	 	 
  shiftOut(dataPin, clockPin, MSBFIRST, 1<<(7-i));   // or shiftOut(dataPin, clockPin, LSBFIRST, 1<<i);	 	 
  shiftOut(dataPin, clockPin, MSBFIRST, 1<<i);	    // or shiftOut(dataPin, clockPin, MSBFIRST, 1<<i);
  digitalWrite(latchPin, HIGH);	 	
  delay(90); 	 	 
 }	 	
}
}

As you can see the difference from before is small, only the addition of the line that sends the data to the second shift register. In the picture you can see a a working prototype version with this software. In the lower part there are the two 74HC595 , in the higher the relative ULN280A . On upper side , the red LEDs connected to the positive terminal of the 12V with 560 ohm resistors . LEDs are used for convenience , instead the 12V relays . I hope that this article will be clear and I hope my bad english will be acceptable. If you have any questions please write to me, I remind you that you must be registered , and the first comment must be approved , which unfortunately I have been forced to introduce because of massive spam that goes in the comments .