This is a follow on question from this answer by Spehro Pefhany, in which he explains to us how to use 74HC595 serial shift registers with only one digital output pin. Below's the picture he posted.

Shift1 system by Roman Black

Out of curiosity, and also to evaluate whether I would be able to control a shift register myself, my questions are:

1. How complicated is it to control shift registers in this way with a MCU, in C, for example?

2. How would the firmware that controls this shift register look like?

3. Are there Arduino libraries to help us handle that (or for other platforms as well)?

I have no idea on how to start.

  • \$\begingroup\$ The diagram is quite explicit: you set the pin low for a specific amount of time, make it high again, wait for a minimum time, repeat for all bits, repeat for latch pulse. BTW did you note that you loose one output pin? \$\endgroup\$ – Wouter van Ooijen Apr 1 '14 at 19:07
  • \$\begingroup\$ @WoutervanOoijen - yes, it is explicit, but I'm struggling to design the code that would just do that. I understand that I would have to use a timer and (as a Software Engineer) would probably like to abstract the high/low action behind a function like Arduino's shiftOut. \$\endgroup\$ – Ricardo Apr 1 '14 at 19:13
  • \$\begingroup\$ @WoutervanOoijen - and yes, I understand that I would have to use one pin to drive this, but then I would save the other two that I usually waste controlling clock and latch. Or is there another pin being used elsewhere? \$\endgroup\$ – Ricardo Apr 1 '14 at 19:14
  • \$\begingroup\$ @WoutervanOoijen - I would definitely try this out in the next few days, so I'll post my attempt at a code that drives this as an answer. It's my homework - the upfront research that I have not done, yet. \$\endgroup\$ – Ricardo Apr 1 '14 at 19:15
  • 1
    \$\begingroup\$ If you don't like the timings I think you could use 22nF capacitors and multiply all times by 10. But Ricardo, you seem to think that this circuit is the best invention since sliced bread. It is a nifty toy. I don't think any professional would include it in a serious design. Use plain 595, or an I2C chip like the MCP23017 (there must be arduino libraries for both). \$\endgroup\$ – Wouter van Ooijen Apr 1 '14 at 20:46

This is only a rough answer because there are areas I'm not sure of, so I'd appreciate it if anyone could point out mistakes. I assume one of your issues is that the delay function only allows for a resolution of milliseconds and the delayMicroseconds function only has a minimum delay time of 2μs. However, the ATmega32U4 on the Arduino Micro (and others as well) has a clock speed of 16MHz, we can therefore calculate the time between cycles:

$$\Delta t = \frac{1}{16\text{ MHz}}=0.0625\: \mu\text{s}$$

Therefore, we can calculate how many clock cycles need to elapse before changing the output from HIGH to LOW and back again. We want a delay of 1μs and therefore we calculate:


Where n is the number of clock cycles. We therefore want the CPU to wait for 16 cycles, we can achieve this with some inline assembly:

__asm__("nop\n\t"/*14 more of these*/"nop\n\t");

However, I haven't taken into account the number of clock cycles digitalWrite requires before changing the output pin voltage, so you would need to look into that too.

As I said, this is just a sketch answer, so I'd appreciate validity checks and suggestions/criticisms; I'm quite new to this!

| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.