Looking for advice on shift registers

151 views
Skip to first unread message

Dylan Distasio

unread,
Mar 31, 2012, 6:28:55 PM3/31/12
to neoni...@googlegroups.com
Hi all-

I've been circling back to the nixie clock project I am working on that starts with a base kit of 6 IN-14s each with their own module that contains a PCB with a 74141 on it.  I have never used shift registers before, but finally got around to some initial experiments driving one 74HC595 with an Arduino connected to one set of 74141 inputs (ABCD) to keep things simple.  I was able to get the different digits lit up based on my code, but am wondering if I am missing something in terms of ease of use here.

I will need three 74HC595s if I go this route (6xABCD, 8 registers per 595 IC).  The techniques I had come across on the Arduino consisted of serially feed bits to the 595 until all 8 registers per chip were full.  It would seem like I need to send 24 bits each second as the clock ticks.  The fact that I have to do this serially one bit at a time seems like a pain in the neck.  Am I missing something (I'm sure I probably am) in terms of being able to set all 24 in parallel?

I'm hoping someone with more experience using arduinos and shift registers could provide some insights / tips.  I'm also open to hearing about how to use these from a uC agnostic perspective if noone on list is doing this with arduinos, but some code snippets would be ideal from the arduino perspective.

Thanks,
Dylan

John Rehwinkel

unread,
Mar 31, 2012, 7:00:12 PM3/31/12
to neoni...@googlegroups.com
> I will need three 74HC595s if I go this route (6xABCD, 8 registers per 595 IC). The techniques I had come across on the Arduino consisted of serially feed bits to the 595 until all 8 registers per chip were full. It would seem like I need to send 24 bits each second as the clock ticks. The fact that I have to do this serially one bit at a time seems like a pain in the neck. Am I missing something (I'm sure I probably am) in terms of being able to set all 24 in parallel?

It's a pain for the microprocessor, but so what? It shouldn't take it long to shift out 24 bits, even at a low clock rate.
A modern 74HC595 can accept data at a whopping 100MHz. At that speed, it would take a quarter of a microsecond
to send 24 bits. However, with an ordinary microcontroller, you aren't likely to be sending bits that fast. But you aren't
going to have to worry about outrunning your shift registers, that's for sure!

Hey, David - I think your nixie watch runs its CPU at 8kHz - how long does it take to shift out the 20 or so bits it uses to talk
to its two nixie tube drivers? I'm guessing less than 1/20 of a second.

You don't have to worry about your digits flickering wildly while the registers are being updated. In fact, it can be a
cool effect and help avoid cathode poisoning if you wanted to intentionally clock your data slowly enough to be seen,
and strobe your latches with the clock signal. If you want to make the update process completely invisible, just wait
until you've sent all 24 bits and then strobe the latches to update the displays.

The code to shift out 24 bits is not very complicated - just call the 8-bit version, once each for 3 bytes of data. You
could even arrange the bytes sequentially in RAM and iterate through them.

Some clocks (like B7971 clocks with individually addressible 16-segment tubes, or VFD clocks with dozens of
separate segments) shift out hundreds of bits every second or even more frequently. Yeah, the processor is
doing a lot of work, but so what? It's not like your clock CPU is doing protein folding with its spare cycles.

It only starts to matter when you're really trying to conserve power, and I don't think that's a logical goal when using
six direct drive tubes with six power-hungry TTL driver chips.

Alternatively, you could drive the shift register chips individually - run one I/O pin to all three data inputs, and use
three I/O pins for the clocks - one to each shift register. That way, you could choose which chip to update, and
you'd still only need four I/O pins. Normally this is done by paralleling both the clock and data input inputs, and
using a chip select or enable input to specifiy which chip you want to talk to, but the 74HC595 doesn't have a
chip select input, so you'd have to implement that yourself by gating the clock inputs, and using more I/O pins.

> I'm hoping someone with more experience using arduinos and shift registers could provide some insights / tips. I'm also open to hearing about how to use these from a uC agnostic perspective if noone on list is doing this with arduinos, but some code snippets would be ideal from the arduino perspective.

While I've worked with several different microcontrollers over the years, and mostly use AVR these days, you're right -
the concepts aren't processor specific. Some microcontrollers have hardware support for sending serial data in various
formats, but as long as you can individually control two I/O pins, you can talk to all sorts of things. Getting the data
transmission to work at all can be annoying, but once it works, it tends to be extremely reliable, and you can safely
hide the details in a subroutine you simply call whenever you want to send something.

I've used a 36-bit DSP chip with no concept of bytes or bits, just its weird 36-bit words, to implement the Dallas
"1 wire" serial protocol. It was kind of hairy to do, but it worked.

In short, I'd just send all 24 bits once every second, updating all six driver chips. If there's a transmission glitch, one
digit will be wrong, but since all digits are updated every second, it won't be wrong for more than that second. If
you're getting frequent glitches, there's probably something wrong with the wiring or the code talking to the shift registers.

>
> Thanks,
> Dylan
>
> --
> You received this message because you are subscribed to the Google Groups "neonixie-l" group.
> To post to this group, send an email to neoni...@googlegroups.com.
> To unsubscribe from this group, send email to neonixie-l+...@googlegroups.com.
> For more options, visit this group at http://groups.google.com/group/neonixie-l?hl=en-GB.

David Forbes

unread,
Mar 31, 2012, 7:48:10 PM3/31/12
to neoni...@googlegroups.com
On 3/31/12 3:28 PM, Dylan Distasio wrote:
> Hi all-
>
> I've been circling back to the nixie clock project I am working on that
> starts with a base kit of 6 IN-14s each with their own module that
> contains a PCB with a 74141 on it. I have never used shift registers
> before, but finally got around to some initial experiments driving one
> 74HC595 with an Arduino connected to one set of 74141 inputs (ABCD) to
> keep things simple. I was able to get the different digits lit up based
> on my code, but am wondering if I am missing something in terms of ease
> of use here.
>
> Thanks,
> Dylan

Dylan,

A clever programmer will figure out how to use the Arduino's SPI port
with the 74HC595s to eliminate all the software work of banging out the
bits. I've never used an Arduino, so I don't know how it's done. I've
used this chip with the PIC SPI port, and it works.


--
David Forbes, Tucson AZ

Adam Jacobs

unread,
Mar 31, 2012, 9:02:50 PM3/31/12
to neoni...@googlegroups.com
Yep, if you're trying to bit-bang the SPI then you are definitely re-inventing the wheel. Look at Arduino "sketches" for other SPI devices and see how they do it there. I don't have any arduino experience so I can't be of much help either, but I've used the SPI port on the AVR many many many times and it's a breeze.

-Adam

--
You received this message because you are subscribed to the Google Groups "neonixie-l" group.
To post to this group, send an email to neoni...@googlegroups.com.
To unsubscribe from this group, send email to neonixie-l+unsubscribe@googlegroups.com.

Dylan Distasio

unread,
Mar 31, 2012, 9:10:12 PM3/31/12
to neoni...@googlegroups.com
Thanks for the comments on the SPI, David and Adam.  I'll look into that approach.  I'm excited to pick up some new skills/tricks!

To unsubscribe from this group, send email to neonixie-l+...@googlegroups.com.

Cobra007

unread,
Mar 31, 2012, 10:09:42 PM3/31/12
to neonixie-l
I never used an Arduino before but this seems like all you need to
know about the SPI:

http://arduino.cc/en/Reference/SPI

The bit-bang method is still interesting to try things out as you get
to fully understand what will happen once you start using the SPI.

Michel



On Apr 1, 11:10 am, Dylan Distasio <interz...@gmail.com> wrote:
> Thanks for the comments on the SPI, David and Adam.  I'll look into that
> approach.  I'm excited to pick up some new skills/tricks!
>
>
>
>
>
>
>
> On Sat, Mar 31, 2012 at 9:02 PM, Adam Jacobs <a...@jacobs.us> wrote:
> > Yep, if you're trying to bit-bang the SPI then you are definitely
> > re-inventing the wheel. Look at Arduino "sketches" for other SPI devices
> > and see how they do it there. I don't have any arduino experience so I
> > can't be of much help either, but I've used the SPI port on the AVR many
> > many many times and it's a breeze.
>
> > -Adam
>
> > On Sat, Mar 31, 2012 at 4:48 PM, David Forbes <dfor...@dakotacom.net>wrote:
>
> >> On 3/31/12 3:28 PM, Dylan Distasio wrote:
>
> >>> Hi all-
>
> >>> I've been circling back to the nixie clock project I am working on that
> >>> starts with a base kit of 6 IN-14s each with their own module that
> >>> contains a PCB with a 74141 on it.  I have never used shift registers
> >>> before, but finally got around to some initial experiments driving one
> >>> 74HC595 with an Arduino connected to one set of 74141 inputs (ABCD) to
> >>> keep things simple.  I was able to get the different digits lit up based
> >>> on my code, but am wondering if I am missing something in terms of ease
> >>> of use here.
>
> >>> Thanks,
> >>> Dylan
>
> >> Dylan,
>
> >> A clever programmer will figure out how to use the Arduino's SPI port
> >> with the 74HC595s to eliminate all the software work of banging out the
> >> bits. I've never used an Arduino, so I don't know how it's done. I've used
> >> this chip with the PIC SPI port, and it works.
>
> >> --
> >> David Forbes, Tucson AZ
>
> >> --
> >> You received this message because you are subscribed to the Google Groups
> >> "neonixie-l" group.
> >> To post to this group, send an email to neoni...@googlegroups.com.
> >> To unsubscribe from this group, send email to neonixie-l+unsubscribe@**
> >> googlegroups.com <neonixie-l%2Bunsu...@googlegroups.com>.
> >> For more options, visit this group athttp://groups.google.com/**
> >> group/neonixie-l?hl=en-GB<http://groups.google.com/group/neonixie-l?hl=en-GB>
> >> .

Jon

unread,
Apr 1, 2012, 4:35:03 AM4/1/12
to neonixie-l


On Mar 31, 11:28 pm, Dylan Distasio <interz...@gmail.com> wrote:
> The fact
> that I have to do this serially one bit at a time seems like a pain in the
> neck.  Am I missing something (I'm sure I probably am) in terms of being
> able to set all 24 in parallel?


Dylan,

Nope, it's a serial shift register, so you do need send the data out
one bit at a time.

But it's totally not a problem on either the code or timing front. I'm
assuming you've got the 595s wired in a daisy chain, with the data
input of the first register wired to an IO bit on the microcontroller,
the data out of that 595 wired to the data input of the next etc.
Connect all the 595 clock pins together to a pin on your arduino,
ditto with the latch and output enable lines (if you're using the
latter).

The 595 will take the data essentially as fast as you can throw it out
(unless you're using a really exotic controller). There are a zillion
ways to code this, depending on whether you want speed, compact code,
want to use hardware assistance as David suggests elsewhere in the
thread. But honestly, there's no need to get flowery here - a simple
bit bang works perfectly in this setting. Here's a platform-
independent code snippet in C which is cut'n'pasted from the code for
my 42 tube clock (http://youtu.be/4FnxWsp58EM)


/*
** Function to write a byte to the shift register chain as fast as
needed.
** The argument is a byte of data which is simply inspected one bit at
a time,
** used to set the DATA line and then a fast clock pulse formed. No
manipulations
** are made of the latch or output enable lines - it is for the caller
** to ensure that these are managed appropriately. There are no
returns. It takes
** about 4us to blast out the whole byte.
**
** Usage: write_SR(value);
**
** void write_SR();
** byte value;
*/

void write_SR(byte value)

{
if (value & 0x80)
DATA = 1;
else DATA = 0;
CLOCK = 1;
CLOCK = 0;
if (value & 0x40)
DATA = 1;
else DATA = 0;
CLOCK = 1;
CLOCK = 0;
if (value & 0x20)
DATA = 1;
else DATA = 0;
CLOCK = 1;
CLOCK = 0;
if (value & 0x10)
DATA = 1;
else DATA = 0;
CLOCK = 1;
CLOCK = 0;
if (value & 0x08)
DATA = 1;
else DATA = 0;
CLOCK = 1;
CLOCK = 0;
if (value & 0x04)
DATA = 1;
else DATA = 0;
CLOCK = 1;
CLOCK = 0;
if (value & 0x02)
DATA = 1;
else DATA = 0;
CLOCK = 1;
CLOCK = 0;
if (value & 0x01)
DATA = 1;
else DATA = 0;
CLOCK = 1;
CLOCK = 0;
}


You might ask why I don't have a loop as the code is so repetetive.
The answer is speed - I deliberately unrolled the loop because I have
a 160 bit shift register chain to manage for a multiplexed display
with cross-fades and some other quite complex display animations too.
Note that even for such a long shift register chain, there's no need
to worry about display glitching if you use the LATCH line. Just clock
all the bits through at your leisure and then pulse the LATCH line
once to update the output in one go.

Hope this helps some.

Jon.

coggs

unread,
Apr 1, 2012, 9:09:06 AM4/1/12
to neonixie-l
You can check out the source code and schematics to my nixie driver
board which utilizes the atmega 328 hardware spi - schematics here:
http://cogwheelcircuitworks.com/downloads/ source code here:
https://github.com/cogwheelcircuitworks/Cogwheel-Nixie-System
..c

Eric1180

unread,
Apr 1, 2012, 11:16:24 AM4/1/12
to neoni...@googlegroups.com
HI William, I am a realative newbie to programming so I think what I did would be easyer to understand. I have already done what your are asking for I have a arduino connected to 3x 595's for 24 Output pins also I wrote a code for it so it changes based on a RTC. It was for a art project where I made a clock with strips of led light 12 hours and 12 minute segments = 24 pins. I can email you the code if you would like.
It should be easy to modify the bits to corspond with binary.

David Forbes

unread,
Apr 1, 2012, 12:03:18 PM4/1/12
to neoni...@googlegroups.com
On 3/31/12 3:28 PM, Dylan Distasio wrote:
> Hi all-
> I will need three 74HC595s if I go this route (6xABCD, 8 registers per
> 595 IC). The techniques I had come across on the Arduino consisted of
> serially feed bits to the 595 until all 8 registers per chip were full.
> It would seem like I need to send 24 bits each second as the clock
> ticks. The fact that I have to do this serially one bit at a time seems
> like a pain in the neck. Am I missing something (I'm sure I probably
> am) in terms of being able to set all 24 in parallel?
>

There are two aspects to using a shift register. The first is sending
the bits. This happens one at a time, no matter how you do it, because
there's only one data line.

The second aspect is when the display gets updated, which occurs when
you send a pulse on the latch enable line, which causes the contents of
the shift registers to get loaded into the output registers. That's when
the display changes.

I'm assuming that you have wired the 595s in a string, with data out
from the first going to data in to the second, and all the clocks and
latch enables and resets wired together and driven by one Arduino pin each.

Paul

unread,
Apr 4, 2012, 5:40:17 PM4/4/12
to neonixie-l
Try this Arduino web site http://arduino.cc/en/Tutorial/ShiftOut
It gives several examples of using this chip with code.

Julien Noël

unread,
Apr 5, 2012, 1:18:40 PM4/5/12
to neoni...@googlegroups.com, neonixie-l
Hi paul,

Ogi lumen nixie kit (google it) is based exactly the same components you re going to use.

They also provide schema and an arduino library to drive it.

I used that library as example to build my clock based on shift register

--
Julien Noël

Reply all
Reply to author
Forward
0 new messages