Shop OBEX P1 Docs P2 Docs Learn Events
P2 don't need no stinking pullup resistors(?) — Parallax Forums

P2 don't need no stinking pullup resistors(?)

Say I have a switch between pin 5 and ground and I don't have a pullup resistor. I've seen tantalizing hints in the forum that the P2 doesn't need pullups, but I haven't found actual code. Is the following a good way to set up pin 5 in order to read the switch state in Spin2?

wrpin(5, P_HIGH_150K)
pinh(5)
...
if pinr(5)
' switch is open
else
' switch is closed

Comments

  • RaymanRayman Posts: 14,754
    edited 2022-12-27 22:46

    Yes, it's something like that. I'd look in I2C code to find it...

    Here's an except from jm_i2c.spin2:

    pub setup(scl, sda, khz, pullup) | tix
    
    '' Define I2C SCL (clock) and SDA (data) pins
    '' -- khz is bus frequency: 100 (standard), 400 (full), 1000 (fast)
    ''    * circuit/connections will affect maximum bus speed
    '' -- pullup controls high level drive configuration of SCL and SDA
    
      longmove(@sclpin, @scl, 2)                                    ' copy pins
      clktix := tix := (clkfreq / (khz * 1_000)) >> 2               ' calculate ticks in 1/4 period
    
      case pullup
        PU_NONE : pullup := P_HIGH_FLOAT                            ' use external pull-up
        PU_1K5  : pullup := P_HIGH_1K5                              ' 1.5k
        PU_3K3  : pullup := P_HIGH_1MA                              ' acts like ~3.3k
        other   : pullup := P_HIGH_15K                              ' 15K
    
      org
                    wrpin     pullup, scl                           ' configure high drive
                    wrpin     pullup, sda
                    drvh      scl                                   ' both high
                    drvh      sda
    
  • RaymanRayman Posts: 14,754
    edited 2022-12-27 22:48

    You can see the 3 options there...
    You can also find those definitions in the Spin2 docs: https://docs.google.com/document/d/16qVkmA6Co5fUNKJHF6pBfGfDupuRwDtf-wyieh_fbqw/edit#

  • evanhevanh Posts: 16,029
    edited 2022-12-28 00:47

    Recommend: wrpin(5, P_SCHMITT_A|P_FILT1_AB|P_HIGH_150K|P_LOW_FLOAT|P_INVERT_OUTPUT)

    P_LOW_FLOAT prevents a low output from fighting the input. I know the switch likely also only pulls low but better to be safe.
    P_INVERT_OUTPUT is related in that it defaults to the high pull-up even if all cogs have been stopped. Don't use pinh()

    P_SCHMITT_A and P_FILT1_AB provides a short debounce on the switch. P_FILT1_AB (default of 96 sysclock ticks) can be swapped for P_FILT2_AB for a long debounce (default of 2.6 million sysclock ticks). The lengths can also be customised with a hUBSET instruction but defaults should be effective.

  • mparkmpark Posts: 1,305

    Thanks @Rayman
    How does one decide which pullup option to choose? I mean PU_NONE obviously if there's an external resistor, but if not, what are the pros/cons of PU_1K5 vs PU_3K3 vs other?

    @evanh
    I gave wrpin(5, P_SCHMITT_A|P_FILT1_AB|P_HIGH_150K|P_LOW_FLOAT|P_INVERT_OUTPUT) a try and then did term.dec(pinread(5)) in a loop; I got a string of 1s (expected), but when I touched the switch (just the metal housing) I started seeing 0s mixed in with the 1s (not expected; I didn't expect to see 0s until I actually flipped the switch).
    I like the idea of avoiding pinh if possible. Please advise.

  • evanhevanh Posts: 16,029
    edited 2022-12-28 11:28

    I'd consider 3k3 a strong pull-up, 15k pretty average and 150k particularly weak for this use. So replacing P_HIGH_150K with P_HIGH_1MA will make it very resistant to external noise.

    Changing P_FILT1_AB to P_FILT2_AB will also improve noise resistance, but at a cost of responsiveness.

  • mparkmpark Posts: 1,305

    Sadly, still unable to get your "no pinh" solution to work. Tried replacing P_HIGH_150K with _15K and _1MA, tried P_FILT2_AB -- pinr does not reliably return 1 when switch is open.

    The code in my first post works reliably but I see your point about P_HIGH_150K being weak; I'll use P_HIGH_15K going forward.

  • evanhevanh Posts: 16,029

    So it's still randomly toggling when using P_INVERT_OUTPUT?

  • mparkmpark Posts: 1,305
    edited 2022-12-29 04:39

    @evanh said:
    So it's still randomly toggling when using P_INVERT_OUTPUT?

    'Fraid so, though only when the switch is open. When the switch is closed, I read 0 consistently.

    Ordinarily I'd blame it on my accursedly bad luck with hardware, but the other approach does work, so... [shrug emoji]?

  • evanhevanh Posts: 16,029

    Oops, my fault. Still need DIR set high to drive the pull-up. May as well continue using PINH instead.

    wrpin(5, P_SCHMITT_A|P_FILT2_AB|P_HIGH_15K|P_LOW_FLOAT)
    pinh(5)
    
  • mparkmpark Posts: 1,305

    ...May as well continue using PINH instead.

    Oh, too bad. But I guess that makes sense.

    wrpin(5, P_SCHMITT_A|P_FILT2_AB|P_HIGH_15K|P_LOW_FLOAT)
    pinh(5)
    

    Since pin 5 is high, doesn't that mean the P_LOW_FLOAT is superfluous? I'm slowly wrapping my head around this whole P_HIGH_* and P_LOW_* stuff. Is it the case that none of the P_LOW_* constants has any effect in this situation?

  • That makes no sense.

    If you drive the pin as output, low or high, no pullup or down resistor would make any sense. For what? You are actively driving the pin to low or high.

    Pullup or down resistors make JUST sense for floating (like IC2) or input pins (say RX on serial).

    Something is wrong here,

    Mike

  • Its not wrong, just 'different' to what people are used to. There are advantages. However there does need to be a quick byte for this as it comes up regularly, and its frustrating not to be able to get basic things like this working an understood without friction

    The advantages include being able to gently start audio output without introducing a sudden click, or setting up pin oscillators using the feedback modes.

    I know information on this has been posted before in the forums, but couldn't find it.

  • @mpark said:
    Since pin 5 is high, doesn't that mean the P_LOW_FLOAT is superfluous? I'm slowly wrapping my head around this whole P_HIGH_* and P_LOW_* stuff. Is it the case that none of the P_LOW_* constants has any effect in this situation?

    Yes, P_LOW_* is superfluous in this case if you're keeping the pin always driven high.

    Think about i2c, you can do an initial SDA setup with P_HIGH_1mA (~3k3) to cover the high state, but P_LOW_FAST to actively drive the data line low during data output. Once set up, you just output high and low bits at will, or can always read the true state of the line to see if a peripheral/slave is pulling the SDA line low against the P2's ~3k3 pullup.

    One advantage of this, compared to an external resistor, is that you're not burning excess energy in the pullup resistor every time you output a low on the SDA line (and perhaps the SCL line too). i3c is very energy conscious and does it more like this too

  • AribaAriba Posts: 2,690

    Here is a picture of how I imagine the output circuit of a P2 pin.
    It is of course not the true realization, but it helps to see the function of the pullups.
    https://forums.parallax.com/discussion/comment/1524471#Comment_1524471

  • @Tubular said:
    ... does need to be a quick byte for this ...

    Let's make that happen after the holidays. Lots of content here to scrape and share!

    Please keep posting anything additional you'd like to see, or any prior post references.

  • evanhevanh Posts: 16,029
    edited 2022-12-29 21:21

    Yeah, it's funny how often I find myself adding the setting of DIR later, even for regular data output.

    P_LOW_FLOAT is there just as precaution for those times when OUT does get set low.

    Mike,
    Yes, read Ariba's link. The "pull-up" is actually a repurposed strength-limited output.

  • evanhevanh Posts: 16,029

    @VonSzarvas said:
    Please keep posting anything additional you'd like to see, or any prior post references.

    @Tubular said:
    The advantages include being able to gently start audio output without introducing a sudden click, or setting up pin oscillators using the feedback modes.

    I used the pin's ADC input mode to get a de-popping slow slew rate on an audio output - https://forums.parallax.com/discussion/comment/1535297/#Comment_1535297

    I then went on to making a high impedance ADC (SAR) using the compDAC pin mode - https://forums.parallax.com/discussion/174441/measuring-floating-pin-voltage-adc-from-just-the-built-in-comparator

  • mparkmpark Posts: 1,305

    @Ariba wow, what a great diagram!

    Please keep posting anything additional you'd like to see, or any prior post references.

    I'd love to know if there's a way to do the hidden pullup trick with quadrature mode.

  • evanhevanh Posts: 16,029
    edited 2022-12-30 00:16

    Just add in the smartpin mode to the pin's mode word. Ditch the debounce function assuming the quadrature encoder is using transistors rather than electro-mechanical switches:

    pinf(5)
    wrpin(5, P_QUADRATURE|P_OE|P_SCHMITT_A|P_HIGH_1MA|P_LOW_FLOAT)
    wxpin(5, sampleperiod)
    pinh(5)
    

    Or use pinstart():

    pinstart(5, P_QUADRATURE|P_OE|P_SCHMITT_A|P_HIGH_1MA|P_LOW_FLOAT|P_INVERT_OUTPUT, sampleperiod, 0)
    

    EDIT: Added P_OE. This controls the pin's DIR when using a smartpin. The smartpin consumes the Cog's DIR signal.

    Study the block diagram Rayman did for me, I've tried to clarify that the smartpin is not the whole pin - https://forums.parallax.com/discussion/comment/1530931/#Comment_1530931

  • mparkmpark Posts: 1,305
    edited 2022-12-30 01:58

    Edit: Never mind, "accursedly bad luck with hardware" strikes again.

  • AribaAriba Posts: 2,690

    @mpark said:
    @Ariba wow, what a great diagram!

    Please keep posting anything additional you'd like to see, or any prior post references.

    I'd love to know if there's a way to do the hidden pullup trick with quadrature mode.

    Here is an example in flexBasic, but the smartpin configuration works the same in Spin2 or C:
    https://forums.parallax.com/discussion/comment/1530811/#Comment_1530811

    Andy

  • evanhevanh Posts: 16,029

    Doh! Two pins are needed ...

    wrpin(6, P_SCHMITT_A|P_HIGH_1MA|P_LOW_FLOAT)
    pinstart(5, P_QUADRATURE|P_PLUS1_B|P_OE|P_SCHMITT_A|P_HIGH_1MA|P_LOW_FLOAT, sampleperiod, 0)
    pinh(5 addpins 1)
    
  • mparkmpark Posts: 1,305

    Thanks @Ariba and @evanh !

Sign In or Register to comment.