Shop OBEX P1 Docs P2 Docs Learn Events
prop2 pin set to simultaneous current source and adc? — Parallax Forums

prop2 pin set to simultaneous current source and adc?

Hi, new prop2 user here. Anyone know if it is possible to set a prop2 pin to simultaneously output a fixed current and at the same time measure the voltage on the pin? I'm trying to measure the resistance between the pin and ground, without using a second prop2 pin. I've been able to set the output current with this spin2 code:

pinclear( pin )
wrpin( pin, P_HIGH_100UA )
pinhigh( pin )

and separately measure the voltage with

pinstart( pin, p_adc_1x | p_adc, 13, 0 )
out := readpin( pin)

but not sure how to combine these two functions or if it is even possible in spin2. Any ideas? Thank you in advance. I recognize this sort of thing is usually done by adding a capacitor in parallel and measuring the rc time constant, but don't want to go that route bc of the tolerance in capacitance. I also recognize that separating the two function into two separate pins is another path forward, but I don't want to go that route bc I can't afford the pins. Thanks again for any pointers.

Comments

  • RaymanRayman Posts: 15,302
    edited 2025-06-20 05:34

    Guess I’d try to or together those three p_ things into one pinstart…

  • Thanks for the reply. I tried this, and it failed to set the output voltage:

    pinstart( pin, P_HIGH_100UA | p_adc_1x | p_adc, 13 ,0 )

    I'm open to any ideas...

  • RaymanRayman Posts: 15,302

    Try to or in P_OE

  • RaymanRayman Posts: 15,302

    This looks like it might be working on P56:

      pinstart( 56, P_HIGH_100UA | p_adc_1x | p_adc| p_OE, 13 ,0 )
      pinh(56)
      repeat
        waitms(500)
        debug(udec(rdpin(56)))
    

    Can't say for sure though...

  • evanhevanh Posts: 16,525
    edited 2025-06-20 12:13

    Yep, both the P_OE and pinh() are needed. Digital output control is well supported while using the ADC. The P_OE is there because DIR is consumed to control the P_ADC smartpin mode.

    I'd use pinstart( pinnum, P_HIGH_100UA | P_LOW_FLOAT | P_ADC_1X | P_ADC | P_OE, 13 ,0 ) so that when the pin output is set low it isn't driving low.
    And replace pinh() with outh(). And use outl() to turn off the current source. This then cleanly separates output drive from ADC operation.

  • Rayman, evanh, Thank you this worked:

    pinstart( pin, P_HIGH_100UA | P_LOW_FLOAT | P_ADC_1X | P_ADC | P_OE, 13 ,0 )
    pinh( pin )
    rdpin( pin )

    However I noticed that as I dialed the resistance from 0-28k, the voltage was not linear with resistance; it drooped a bit especially at the higher resistances. Perhaps due to the internal resistance of the current source. Unfortunate bc I was hoping to get a repeatable reading of the resistance, consistent across different pins and chips. I may move to a voltage divider with a known fixed resistance, and simply measure voltage across the unknown resistance. Thanks again.

  • RaymanRayman Posts: 15,302

    @Dodwin Well, one must do a calibration for the best results. The P2 can internally connect ADC input to either GND or 3.3V for this purpose...
    Pretty sure there is a lot of code around to do this...

  • evanhevanh Posts: 16,525
    edited 2025-06-20 19:14

    Oh, the ADC has 500k resistance to virtual ground at VIO/2 (1.67 Volts). Not sure if that would explain it all though.

    PS: To confirm using a multimeter, remove the ADC and use the 100 uA pull-up only.

        wrpin( pin, P_HIGH_100UA | P_LOW_FLOAT )
        pinh( pin )
    
  • Rayman, thanks for the suggestion. Calibration seems like the way to go; I tried the voltage divider and had the same chip to chip non-repeatability as the current source.

    Evanh, thanks for the tip.

Sign In or Register to comment.