Zonnestroompanelen in Nederland

duurzaamheid achter de meter

(13) Two ways to control a ten-segment led bar with an Arduino

by Floris Wouterlood – November 15, 2019

Summary
Led bars can be used for a variety of visual effects such as indication of sound volume, charge state of batteries, etcetera. Here we deal with a simple monochrome 10-segment led bar. The simplicity of this bar lies in the fact that it consists of a parallel series of leds embedded in a plastic block. The simplicity is expressed by the absence of controlling chips. As a consequence a 10-segment bar has 20 pins: a row of 10 anodes and a row of 10 cathodes. In the present paper we discuss two ways of wiring a led bar with an Arduino. The most straightforward way is pin-to-pin wiring. As this method takes ten pins of the Arduino a second method is illustrated that needs only three pins. Our assistant here is the 74HC595 shift register. The advantages of implementing shift registers is, first that the occupation of only three output pins of the Arduino leaves all other pins available for other input/output functions, and second that the 74HC595 makes it possible to daisy-chain endless series of led bars without much additional effort.

Introduction
Series of leds that, in programmable sequences, can be individually instructed to light up are an endless source of creativity, fun and practical application. Instructing leds to light up is easy to do with the Arduino family of microcontroller boards. The only drawback with the Arduino is that there are only 14 digital output pins which, together with the six additional analog pins (A0 through A5), restrict the number of directly programmable leds to 20. In that case no pin is left to receive input or to run another function. Apart from constructing led matrices or other tricks to control larger numbers of leds one can exploit shift registers. In this respect the 8-bit 74HC595 shift register is an ideal extension of the Arduino. For instance, this chip needs on the input side only three wires from the Arduino, while on its output interface it has 8 pins available to attach leds to. One very attractive feature of the 74HC595 is that it has one pin to drive the next-in-line shift register. In other words, these chips can be used to construct daisy chains in which each 74HC595 drives 8 leds. No matter the length of a daisy chain, only three pins on the Arduino will be required.

Figure 1. Top and bottom views of a simple 10-segment led bar. In top view of this bar each white stripe is an individual led. The bottom has two rows of pins. One has to establish by trial and error which row consists of anode pins and which row carries the cathode pins because there is no marking.

Let’s attempt to drive the simple 10-segment led bar shown in figure 1. It has 10 pins on each long side and it has no indication whatsoever which row contains the anode or cathode pins. To find that out we connected a pin on one row with a pin on an Arduino, the corresponding pin on the other row of the bar to GND. Then we set the Arduino pin HIGH (Arduino IDE, File  Examples 01. Basics  Blink). Blinking of the led indicates that the wiring has been done correctly. Cathode and anode rows of the bar are now identified.

Pin-to-Pin wiring
We use here an Arduino Nano because its small form factor allows to stick it on a prototyping breadboard. The wiring (shown in figure 2) consists of a tenfold repeated pattern: a wire runs from an Arduino pin to an anode pin of the bar; the corresponding bar cathode pin is wired via a 220 Ω resistor to the GND rail of the breadboard. Of course the GND rail is connected to the GND pin of the Nano. As simple as that. Pins D2 through D12 of the Nano were thus connected to the anode pins to drive the bar. A working prototype is shown in figure 3.

Figure 2. Pin-to-pin wiring scheme including an Arduino Nano and one 10-segment led bar.

Necessary parts
1x 10-segment led bar
1 x Arduino Nano
1 x breadboard
10 x 220 Ω resistor
jumper wires

Figure 3. Working prototype of a pin-to-pin wired monochrome (red) 10-segment led bar.

Sketch

The following sketch contains all the instructions to stepwise light all segments and after that the stepwise return to the off state.

// blink_led_bars_accumulate.ino
// led bar with 10 leds
// each led its own pin
// based on ‘blink’ example
// Floris Wouterlood
// 15 november 2019

int j=0;
int k=0;

void setup(){

for (j=2; j<13; j++);
{
pinMode (j,OUTPUT);
}
}

void loop() {

for (k=2; k<13; k++)
{
digitalWrite (k, HIGH);
delay (100);
}

for ( k=13; k>=1; k–)
{
digitalWrite (k, LOW);
delay (100);
}

delay (500);
}

Shift register wiring
In figure 4 a 74HC595 shift register is positioned in between the Arduino Nano and the led bar. The polarity of the shift register chip is indicated with a notch. To make it easier to identify the proper pins I made an extra mark with paint on the left upper corner of the chip.

Figure 4. A 74HC595 shift register positioned in between an Arduino Nano and the 10-segment led bar. Notice that one of this type of shift register can control only 8 leds. To control the entire bar we need two shift registers.

Shift register chips have 16 pins of which eight can be connected with anode pins of the led bar. Apart from 5V power supply and GND wires, three pins of the shift register need to be connected with the Nano: ‘data’, ‘clock’ and ‘latch’. These pins are indicated in figure 4. One shift register can drive only 8 segments of the led bar, so in order to drive all bars we need a chain of two shift registers, with only two output pins of the second chip connected with segments nrs. 9 and 10 of the led bar. Using multiple shift registers is possible because the 74HC595 brilliantly has one pin reserved for transmitting ‘data’ tot he data pin of the next shift register. This coupling can go on nearly indefinitely. The use of shift registers therefore implies that we can control led bars placed in series. In this paper we wire two shift registers with the led bar (figure 5). Data is connected in series; clock and latch are wired parallel. It is as simple as that.

Figure 5. Wiring diagram including an Arduino Nano, two shift registers and the 10-segment led bar. Note that in between the two shift registers the ‘data’ line (green) is in series while ‘clock’ (yellow) and ‘latch’ (magenta) are wired parallel.

Necessary parts
1x 10-segment led bar
1 x Arduino Nano
2x 74HC595 shift registers
2 x breadboard
10 x 220 Ω resistor
jumper wires

Figure 6. Working prototype of a two shift register wired monochrome (red) 10-segment led bar. Note that only three control wires run from the Nano to the first shift register: ‘data’ (green), ‘clock’ (yellow) and ‘latch ‘ (orange wire).

Sketch
The following sketch contains all the instructions to light the segments in a ‘ladder’ fashion: the segments light up each after another, running up the ladder and then down.
Note here that pin designation of the Nano is in software, so there is much flexibility of choice here when the led bar is used in a sketch in which several pins of the Arduino are reserved for particular input or output functions. The pin designations used in this paper are those used conventionally in sketches with the 74HC595 in Arduino designs. Data, latch and clock pin declarations can be found in the declaration section of the Arduino sketch.

// blink_led_bar_74HC595_up_down.ino
// sketch for a 10-pins led bar using two 74HC595 shift registers
//
// modification of a sketch by stevenart
// by Floris Wouterlood
// public domain
// so use it freely and have fun
// November 15, 2019

int datapin = 11;
int latchpin = 8;
int clockpin = 12;
boolean registers[10];

void setup() {

pinMode(datapin,OUTPUT);
pinMode(latchpin,OUTPUT);
pinMode(clockpin,OUTPUT);
writereg();
}

void loop(){

leds_go_up();
delay(500);
leds_go_down();
delay(500);
}

// ============== subroutines =====================

void writereg() {
digitalWrite(latchpin, LOW);
for (int i = 10; i>=0; i–)
{
digitalWrite(clockpin, LOW);
digitalWrite(datapin, registers[i] );
digitalWrite(clockpin, HIGH);
}
digitalWrite(latchpin, HIGH);
}

// ============== leds go down ====================

void leds_go_down () {
for (int i=0; i<10; i++)
{
registers[(i)] = HIGH;
writereg();
delay(10);
registers[(i)] = LOW;
writereg();
delay(10);
}
}

// ============== leds go up =======================

void leds_go_up () {
for (int i = 10; i>=0; i–)
{
registers[(i)] = HIGH;
delay(10);
writereg();
registers[(i)] = LOW;
delay(10);
writereg();
}
}

Discussion
Controlling leds in a 10-segment led bar can easily be performed with a simple pin-to-pin wiring. This works fine, the sketch is simple and straightforward and does not need any library to compile. Pin declaration is simple: pin number, OUTPUT. The only disadvantage is that ten pins on the microcontroller board need to be reserved for the led bar, which leaves a modest number of pins on the Arduino available for input/output and communication purposes. The number of pins on an Arduino is insufficient to drive in this way more than two of these led bars. Help comes in the form of the 74HC595 shift register. This chip is very popular in the Arduino world to drive scores of leds, led matrices, led bars and devices like 7-segment led displays. The popularity of the 74HC595 shift register chip is caused also by its affordability. Their 8-bit design supports only eight leds per chip. Fortunately it is very easy to connect 74HC595s in series.
It should be kept in mind that the chip manufacturer warns that output power of one 74HC595 may not exceed 70 mA. With all eight pins connected to leds firing simultaneously this means that in this ‘full power’ scenario each pin may not draw more current than 70/8 = approximately 9 mA. One single pin firing solitarily may not draw more current than 35 mA. We need therefore for each output pin a current limiting resistor to keep the power load of a 74HC595 in the safe range. Various publications and forum discussions focus on the value of this current limiting resistor. This has to do with the allowed current load of the 74HC595 shift register. Reported resistor values vary between 220 and 560 Ω. Obviously, at a ‘standard’ 220 Ω the current drawn from the shift register’s pin is about 18 mA. This current is not a big problem for the chip since it can handle 70 mA with each pin allowed a maximum of 35 mA. Problems may arise when for instance all eight leds connected to one shift register chip are lighted simultaneously. With 220 Ω resistors this would cause 8×18 mA to be drawn (144 mA) which overloads the shift register with a factor 2. Conversely, a resistor in the 400-500 Ω range may be sufficient. The disadvantage of high-resistance resistors is that the bars in the 10-segment bar light up rather dim. In the current prototype I maintained the 220 Ω resistor while in final designs I intend to use higher value resistors. A cautious constructor prefers a robust end product that lasts long.

Finally there is the issue of noise. In shift registers a lot of switching is involved. This switching is done by setting the clock pin on the chip ‘high’ and ‘low’. A 74HC595 has eight registers that each hold one bit (a ‘0’ or a ‘1’). Each time the clock ‘ticks’, the bit in each register is moved to the next register. Shifting needs to run smoothly which is done via fast and tight clocking. The more shift registers are lined up in a chain, the more critical accurate timing becomes. Switching noise can be reduced by adding decoupling capacitors in the design between the 5V and GND pins, preferably one capacitor for each shift register chip. Discussions in forums about shift registers often go at length whether and where to solder one or more these decoupling capacitors. Experts suggest to use one 100 nF capacitor for each shift register, mounted between the 5V and GND pins. Because we operate the current design with only two shift registers it is not critical to complicate the design by including one capacitor per shift register. However, when more than two shift registers are placed in series the application of one 100 nF capacitor per shift register is recommended (100 nF between 5V and GND).
While the 74HC595 can be considered a good and cheap companion to an Arduino a disadvantage of this chip remains its limited current load. If higher current loads are desired, a heavier chip like the high-current 595 driver chip such as the TPIC6C595 may be useful. These chips are less cheap than the 74HC595, while they are available in DIP16 version.