Forum Rule: Always post complete source code & details to reproduce any issue!
Results 1 to 12 of 12

Thread: SN74HC165 shift register revisited

  1. #1
    Senior Member
    Join Date
    Jan 2017
    Location
    Maastricht
    Posts
    113

    SN74HC165 shift register revisited

    The SN74HC165 shift register makes it easy to add digital input to a Teensy/Arduino. On the Arduino playground a description can be found: SN74HC165N, a Sparkfun tutorial relies on the same approach.
    It always seemed strange to me that shifting in would require 4 wires, whereas shifting out can make do with three. Turns out that you only need three wires, the clock inhibit is superfluous. The tutorial mentioned refer to the timing diagram:

    Click image for larger version. 

Name:	sequence.png 
Views:	94 
Size:	67.8 KB 
ID:	12398

    The way I interpret the datasheet this diagram refers to the case where there's a continuously running clock, not when you have full control over the clock. Also in the datasheet is an example of a typical application with a microcontroller:

    Click image for larger version. 

Name:	typicalApplication.png 
Views:	100 
Size:	76.0 KB 
ID:	12399

    In this example the clock inhibit (pin 15) is connected to ground and just three wires are used.

    The tutorials also make use of delay() statements for timing purposes.

    Code:
    /* Width of pulse to trigger the shift register to read and latch.
    */
    #define PULSE_WIDTH_USEC   5
    
    
    BYTES_VAL_T read_shift_regs()
    {
        long bitVal;
        BYTES_VAL_T bytesVal = 0;
    
        /* Trigger a parallel Load to latch the state of the data lines,
        */
        digitalWrite(clockEnablePin, HIGH);
        digitalWrite(ploadPin, LOW);
        delayMicroseconds(PULSE_WIDTH_USEC);
        digitalWrite(ploadPin, HIGH);
        digitalWrite(clockEnablePin, LOW);
    
        /* Loop to read each bit value from the serial out line
         * of the SN74HC165N.
        */
        for(int i = 0; i < DATA_WIDTH; i++)
        {
            bitVal = digitalRead(dataPin);
    
            /* Set the corresponding bit in bytesVal.
            */
            bytesVal |= (bitVal << ((DATA_WIDTH-1) - i));
    
            /* Pulse the Clock (rising edge shifts the next bit).
            */
            digitalWrite(clockPin, HIGH);
            delayMicroseconds(PULSE_WIDTH_USEC);
            digitalWrite(clockPin, LOW);
        }
    
        return(bytesVal);
    }
    Using an oscilloscope I performed some tests to see whether the delay is actually required. The test setup (alle delay statements removed and clock inhibit connected to ground) is shown in the following picture:

    Click image for larger version. 

Name:	shift-test-setup.jpg 
Views:	70 
Size:	158.7 KB 
ID:	12400

    The stripboard contains four 74HC165 shift registers for the buttons and three 74HC595 shift registers for the leds, the other buttons are on two separate boards. Alle the IC sockets have 100nF decoupling caps build in. A Teensy 3.6 is mounted on a Tall Dog extension board, it is mounted on its side for easy access to all the pins.
    I'm no electrical engineer but this looks like a decent clock pulse to me. Here's a screenprint showing the clock measured at the last IC in the chain:

    Click image for larger version. 

Name:	shift-wave-last.png 
Views:	45 
Size:	28.5 KB 
ID:	12401

    The clock frequency is just over 2MHz, pulse width is about 175ns. From the datasheet:

    Click image for larger version. 

Name:	timing.png 
Views:	48 
Size:	65.3 KB 
ID:	12402

    Worst case is a maximum of 6MHz and a minimum pulse width of 80ns so we're well in the clear. No need for any delays in the code.

    The code running in the test:
    Code:
    unsigned long readShiftRegisters()
    {
        int bitVal;
        unsigned long bytesVal = 0;
        // Trigger a parallel Load to latch the state of the data lines
        digitalWrite(ploadPin, LOW);
        digitalWrite(ploadPin, HIGH);
        // Loop to read each bit value from the serial out line of the SN74HC165N.
        for(int i = 0; i < DATA_WIDTH; i++)
        {
            bitVal = digitalRead(dataPin);
            // Set the corresponding bit in bytesVal.
            bytesVal |= (bitVal << ((DATA_WIDTH-1) - i));
            // Pulse the Clock (rising edge shifts the next bit).
            digitalWrite(clockPin, HIGH);
            digitalWrite(clockPin, LOW);
        }
        return(bytesVal);
    }

    Kind regards,

    Gerrit

  2. #2
    Senior Member+ Theremingenieur's Avatar
    Join Date
    Feb 2014
    Location
    Colmar, France
    Posts
    1,792
    What you are doing looks basically like a bit-banging emulation of a slow ancestor of the SPI bus. Great to see that it works!

  3. #3
    Senior Member
    Join Date
    Jan 2017
    Location
    Maastricht
    Posts
    113
    Quote Originally Posted by Theremingenieur View Post
    What you are doing looks basically like a bit-banging emulation of a slow ancestor of the SPI bus. Great to see that it works!
    I had a look at the SPI library documentation, it seems this is intended for more specialised applications. Using shift registers this way is really easy as there is no protocol overhead and all buttons can be debounced simultaneously.
    While browsing the libraries I found a similar case of clock ringing mentioned in the OctoWS2811 documentation so I thought I'd try a putting a series resistor in the clock line. I started with 220Ω and and then tried 100Ω. The resistor is mounted on the cable connector at the Teensy side.

    Click image for larger version. 

Name:	clock-100ohm-220ohm.jpg 
Views:	37 
Size:	57.3 KB 
ID:	12423

    220Ω is a bit too much, the corners are rounded off and the rise time increases, 100Ω is just fine. The little blips in front of the first pulse are the result of crosstalk from the parallel load line, adding a series resistor cleans it up a little. Here's a before-after comparison of the clock signal without any series resistors and with 100Ω series resistors in the clock an parallel load lines:

    Click image for larger version. 

Name:	shift-wave-before-after.jpg 
Views:	32 
Size:	58.8 KB 
ID:	12424

    I'm quite satisfied with this result. A nice, clean clock signal and 32 buttons scanned in about 15Ás.

    Kind regards,

    Gerrit

  4. #4
    Senior Member
    Join Date
    Jan 2017
    Location
    Maastricht
    Posts
    113
    The finished button panel:

    Click image for larger version. 

Name:	button-panel-board.jpg 
Views:	55 
Size:	156.1 KB 
ID:	12461

    Real old school wiring, it looks a little messy but remember that with shift registers the high frequency clock and data signals are confined to the ICs so there's no risk of RF interference. This is about as far as I'd go without designing a PCB but at least when using strip board like this it is easy to get exact dimensions for a front panel design by counting holes. Mounted on the front panel it look like this:

    Click image for larger version. 

Name:	button-panel.jpg 
Views:	51 
Size:	112.2 KB 
ID:	12462

    The board is mounted on 8 M3 threaded standoffs on the back of the frontpanel, fortunately the measurements were correct so all the buttons are perfectly aligned In case you're wondering, this is part of a DAW (Digital Audio Workstation) plugin controller project I'm working on.

    Kind regards,

    Gerrit

  5. #5
    Senior Member+ KurtE's Avatar
    Join Date
    Jan 2014
    Posts
    3,638
    Looks good!

    Wonder if you could use the Arduino function shiftin (https://www.arduino.cc/reference/en/...ed-io/shiftin/)
    To do each byte... But since you already have it working...

  6. #6
    Senior Member
    Join Date
    Jan 2017
    Location
    Maastricht
    Posts
    113
    Quote Originally Posted by KurtE View Post
    Looks good!

    Wonder if you could use the Arduino function shiftin (https://www.arduino.cc/reference/en/...ed-io/shiftin/)
    To do each byte... But since you already have it working...
    Thanks.

    I thought about using shiftIn() but, as you said, it's working now and there's still a lot to do. When my project is finished I'll take another look at this, it could well be that shiftIn() is faster.
    In the meantime I've got to the point where all the buttons and leds are operational with the DAW software (Logic Pro X).

    Kind regards,

    Gerrit

  7. #7
    Junior Member
    Join Date
    Nov 2017
    Posts
    18
    I would like to know where you got the switches with leds in them? Part number and supplier?

    Thanks.

  8. #8
    Senior Member
    Join Date
    Jan 2017
    Location
    Maastricht
    Posts
    113
    Quote Originally Posted by mark.winger View Post
    I would like to know where you got the switches with leds in them? Part number and supplier?

    Thanks.
    The switches are from the C&K Digitast series. I can't make heads or tails of the pricing which varies a lot per supplier and type. I got them from RS Components and Mouser, here's a link to the black ones with the green leds

    Here's the datasheet: DIGITAST.pdf

    These switches have a very nice feel and precise pressure point, I selected the wide version because they're almost exactly the width of a finger. I also have some no name imitations but they're definitely not as refined as the C&K.

    Kind regards,

    Gerrit

  9. #9
    Member
    Join Date
    Sep 2014
    Location
    South Dundas, Ontario, Canada
    Posts
    24
    I'm interested in how you made/cut the panel for the switches and the labelling. I often don't get past doing "a proof of concept" because of a lack finishing details and equipment. Thanks.

    Peter.

  10. #10
    Senior Member
    Join Date
    Jan 2017
    Location
    Maastricht
    Posts
    113
    Quote Originally Posted by KOC62 View Post
    I'm interested in how you made/cut the panel for the switches and the labelling. I often don't get past doing "a proof of concept" because of a lack finishing details and equipment. Thanks.

    Peter.
    The panel was made by Schaeffer using their free front panel designer software. It's not cheap but the result looks great and you can check the price at anytime in the design software, when finished the panel can be ordered from within the application.

    Kind regards,

    Gerrit

  11. #11
    Senior Member oddson's Avatar
    Join Date
    Feb 2013
    Location
    Isle in the Salish Sea
    Posts
    985
    It really is a beautiful build.

    But why a shift-register instead of a mux or GIPO expander? Seems like a lot of effort was expended to get this working, presumably not to save a few cents on the chips.

    Also, what's with the TRS connectors? Is this thing going to be an audio interface too?

    I hope you'll do a write up of the full project when complete.

  12. #12
    Senior Member
    Join Date
    Jan 2017
    Location
    Maastricht
    Posts
    113
    Quote Originally Posted by oddson View Post
    It really is a beautiful build.

    But why a shift-register instead of a mux or GIPO expander? Seems like a lot of effort was expended to get this working, presumably not to save a few cents on the chips.

    Also, what's with the TRS connectors? Is this thing going to be an audio interface too?

    I hope you'll do a write up of the full project when complete.
    Thanks

    Here's a picture with the display and rotary encoder panel:

    Click image for larger version. 

Name:	Zeus-DPC-Lexicon-front.jpg 
Views:	39 
Size:	90.3 KB 
ID:	13516

    For study I once took apart a Behringer controller and the thing is full of them (and the 595) so I figured I'll do it like this too. I also like the fact that there no multiplexing of the buttons, i.e. high frequency switching all over the pcb.

    Here's the rear view of the display and rotary panel:

    Click image for larger version. 

Name:	Zeus-DPC-rear.jpg 
Views:	38 
Size:	130.3 KB 
ID:	13520

    Level shifters for the encoders and two more shift registers for the encoder buttons.

    The trs jacks are for future expansion with foot pedals and other stuff, I thought I'd put them in now so I don't need to drill holes in the chassis later on. No audio functionality is planned, this is purely a (Mackie control compatible) controller.
    As soon as I find the time to create a little video demonstrating the controller I'll start a thread on the subject.

    Kind regards,

    Gerrit

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •