Zonnestroompanelen in Nederland

duurzaamheid achter de meter

(25) Blinking the leds on two common-anode 8-led bars

Summary
Leds can be controlled by an Arduino in several ways, for instance directly in a one led – one pin configuration, via arrays or indirectly, with only three pins with a shift register chip as intermediary element. This paper discusses the construction of a configuration on a prototyping board consisting of an Arduino Nano, two shift registers and two 8-led bars. These bars are Chinese gadgets with a common anode. The paper starts with a ‘classical’ design consisting of wiring that connects each individual led with its own Arduino pin

Introduction
Stocked deep in a drawer I discovered a couple of forgotten 8-led common anode bars that I bought a long time ago to serve some Christmas illumination project. Led bars are interesting devices serving useful applications such as indicating dynamically changing sound or power levels. In web shops these items are sold under a peculiar label, ‘water flow bar’.

Figure 1. Common anode 8-led ‘water flow’ bar unit, made in China.

With individual leds power is supplied to the anode while the led’s cathode is via a resistor connected to GND. On the device shown in figure 1 a pin marked GND is missing. Because of that, and also because a pin is present marked VCC, I suspected that we deal here with a common anode device and that the pins marked LED1 through LED8 are the cathode pins. Two questions came up in my mind, first, can I control the individual leds of this device with an Arduino connected via ‘classical’ wiring, that is each led through its own dedicated Arduino pin, and second, can I control this device via a shift register. Shift registers can be programmed to deliver HIGH and LOW states at their output pins. While a HIGH state produces a current flowing from the shift register to the led, would a LOW state draw a current form the led to the shift register in this common anode design and by consequence make the led light up? Let’s try it out!

Classical design: pin to pin
Before getting involved into more complex designs using shift registers the simplest approach is to wire up the bars in the way every beginner is advised to do: connect each pin of each bar with an appropriate pin on the Arduino. Figure 2 shows the corresponding wiring diagram. An advantage of the common anode design is that a single voltage limiting resistor can be placed in series with the anode wire. The wires are not directly soldered to their pins on the bar but instead to pins on a socket cut to size from a large female pin header. As there are two led bars there are two sockets. On the Arduino pins D2, D3, D4, D5, D6, D7, D8 and D9 serve as sinks for the leds on bar 0 while pins D10, D11, D12, D13, A0, A1, A2 and A3 serve as sinks for the leds of bar 1. The red position on the socket is where the pin marked ‘VCC’ of the led bar should stick in.

Figure 2. Classical wiring diagram that includes two 8-led bars with common anode. One 220 Ω voltage limiting resistor is mounted in series with the anode wire.

In this design activity on the Arduino pins will let the leds blink only when these pins are configured as sinks. Pins should be set LOW to produce a current running through the leds, forcing them to produce light!

Electronics and supplies
1x Arduino Nano, 2x common anode 8-led bars, 1x 70×90 mm soldering board, 2x 9-pin female pin header, 1x 220 Ω resistor, wire, 4x M3 nylon spacer length 10mm.

Sketch: two_units_8_led_common_anode_classic.ino

// two_units_8_led_common_anode_classic
//
// two bars of 8 leds common anode
// each led has its own pin
// we use here pins D2 thru A2
// place a 220 ohm resistor between bar anode and 5V of the Nano to protect leds
// variables are blinkTime and delayTime
// by Floris Wouterlood – 1 December 2018
// this sketch is in the public domain

int j = 0;
delayTime = 25;
int blinkTime = 45;

void setup() {

for (j=2;j<19;j++){ // initialize digital pins
pinMode (j, OUTPUT);
}

for (j=2;j<19;j++){
digitalWrite (j,HIGH); // set pins HIGH = leds off in common anode mode
}
}

void loop() {

for (j=2;j<21;j++){
digitalWrite(j, LOW); // turn led on (LOW allows current to pass)
delay(blinkTime); // leave led on for a while
digitalWrite(j, HIGH); // turn led off by equalizing the voltage
delay(delayTime); // leave led off for a while

}
}

Result
After uploading the above sketch the leds blink one after another in a sequence from left (bar 0, led 1) to right (bar 1, led 8) and then the sequence starts again. The variables delayTime and blinkTime control the speed of the ‘movement’.
Note that pins need to be set LOW to produce a blinking led. Normally a pin is set HIGH to produce the voltage that makes a led light up. In a common anode design the wire to the led is in the HIGH state, so a digitalWrite (j,HIGH) instruction would put 5V against 5V thus not producing any voltage difference. No voltage difference over a led, no action!
The consequence of having a burning led on a digital pin set LOW is that such a pin on an Arduino acts as a current sink.
Would a shift register work also in this fashion? Why using shift registers at all?

Shift register design
The big advantage of a design including shift registers is that only three pins on the Arduino are needed, freeing other pins to be used for other functions. Shift registers together with the leds connected to them can easily be daisy-chained into repetitive units which makes it possible to create strings of leds much, much longer than a two-bar with a modest eight leds. Thanks to the existence of shift registers the creation of even a 3D led cube is within reach. So let us look in detail at a shift register. In the Arduino world a chip called 74HC595 is very popular. This chip is a cheap, simple and versatile eight-bit device.

Basics and schematic wiring
Figure 3 shows a 74HC595. Three of the Nano’s output pins are necessary to control this chip: data, clock and latch. Note that the ‘data’ connection is from the Nano to pin SI (Serial In) of the shift register. From pin QH’ of this chip a data link wire connects to pin SI of the next shift register. Concatenation is only done for the serial data line: The two other connections involved: ‘latch’ and ‘clock’, are distributed parallel (pin RCK receives the latch signal and pin SCK receives the clock signal). A terminator on pin QH’ of the second shift register is not necessary, which renders this pin available for linking to yet another shift register.
One 74HC595 chip has eight output pins (QA through QH) available to drive an equal amount of leds. Thus only three pins on a Nano can be used to govern in this case eight leds, and with more shift registers potentially an endless chain of leds.

Figure 3. A 74HC595 shift register and its pin layout.

Shift register design
As there are two led bars there should be two shift registers. To have reliable connections I planned the entire configuration to be soldered onto a board, with the Nano and the led bars stuck into sockets made of female pin headers. The shift registers might be soldered directly onto the board, but it is much more elegant to mount them on DIP sockets. For this project I selected a 70 x 90 mm double-sided soldering board with sufficient holes (31 x 26) to accommodate the design. The wiring diagram is shown in figure 4.

Electronics and supplies
1x Arduino Nano, 2x 74HC595 shift register, 2x common anode 8-led bars, 1x 70×90 mm soldering board, 2x 9-pin female pin header, 2x 15-pin female pin header; 2x DIP16 socket, 2x 220Ω resistor, 1x 0100 nF capacitor, wire, 4x M3 nylon spacer length 10mm.

Figure 4. Layout and wiring of the PCB with one Arduino Nano, two 74HC595 shift registers (A and B) and two sockets that will hold the 8-led bars. The 220 Ω resistors protect the shift registers by limiting current flow from the leds. The 100 nF capacitor suppresses noise (not really necessary in a two-shift register configuration). The data line is wired serially; clock and latch are wired parallel. The arrows on the shift registers point to the top notch.

Construction of the board
In previous projects I used insulated 24 AWG (diameter 0.5 mm) solid copper wire for the wiring. In an application with shift registers which draws 14 mA on each pin (see Discussion) wire with this thickness amounts to overkill. I wired up for that matter the shift registers with much thinner 28 AVG wire (diameter 0.3 mm) and used the 24 AWG wire for the 5V, common anode and GND connections. Figure 5 shows the result. Here the two shift registers have already been placed in their final position in the DIP sockets. On the corners of the board a nylon spacer was mounted to protect the delicate wiring from mechanical damage. On the bottom view the wires with different diameter can easily be distinguished. Here, the same color coding has been used as in the schematic wiring drawings.

Figure 5: Top and bottom views of the completely wired soldering board. The shift registers are already in place in their DIP sockets. The testing phase can be started once the Nano and the led bars have been placed on their pin headers.

Sketch: two_units_8_led_common_anode_74HC695.ino
The sketch first defines the pins used for the data, clock and latch functions, then the two variables are declared that govern blinking: delayTime and blinkTime, and finally an array is created that holds the values of the output pins of the shift register, i.e. the pin numbers to which corresponding leds are attached. In the main loop a subroutine is called, “run_ledstrip()”. This subroutine does the main job, while it outsources writing to the shift registers to another subroutine, “writeRegister()”. Note that HIGH and LOW for clock and latch signals are as usual while only data LOW and HIGH are reversed compared to settings applied usually with shift registers. In this sketch, the ‘data’ LOW instruction forces the output pin on the 74HC595 to become 0V (i.e., equal to GND) in order to create a sink that makes a current flow through the connected led.

// two_units_8_led_ common_anode_74HC595
//
// two bars of 8 leds common anode
// two 74HC595 shift registers
// each shift register controlling one 8-led unit with common anode
// this sketch lights led after led over the entire 2 x 8 = 16 led bar
// data pin = D11
// clock pin = D12
// latch pin = D8

// by Floris Wouterlood
// public domain
// so use it freely and have fun
// December 1, 2018

int pinval = 0;
int datapin = 11;
int clockpin = 12;
int latchpin = 8;
int delayTime = 25;
int blinkTime = 45;
int ledstrip_array [16] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15}; // there are 16 leds on two bars

#define n_pins 16 // declare here the total number of 74HC595 pins plus one
boolean registers [n_pins];

void setup(){

pinMode (datapin, OUTPUT);
pinMode (clockpin, OUTPUT);
pinMode (latchpin, OUTPUT);
clearRegisters(); // reset all register pins
writeRegisters();
}

void loop(){

run_ledstrip ();
}

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

void run_ledstrip (){

for (int i=0; i<16; i++){
pinval = ledstrip_array [i];
setRegisterPin (pinval, LOW); // LOW here because of common anode
writeRegisters();
delay (blinkTime);
setRegisterPin (pinval, HIGH); // HIGH here because of common anode
writeRegisters();
delay (delayTime);
}
}

void clearRegisters(){ // set all register pins to LOW

for(int i = (n_pins-1); i >= 0; i–){
registers[i] = LOW;
}
writeRegisters();
}

void writeRegisters(){ // set and display registers

digitalWrite(latchpin, LOW);
for (int i = (n_pins-1); i >= 0; i–) {
digitalWrite(clockpin, LOW);
int val = registers[i];
digitalWrite(datapin, val);
digitalWrite(clockpin, HIGH);
}
digitalWrite(latchpin, HIGH);
}

void setRegisterPin(int index, int value){ // set an individual pin HIGH or LOW

registers[index] = value;
}

Result
This sketch worked perfect using the same delayTime and blinkTime constants as in the classical sketch. During the development, refining and testing of the sketch I created also a version in which all 16 output pins of the shift registers were set LOW. This created lighting up of all leds (figure 6) while, fortunately, it did not fry the shift registers.

Figure 6: Working! One of the tests was to light all leds simultaneously, as shown here.

Discussion
The current project was undertaken to determine whether 74HC595 shift registers can be used successfully in combination with common anode 8-led bars. To my surprise setting the output pins of the shift registers LOW made the leds blink. This is a perfect result because it proves that common-anode devices are compatible with 74HC595 shift registers. Not every shift register available for the Arduino may offer both current sourcing and current sinking. For instance, the TPIC6C595 offers current sink only.
The 74HC595 is said to be a low power 8-bit chip. The Texas Instruments SN54HC595 data sheet mentions a maximum of 20 mA current per output pin at a total power consumption of 80mA. A 220Ω resistor in series and assuming a voltage drop of 1.9V over each led would limit the current running through each led to (5-1.9)/220 = 14 mA. All eight leds on a bar blinking simultaneously would draw 8×14 = 112 mA. The latter current is close to 50% higher than the maximum allowed current of 80 mA. The chips still worked after several 30-seconds ‘blink all’ tests shown in figure 6. This survival was in conflict with the prediction based on the data sheet. This made me to inspect the 8-led bar units again. They feature a curious black shiny upright strip marked ‘RP1’ (figure 1). A reconstruction of the wiring of the PCB of the led bar unit is shown in figure 7.

Figure 7. Reconstruction of the wiring of the led bar PCB. Pin VCC is wired to the first pin of a 9-pin RP1 (abbreviation for ‘resistor pack’ ?).

Apparently the RP1 unit is a pack of anode-connected resistors. I measured a resistance of 280Ω between the VCC pin and each of the RP1 output pins wired to the base of the leds. Thus, the accumulated resistance at the anode of each led is 280 + 220 = 500Ω. This value explains the shift register’s survival. Current running at 5V through a 500Ω resistance, and taking a 1.9V voltage drop at the led into account is (5-1.9)/500 = 6 mA. Eight of these currents (48mA) is well within the specifications of the 74HC595 (i.e., 70 mA max). The current design therefore can safely be used even with all leds lighting up permanently. Under normal working conditions with all kinds of combinations of leds blinking the shift registers will never be stressed beyond their datasheet limits. Conversely, the application of anode-connected resistors with values higher than 220Ω in the current project will only reduce the luminosity and not increase safety.
In other projects I applied also 74HC595’s (a 24-led ‘cyclotron’ and a 31-led ‘pyramid’ – both common cathode projects). In these projects I applied 560Ω resistors in series with the cathodes of the leds. The leds and the shift registers here also never gave problems.

Sketches
two_units_8_led_common_anode_74HC695.ino
two_units_8_led_common_anode_classic.ino

These sketches can be downloaded here (zipped)