Shop OBEX P1 Docs P2 Docs Learn Events
Shift register suggestions — Parallax Forums

Shift register suggestions

ke4pjwke4pjw Posts: 1,173
edited 2010-02-27 17:46 in Propeller 1
Hey folks,
I am working on a project that needs to read a set of dip switches. I am running low on available pins on the propeller and am looking at using a PISO shift register. I was thinking of going with the CD4014BE. It appears to be widely available but is of the 5 volt variety. Is this a good choice, or is there something better suited?

Regards,
Terry

▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
-- Terry

Comments

  • LeonLeon Posts: 7,620
    edited 2010-02-22 19:29
    It would be OK on 3.3V but a 74HC164 would be a better choice. I think it's a PISO SR.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Leon Heller
    Amateur radio callsign: G1HSM
  • rlingenfrlingenf Posts: 9
    edited 2010-02-22 21:03
    I think the 74HC164 is commonly used as a SIPO. The Basic Stamp N&V Article 40 by Jon Williams, uses it to drive a speech chip.

    Robert
  • LeonLeon Posts: 7,620
    edited 2010-02-22 21:19
    Sorry, it's the 74HC165 that is the PISO.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Leon Heller
    Amateur radio callsign: G1HSM
  • Timothy D. SwieterTimothy D. Swieter Posts: 1,613
    edited 2010-02-22 23:58
    You could use a I2C General Purpose I/O IC such as the PCA9555. How many pins do you have free? How many dip switches do you want to read? You might be able to do some pin multiplexing.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Timothy D. Swieter, E.I.
    www.brilldea.com - Prop Blade, LED Painter, RGB LEDs, 3.0" LCD Composite video display, eProto for SunSPOT
    www.tdswieter.com
  • tonyp12tonyp12 Posts: 1,951
    edited 2010-02-22 23:59
    How many dip switches?
    Are only one switch on at at any time?

    Some type of Multiplexing/charlieplixing could also work.
  • ke4pjwke4pjw Posts: 1,173
    edited 2010-02-23 01:53
    There are 16 dip switches. Any combination of switches may be on or off. The switch configurations will be read at boot time. I only have maybe 5 pins free. The PCA9555 looks like it would be a nice fit too!

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    -- Terry
  • Peter JakackiPeter Jakacki Posts: 10,193
    edited 2010-02-23 01:59
    Did I hear"DIP switches"? and lot's of them too! I know that there are reasons for having something that people can see and set with the inky end of a pen but very very few of my designs have DIP switches, even when a customer specifies it.
    You know that DIP switches need access ports in the enclosure, they take up room and I/O. Unless they are things that need to be configured "in the field" by almost anyone, I favor the USB serial to laptop approach or if the unit has a display then use that with 3 to 4 buttons maybe. Anything but DIP switches.

    So I2C bus expanders are a solution to your requirement but changing the requirement may be the solution.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    *Peter*
  • JonnyMacJonnyMac Posts: 9,208
    edited 2010-02-23 19:14
    I've done a couple designs using the 74x165 to read DIP switches -- works just great. Here's a simple Spin method for testing the 74x165:

    pub in165(ld, clk, do) | tmp165
    
    '' Read inputs from 74x165
    '' -- ld  : shift/load pin (output)
    '' -- clk : clock (output)
    '' -- do  : data out (input)
    
      outa[noparse][[/noparse]ld]~~                                            ' default to shift mode
      dira[noparse][[/noparse]ld]~~
      outa[noparse][[/noparse]clk]~                                            ' clock is 0-1-0   
      dira[noparse][[/noparse]clk]~~
      dira[noparse][[/noparse]do]~                                             ' make do an input 
    
      outa[noparse][[/noparse]ld]~                                             ' load present inputs
      outa[noparse][[/noparse]ld]~~
    
      tmp165~                                               ' clear workspace
      repeat 8
        tmp165 := (tmp165 << 1) | ina[noparse][[/noparse]do]                   ' get new bit, MSBFIRST
    '   tmp165 := (tmp165 >> 1) | (ina[noparse][[/noparse]do] << 7)            ' get new bit, LSBFIRST
        outa[noparse][[/noparse]clk]~~                                         ' blip clock
        outa[noparse][[/noparse]clk]~
    
      return tmp165
    



    [noparse][[/noparse]Edit] I just noticed that you have 16 inputs; I only have eight inputs to check. You can easily expand this to 16-bits and daisy-chain the x165s to read them all with one method call and the same three pins.

    The shift/load and clock pins are common to both chips. The downstream 165's DO pin (9) connects to the upstream 165's SERIAL IN pin (10). The upstream 165 DO pin connects to the Propeller.

    pub in165x16(ld, clk, do) | tmp165
    
    '' Read inputs from two 74x165s
    '' -- ld  : shift/load pin (output)
    '' -- clk : clock (output)
    '' -- do  : data out (input)
    
      outa[noparse][[/noparse]ld]~~                                            ' default to shift mode
      dira[noparse][[/noparse]ld]~~
      outa[noparse][[/noparse]clk]~                                            ' clock is 0-1-0   
      dira[noparse][[/noparse]clk]~~
      dira[noparse][[/noparse]do]~                                             ' make do an input 
    
      outa[noparse][[/noparse]ld]~                                             ' load present inputs
      outa[noparse][[/noparse]ld]~~
    
      tmp165~                                               ' clear workspace
      repeat 16
        tmp165 := (tmp165 << 1) | ina[noparse][[/noparse]do]                   ' get new bit, MSBFIRST
    '   tmp165 := (tmp165 >> 1) | (ina[noparse][[/noparse]do] << 15)           ' get new bit, LSBFIRST
        outa[noparse][[/noparse]clk]~~                                         ' blip clock
        outa[noparse][[/noparse]clk]~
    
      return tmp165
    

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Jon McPhalen
    Hollywood, CA

    Post Edited (JonnyMac) : 2/23/2010 7:30:10 PM GMT
  • CannibalRoboticsCannibalRobotics Posts: 535
    edited 2010-02-24 02:24
    Use a 74hc597. My driver for them is on the Obex at

    obex.parallax.com/objects/381/

    - they are $0.78 each in a DIP16. You can cascade them for days.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Signature space for rent!
    Send $1 to CannibalRobotics.com.
  • nohabnohab Posts: 96
    edited 2010-02-24 13:38
    I have used the 74HC165 before.
    What's the difference/pros/cons with 74HC597 ?
  • LeonLeon Posts: 7,620
    edited 2010-02-24 14:07
    I haven't checked this, but it is probably SPI-compatible like the 74HC595, and can use the same software.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Leon Heller
    Amateur radio callsign: G1HSM
  • kwinnkwinn Posts: 8,697
    edited 2010-02-24 14:44
    The '597 is the parallel to serial (input) equivalent to the '595 serial to parallel (output) chip. I have used it with 2 additional prop pins to input data from switches at the same time as I am outputting data to a display.
  • JonnyMacJonnyMac Posts: 9,208
    edited 2010-02-24 16:56
    They have different pin-outs, and the 74HC597 seems to require four pins (based on Cannibal Robotics' object code) where the 74HC165 only needs three. I'm sure both will work just fine; C/R has used the '597 and I've used the '165 -- both work and you have code examples for each.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Jon McPhalen
    Hollywood, CA
  • ke4pjwke4pjw Posts: 1,173
    edited 2010-02-27 01:53
    Thanks for your help guys. The 74HC165 looks like what I want, however I only have the CD4014 on hand. Quite frankly, I am getting my butt kicked by this thing and I thought it would be pretty easy. Jonny Mac's code is exactly what I was was thinking I would have to do, even with the CD4014. But for some reason, it's not happy. I connected "ld" to pin 9 on the 4014, "clk" to pin 10, and "do" to pin 3. I even added 100ms pauses so I could see the transitions on my old scope, but it appears that I only get "1" out of pin 3 on the shift register. Quite frankly, I am lost, because the datasheet uses language that I don't understand. I don't know what a "JAM" input it. This is my understanding of what it should take to get it to operate PISO.

    Pin 9 - 1 ' Set to PISO
    Pin 10 - 1 ' Populate registers with parallel data
    Pin 10 - 0 '

    Repeat 8 times
    {
    Pin 10 - 1 ' Shift data from LSB to Pin 3
    Pin 10 - 0 '
    Read bit from Pin 3
    }

    Is there something wrong with my understand of this?

    Thanks in advance for your help!

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    -- Terry
  • Peter JakackiPeter Jakacki Posts: 10,193
    edited 2010-02-27 05:00
    Pin 9 of 4014 is the parallel/serial mode control and when it is high it allows parallel inputs (DIP switches) to JAM data into the register, that is, it latches the parallel inputs when the CLOCK goes from low to high. To shift this data out serially then you need to flip the parallel/serial control to low which allows the CLOCK to shift data through the register (shift register). This means that data on the SERIAL INPUT ripples into and through the register and the data that is already in the register ripples out Q8 being the last stage of the register. So you basically latch the data using PARALLEL/SERIAL high and issue a CLOCK transition then change to serial mode and sit in a loop of reading Q8 and clocking for the next bit.

    Cascade Q8 from the previous stage into SERIAL INPUT etc.

    So change your clock from high/low to low/high to guarantee an edge and also remember to read the data before clocking for the next one as P8 appears at Q8 straight after parallel load.
    BTW, take note of taking pin 9 low to change to serial mode.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    *Peter*

    Post Edited (Peter Jakacki) : 2/27/2010 5:05:08 AM GMT
  • ke4pjwke4pjw Posts: 1,173
    edited 2010-02-27 05:52
    Here is my code. Some times it gives all 0's , other times all 1's, and rarely it gives garbage. I am just attempting to read 8 bits at the moment.

    I am pulling my hair out [noparse]:)[/noparse] I *MUST* be something stupid that I can't see. I have checked the wiring again and again.

    Thanks guys!

    --Terry

    ld := 19
      clk := 18
      do := 17
      channel := $0000
    
    
    '' -- ld  : shift/load pin (output) - Pin 9 of CD4014
    '' -- clk : clock (output) - Pin 10 of CD4014
    '' -- do  : data out (input) - Pin 3 of CD4014
      
      outa[noparse][[/noparse]ld]~                                            
      dira[noparse][[/noparse]ld]~~
      outa[noparse][[/noparse]clk]~                                             
      dira[noparse][[/noparse]clk]~~
      dira[noparse][[/noparse]do]~                                             
    
      outa[noparse][[/noparse]ld]~~
      waitcnt(1000  + cnt)
      channel := (channel << 1) | ina[noparse][[/noparse]do]
      outa[noparse][[/noparse]ld]~
      waitcnt(1000  + cnt)
      
                                                     
    
      repeat 7
                           
               
        outa[noparse][[/noparse]clk]~~
        waitcnt(1000  + cnt)
        channel := (channel << 1) | ina[noparse][[/noparse]do]
        outa[noparse][[/noparse]clk]~
        waitcnt(1000  + cnt)  
    
    
      Debug.start(31, 30, 0, 57600)
      waitcnt(clkfreq*2 + cnt)
      Debug.tx(Debug#CLS)
      Debug.Bin(channel, 31) 
    
    

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    -- Terry
  • Peter JakackiPeter Jakacki Posts: 10,193
    edited 2010-02-27 08:46
    Terry,

    If you comment your code as to what it is doing you will see it doesn't conform to the description I gave. Look at these simple steps
    1. LD high       ' parallel mode
    2. CLK low
    3. CLK high     ' now parallel data is latched
    4. LD low        ' back to serial mode
                         ' remember not to clock before reading the 1st bit as it is already present!!!!
    5. Repeat 8 times
        shift channel left 
        Or input data with channel
        CLK low
        CLK high                   ' clock this way to guarantee  a low to high (ESPECIALLY THE 1ST TIME)
    
    

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    *Peter*
  • ke4pjwke4pjw Posts: 1,173
    edited 2010-02-27 16:01
    Thank you Peter! I see my mistake. It now works!!!!!! Much appreciated!!

      ld := 19
      clk := 18
      do := 17
      channel := $0000
    
    
    '' -- ld  : shift/load pin (output)
    '' -- clk : clock (output)
    '' -- do  : data out (input)
      
      outa[noparse][[/noparse]ld]~       ' Set shift/load low                                     
      dira[noparse][[/noparse]ld]~~      ' Set shift/load pin for output on Prop
      outa[noparse][[/noparse]clk]~      ' Set clock low                                       
      dira[noparse][[/noparse]clk]~~     ' Set click pin for output on Prop
      dira[noparse][[/noparse]do]~       ' Set data out pin for input on Prop                                      
      waitcnt(1000  + cnt)  
    
      outa[noparse][[/noparse]ld]~~      ' Set shift/load high (parallel mode)
      waitcnt(1000  + cnt)
    
      outa[noparse][[/noparse]clk]~~     ' Set clock high
      waitcnt(1000  + cnt)  
    
      outa[noparse][[/noparse]ld]~       ' Set shift/load low (serial mode)
      waitcnt(1000  + cnt)
    
      repeat 8
                                     
        channel := (channel << 1) | ina[noparse][[/noparse]do]  ' Shift bits in channel and populate with new bit
        outa[noparse][[/noparse]clk]~   ' Set clock low 
        waitcnt(1000  + cnt)
        outa[noparse][[/noparse]clk]~~  ' Set clock high 
        waitcnt(1000  + cnt)
    
    
    

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    -- Terry
  • LeonLeon Posts: 7,620
    edited 2010-02-27 17:46
    A 'jam' input is usually used to set the chip in a state defined by the input pins. It used to be common with counters used with PLLs.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Leon Heller
    Amateur radio callsign: G1HSM
Sign In or Register to comment.