Picaxe and shift registers- controlling individual LEDs

rs2845

Senior Member
Hello all,

Almost reaching the end of the hardware and basic software development for the alarm system I am still building. My question is in relation to the control panel, namely the 22 LEDs for visual indication. There are 16 zone LEDs, 1 power LED, 1 Fire LED, 1 Fault LED, 1 Disablement LED, 1 Processor Fault LED and 1 Test LED.

Currently, I use a Picaxe 40X2 to control these LEDs which is a huge waste for such a powerful MCU. I've recently stumbled across shift registers and am wondering if they would fit into my system to drive these LEDs and take up less pins than the 22 currently being used.

When I switch the control panel on, the Power LED illuminates constantly, the other 5 (fault fire, disablement, test and processor fault) are only illuminated when an event on the system triggers them. When the panel communicates with the devices and encounters a fire condition, the panel looks up the activated devices address on the loop and will then retrieve the device label, zone label and zone number to display on the screen- the corresponding zone LED will then illuminate to indicate the fire condition from a further distance.


I know I'd need 3 shift registers (74HC595), taking 9 pins I assume (3 lots of clock, data and latch). Here are my questions:

1) Can I really power all 22 LEDs from just 5v? Or do I still need transistors?

2) With the 16 zone LEDs (focusing on the first chip controlling zone 1-8), if the zone 3 LED is currently illuminated, how could I illuminate the zone 7 LED on the same shift register? I wouldn't want to switch off the zone 3 LED. I'd say I would have to write the current command (%00100000) to a variable and then use setbit to change the value to %00100010. Is this correct? This would also apply to the other 6 generic indicators to switch them on individually.

3) Can I connect all three clock pins together and then all 3 latch pins? Meaning that I'd have 3 data lines, one clock and one latch on the picaxe.

Would love a little bit of clarification so I can buy some.
 

nick12ab

Senior Member
I know I'd need 3 shift registers (74HC595), taking 9 pins I assume (3 lots of clock, data and latch). Here are my questions:

3) Can I connect all three clock pins together and then all 3 latch pins? Meaning that I'd have 3 data lines, one clock and one latch on the picaxe.
Not necessarily. Pins can be shared e.g. you can have one pin for the clock, one pin for the data and three pins for the latches, then send the data for each shift register in turn, pulsing the latch for the relevant shift register afterwards.

1) Can I really power all 22 LEDs from just 5v? Or do I still need transistors?
You can because when many are on they will be wired in 'parallel' not 'series' because the shift register will connect each individual LED to 5V. However a switching regulator should be used.

2) With the 16 zone LEDs (focusing on the first chip controlling zone 1-8), if the zone 3 LED is currently illuminated, how could I illuminate the zone 7 LED on the same shift register? I wouldn't want to switch off the zone 3 LED. I'd say I would have to write the current command (%00100000) to a variable and then use setbit to change the value to %00100010. Is this correct? This would also apply to the other 6 generic indicators to switch them on individually.
Yes you would have to store the pattern for all 8 LEDs in the PICAXE, change bits as necessary, then send the whole byte to the shift register. You don't have to use the setbit command to do this.
 

rs2845

Senior Member
Not necessarily. Pins can be shared e.g. you can have one pin for the clock, one pin for the data and three pins for the latches, then send the data for each shift register in turn, pulsing the latch for the relevant shift register afterwards.
How would the three shift registers know which the data should be used by if the latch pin would control all three? :confused:

I don't mind having three data lines, then connect all the clocks and all the latches.


So just to confirm- I can achieve what I want!? I'll try source some now from Rapid or RS. Whichever is cheapest!
 

JimPerry

Senior Member
Why use shift registers when a pair of MCP23017 I/O expanders would give you upto 32 outputs for LEDs :confused:
 

rs2845

Senior Member
I'm still learning as I'm progressing with this project!!

I have no idea about half of the components people on here talk about, just like the one you mentioned.

The MCP23017 uses I2C, yet I can't find any examples of its use. Still reading the manuals.

I'm hoping to just use the 40X2, so I can address this MCP23017 so that I can use it on my i2c bus along with my EEPROM chips, right?

It looks horrible communicating with these. I've never used I2C apart from with an EEPROM, and even then, a picaxe helps with that!
 
Last edited:

nick12ab

Senior Member
Why use shift registers when a pair of MCP23017 I/O expanders would give you upto 32 outputs for LEDs :confused:
Why use a pair of MCP23017 I/O expanders when you can use three shift registers for upto 24 outputs for LEDs? Only 22 LEDs are needed, shift registers cost less and an MCP23017 has 28 pins so using them won't have any space savings.

Of course, the MCP23017 is better in many applications, particularly when I/O pins are limited and you want to use i2c. Since using them would not create any disadvantage I can think of to how well the system will operate, either using MCP23017 or shift registers should be fine and it's for the OP to decide.

How would the three shift registers know which the data should be used by if the latch pin would control all three? :confused:
The data you have clocked into a shift register only gets transferred to the output pins on the shift register when you use the latch pin to tell it to do so.

This means you can share the clock and data pins between many shift registers since the data won't be transferred to the output pins of any shift register until you use the latch, and with separate latches you can send the data for each shift register in turn.

I don't mind having three data lines, then connect all the clocks and all the latches.
Connect the datas together, the clocks together and use separate latches so that you can use the shiftout command to control the LEDs instead of having to use bit banging. You cannot use the shiftout command if you share the latches and use separate data connections because 0 will be clocked into the two shift registers you are not addressing at that time.
 

rs2845

Senior Member
Thanks nick12ab. Your help is much appreciated, I think I understand how it would work.

The only reason I am leaning towards shift registers is because I've seen others use them on the forum and YouTube.

But, I wouldn't mind having the MCP23017 because it may help with future expansion. @JimPerry- I don't really understand the data sheet commands so if you could perhaps try interpret how to switch on iodirA's io1,3,7 and the same for iodirB?

I don't know how to use i2c and I hate addressing the damn slave units.
 

nick12ab

Senior Member
But, I wouldn't mind having the MCP23017 because it may help with future expansion. @JimPerry- I don't really understand the data sheet commands so if you could perhaps try interpret how to switch on iodirA's io1,3,7 and the same for iodirB?

I don't know how to use i2c and I hate addressing the damn slave units.
Have you read all of the datasheet? It explains each register.

To write to a register, you simply use hi2cout register_address(value).

Also read Using i2c with PICAXE, which contains general information (only).
 

rs2845

Senior Member
I have read it but it is like a foreign language to me.

However- I was lucky enough to stumble across others who have used these (westaus55) with some very helpful code so I'm going to analyse it tomorrow on a fresh mind- I learn better from other people's code instead of datasheets generally.

I've ordered a few samples from Microchip so depending on how fast they are sent I will just use those, or I may buy some as I have other places which will eventually need lots of pins so they'll come in handy.

At least I know shift registers are a simpler option if this causes me grief.
 

westaust55

Moderator
The use of three 74HC595 shift registers is definitely a possibility.
If you use a smaller X2 part (ie the 20X2) then you have the inbuilt SHIFTOUT command available to you which is at least 4 times faster than bit bang methods required with the M2 parts.
Thus in using an X2 part you could keep the three shift registers in cascade (series) and only require three IO pins and still be faster to update the LED indication panel.

In this thread, I used three 74HC595 chips in cascade to drive 3 x 7-seg displays. Much the same to drive separate LED’s – just keep the data in three byte variables and resend as needed.
http://www.picaxeforum.co.uk/showthread.php?13687-3-digit-display-using-74HC595

As the MCP23017 has also been mentioned, I have also used these for several displays.
With the i2c interface they can readily be connected to any M2, X1 or X2 part and the data transfer will be faster. Also possible to address just one port of 8 pins at a time rather than needing to update all. With two MCP23017’s you will have a spare port which could be used for a keypad or any other IO requirements such as controlling sounders or flashing lights (via transistors) allowing the controller to potentially be a much smaller PICAXE chip.
3 x 74HC595’s has a total of 48 pins, versus 2 x MCP23017 having a total of 56 pins but you are getting 8 extra bi-directional IO.
Have a look at some projects I have done in the past with these chips:
http://www.picaxeforum.co.uk/showthread.php?12531-MCP23017-i2c-IO-exapander-data
http://www.picaxeforum.co.uk/showthread.php?10836-Looking-for-RGB-LEDs-in-Australia/page4&highlight=MCP23017
 

Michael 2727

Senior Member
Just a side note.
When playing with a Lot of LEDs, say 10+ or so.
Take into account the Power requirements you may need.
It can easily add up. For both the Main Power Supply and
the Register Outputs and or Sundry components etc.
E.g. 20 LEDs @ 20mA = 400mA
2c worth.
 

rs2845

Senior Member
Okay, finally had time to get some shift registers onto my breadboard.

I've managed to get them working to control all the LEDs on a single chip, but I'm not sure how these are going to help me switch on individual LEDs when I need them to be illuminated.

Remembering that this is a 16 zone alarm, there's 16 LEDs (one for each zone) and then 6 further general indicators.

Zones 1-8 are on Shift Register 1
Zones 9-16 are on Shift Register 2
General Indicators are on Shift Register 3

I have one global clock and data pin but individual latches.

If say zones 3, 9 and 14 go into 'alarm' at the SAME time how would I even go about illuminating the respective LEDs? And then if there was another alarm say on zone 10 how would I illuminate that LED without affecting 3,9,14? I have no idea how to even tackle this.

Luckily I planned ahead and ordered some MCP23017's because I had a feeling that these shift registers would cause hair loss and stress once again.
 

g6ejd

Senior Member
I'm intrigued to know how your going to implement a process fault LED, if it's normally on and the processor has developed a fault, how will it get switched on?

You could use a mono-stable that is continuously triggered so it never times out, then the moment the processor fails (it does not provide a reset trigger input), then the LED comes on.

You could reduce the LED count by at least two, or use 7-segment displays, one for status and one for Zones, many alarms use the hexadecimal nomenclature for zones, e.g. 0-9 A to F or use a dot-matrix LED display to give even more flexibility.
 

rs2845

Senior Member
The 22 LEDs just provide at a glance indication without logging in. It has a 5.6" colour touchscreen display to provide detailed info and controls for the system. The panel controls a series of devices which are polled by the control panel and then they report back their status, the panel decides what to do based on the results and if necessary, orders the devices to trigger their inbuilt voice sounders and beacons. It's getting there slowly!

The 6 general indicators are Fire, Power, Fault, System Fault (indicates a Picaxe processor error(power failure)- controlled by another separate circuit), Disablement and Test. With regards to the Fault LED, when a device reports back corrupt/specific commands that are due to internal faults then the panel counts this and switches the screen over to 'active events' where details are shown. Same with the rest.

For now I have the Sys Fault LED on the third shift register but once I add the other circuitry I can get that running properly. However, using an 08M2 for that and a buzzer is a bit wasteful. Your idea sounds interesting, does it use a 555 timer? I'll handle that last. The other LEDs are more important.

I really need individual control of these LEDs and I don't think shift registers are going to let me have that. I don't know where to start with them!
 
Last edited:

westaust55

Moderator
Whether using shift registers or i2c IO expanders you have to present a byte (= 8-bits) to each register/port.
You will need to use three of the lower bytes b0, b1 and b2 for the Individual bit variables where each bit gives you a high (=1) or low state possibility. Then whenever ther is a need to change you send all three bytes in the case of the shift registers or 1 byte in case of MCP23017 to update the entire group of outputs involved.

This is where you need to spend some time to experiment and understand how the chips work before you write any final code. Look at and start with the example code in PiCAXE manual2 under the SHIFTOUT command as the basis of shifting a byte (8-bits) and later more data for sending data to your shift registers.
 
Last edited:

rs2845

Senior Member
Hi all,


So I've been working on trying to get 2 MCP23017's working with a Picaxe 40X2 to control 32 LEDs. Bit more elegant than the 74hc595's, and they were free!

I've had a go at trying to get these working with the examples linked below but as always with most threads on the net- the code is for a specialist purpose.
Difficult example 1
Unclear example 2

After lots and lots of tinkering I managed to get them working but like an idiot I saved the wrong code file as I had about 6 PE windows open at once. My fault really.

Is someone able to provide a very simple initialisation sequence to set ports A and B as outputs and simply flash them? I've tried finding the example online and I can't seem to get it working again which is frustrating. I have 3 devices on my i2c bus. One EEPROM and the MCP23017's. EEPROM works 100%.


Addresses for A2-A0 are:


24LC512- 000
MCP23017 (1)- 001
MCP23017 (2)- 010


Code:
hi2csetup i2cmaster,%01000010,i2cslow_16,i2cbyte '
hi2cout [%01000010],0,($00,$00)
hi2cout 8,($00,$00)
 

Rick100

Senior Member
I think this code in post 13 is a simpler example of setting up the ports .
http://www.picaxeforum.co.uk/showthread.php?8260-XBee-wireless-with-I-O-expander-schematic/page2
It sets portB as all ouputs:
writei2c $01,(%00000000) 'All IODIR(B) = Output

and portA as all inputs:
writei2c $00,(%11111111) 'All IODIR(A) = Input

To change portA to all outputs use:
writei2c $00,(%00000000) 'All IODIR(A) = Output

The writes to registers IOCON(A) and IOCON(B) may not be necessary . The example uses older i2c commands but I think it will still work . You can change them to newer commands if it works . You can try this code . It's based on the code in the above link . It sets both ports of the first chip to all outputs and sets each pin high in sequence .

Code:
pause 500
i2cslave %01000010,i2cslow,i2cbyte 'Communicate chip1
writei2c $0A,(%00000000) 'Set IOCON(A) Bank = 0
writei2c $0B,(%00000000) 'set IOCON(B) Bank = 0
writei2c $00,(%00000000) 'All IODIR(A) = Output
writei2c $01,(%00000000) 'All IODIR(B) = Output

main:
b1 = 1
for b2 = 0 to 7
	writei2c $12,(b1)	'GPIO(A)
	writei2c $13,(b1)	'GPIO(B)
	b1 = b1 * 2
	pause 1000
next
goto main
Good luck,
Rick
 
Last edited:

rossko57

Senior Member
If say zones 3, 9 and 14 go into 'alarm' at the SAME time how would I even go about illuminating the respective LEDs? And then if there was another alarm say on zone 10 how would I illuminate that LED without affecting 3,9,14? I have no idea how to even tackle this.
I expect you've worked it out by now, but one simple approach is to keep an _image_ of what you want in the Picaxe. 16 bits is one word. Have your set/unset LEDs routines update only their bit in the image word. Roll out the whole image to the real LEDs peridically - just like you poll your input devices.
 

westaust55

Moderator
You should also not that with the MCP23017 set in the right mode that the same/corresponding registers for the two 8-bit ports are consecutive. See how the code snippet Rick provided has locations $12 and $13 for data to the output ports.
That enaes you to send the two data bytes in one i2c write command saving time and program space.
 
Top