P2 don't need no stinking pullup resistors(?)
mpark
Posts: 1,305
in Propeller 2
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
Yes, it's something like that. I'd look in I2C code to find it...
Here's an except from jm_i2c.spin2:
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#
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.
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 didterm.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.
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.
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.
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]?
Oops, my fault. Still need DIR set high to drive the pull-up. May as well continue using PINH instead.
Oh, too bad. But I guess that makes sense.
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.
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
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
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.
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.
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
@Ariba wow, what a great diagram!
I'd love to know if there's a way to do the hidden pullup trick with quadrature mode.
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:
Or use pinstart():
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
Edit: Never mind, "accursedly bad luck with hardware" strikes again.
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
Doh! Two pins are needed ...
Thanks @Ariba and @evanh !