Shop OBEX P1 Docs P2 Docs Learn Events
How to use Smart Pin for ADC? — Parallax Forums

How to use Smart Pin for ADC?

I am trying to understand how the Smart Pins work (and how to use them).
I want to use a smart pin (let's say a pin(s) P5 to P7) to measure the voltage from a simple potentiometer circuit.
I have the potentiometer wired to +3.3v and GND. The wiper will be connected to the Smart Pin.

1. Do I need anything else connected?
2. What would be the command to configure the Smart Pin? (in either Spin2/P2ASM or TAQOZ or fastspin basic.)
3. What would be the procedure to read the voltage?
4. I assume that I can't connect voltages greater than 3.3v (without using voltage dividers), is that correct.
5. Anything else I am missing?

I appreciate your help
Tom

Comments

  • evanhevanh Posts: 15,169
    edited 2019-01-12 22:48
    1. All good.
    2a. WRPIN ##%100_000_0000000_00_01111_0, #adcpin
    2b. WYPIN #0, #adcpin
    2c. WXPIN #0, #adcpin
    2d. DIRH #adcpin
    3a. RDPIN sample, #adcpin
    3b. SUB sample, diff1
    3c. ADD diff1, sample
    4. You can go over/under the power rails by about 0.3 volts without the protection clamps distorting the signal.

    5a. Details are in the main google doc that Chip maintains: https://forums.parallax.com/discussion/162298/prop2-fpga-files-updated-2-june-2018-final-version-32i/p1
    Peter has posted a PDF of the current version: https://forums.parallax.com/discussion/comment/1461234/#Comment_1461234
    And here's the details I put together about the real pad I/O config'ing: https://forums.parallax.com/discussion/comment/1452036/#Comment_1452036

    5b. My example there doesn't use a sampling trigger, so it is a rolling value that you have to do the diff'ing on. If you setup a sampling trigger, with a non-zero WXPIN and monitoring of IN, then the hardware will do the diff'ing and give you the final sample.


    EDIT: Typo on the mode
  • @evanh,
    Thanks, I'll have to read this over a few times and read the links you posted with your comments as examples. I'm sure I'll have questions once I try this.

    Tom
  • Mode %100_000_0000000_00_01111_0 is actually the ground calibration setting, you don't want that.
    Mode %100_011_0000000_00_01111_0 will read the A input (ie the pin normally) - use that
    Mode %100_001_0000000_00_01111_0 is Vio calibration
    Mode %100_010_0000000_00_01111_0 will read the B input (ie the pin normally)

    In P2ASM:
    CON
        OSCMODE = $010c3f04
        FREQ = 160_000_000
        BAUD = 115200
    
    
        ADC_MODE = %0000_0000_000_100011_0000000_00_01111_0
    
        ADC_PIN = 48
    
        ADC_CYCLES = 1600
    
    OBJ
        ser: "SmartSerial.spin2"
        
    VAR
    
        long value
        
    
    PUB demo | i, a
        clkset(OSCMODE, freq)
        ser.start (63, 62, 0, BAUD)
        ser.str (string ("Hello ADC"))
        ser.tx (13)
        ser.tx (10)
    
        pausems (1000)
        adc_addr := @value
        cognew (@adc_read)
        repeat
            pausems (100)
    	ser.dec (value)
    	ser.tx (13)
    	ser.tx (10)
    
    DAT
                    org     0
    
    adc_read
    		wrpin   ##ADC_MODE, #ADC_PIN
    		wxpin	##ADC_CYCLES, #ADC_PIN 
    		wypin	##0, #ADC_PIN  
    		dirh    ##ADC_PIN
    
    		getct  time
    		addct1  time, ##ADC_CYCLES
     
    .loop		waitct1
    		addct1	time, ##ADC_CYCLES
    		rdpin	val, #ADC_PIN
    		wrlong	val, adc_addr   ' store output
    		jmp	#.loop
    
    
    adc_addr	long    0
    diff		long	0
    time		res	1
    val		res	1
    
  • evanhevanh Posts: 15,169
    Oops, I wasn't very attentive, thank you for the correction Mark.
  • Mark,
    Thanks, seeing a full demo really helps me see what is going on.

    Tom
  • Thanks for the demo. I changed the pin number and baud and printed the volts.
    I also found that I needed to do a calibration to find the min and max values corresponding to 0 and 3.3v. Those are valmin and valmax in the code. The ones that are commented out are the ones for ADC_CYCLES = 1600.

    Is that expected?

    How did you select 1600?
    Does increasing the cycles increase the bits accuracy of the value?

    Thanks again,
    Tom
    CON
        OSCMODE = $010c3f04
        FREQ = 160_000_000
        BAUD = 2000000
    
        ADC_MODE = %0000_0000_000_100011_0000000_00_01111_0
        ADC_PIN = 22
        ADC_CYCLES = 2047           ' 1600
    	'valmin = 270
    	'valmax = 1305
    	valmin = 351
    	valmax = 1670
    
    OBJ
        ser: "SmartSerial.spin2"
        
    VAR
        long value
        
    
    PUB demo | i, a
        clkset(OSCMODE, freq)
        ser.start (63, 62, 0, BAUD)
        ser.str (string ("Hello ADC"))
        ser.tx (13)
        ser.tx (10)
    
        pausems (1000)
        adc_addr := @value
        cognew (@adc_read)
        repeat
            pausems (100)
            ser.dec (value)
    	ser.tx (13)
    	ser.tx (10)
    
        	ser.dec (0 #>(value - valmin) * 330 / (valmax - valmin)<# 330)
    
    	ser.tx (13)
    	ser.tx (10)
    	ser.tx (13)
    	ser.tx (10)
    
    DAT
                    org     0
    
    adc_read
    		wrpin   ##ADC_MODE, #ADC_PIN
    		wxpin	##ADC_CYCLES, #ADC_PIN 
    		wypin	##0, #ADC_PIN  
    		dirh    ##ADC_PIN
    
    		getct  time
    		addct1  time, ##ADC_CYCLES
     
    .loop		waitct1
    		addct1	time, ##ADC_CYCLES
    		rdpin	val, #ADC_PIN
    		wrlong	val, adc_addr   ' store output
    		jmp	#.loop
    
    adc_addr	long    0
    diff		long	0
    time		res	1
    val		res	1
    
    
  • evanhevanh Posts: 15,169
    twm47099 wrote: »
    How did you select 1600?
    Does increasing the cycles increase the bits accuracy of the value?

    Yes, it's a trade-off between resolution and speed. The longer the sample period is the more bits are collected and, like doing a bigger average, the more precise the result is.

  • I originally had 160 for 1MSPS, but changed it by a factor of ten during testing for no
    particular reason :)
  • jmgjmg Posts: 15,144
    twm47099 wrote: »
    I also found that I needed to do a calibration to find the min and max values corresponding to 0 and 3.3v. ...
    Is that expected?
    Yes, the ADC uses feedback resistors inside the device, so benefits from calibration to null their variation.
    Your measurement loop should periodically run the calibrate step on every ADC pin.
    There is enough variation that using another channel to calibrate is less useful.

    twm47099 wrote: »
    How did you select 1600?
    Does increasing the cycles increase the bits accuracy of the value?
    Broadly, yes, but above some point, 1/f noise means longer sample times do not give much noise benefit.
    You might choose a sample size/rate that helps reduce unwanted coupled noise from mains or a SMPS.

  • I am confused. I was able to follow most of the Spin2 and P2ASM, except for this line:
    wrpin   ##ADC_MODE, #ADC_PIN
    
    where
    ADC_MODE = %0000_0000_000_100011_0000000_00_01111_0
    
    Parallax Propeller 2 Documentation v32 dated 2018-09-01from the P2-ES product page explains the 32 bit D field for the wrpin instruction.

    I don't understand the "P" bits described in the document compared with the
    100011_0000000
    
    in the command above. The documentation only describes P12:P10 equal to %101, but I couldn't see anything for P12:P10 = %100.

    I also don't understand how field MMMMM = %01111 is an adc mode. I see that it increases when A is high for a period of time, and that is how a Sigma Delta ADC works, but I don't see how a Sigma Delta is configured. I would have thought that based on the description of the TT field that ADC would have been enabled through a DAC mode?

    I would appreciate it if someone could explain how the D field of wrpin is set up (for example for ADC mode). What does each field mean? Is there newer documentation, or do I just lack understanding?

    Thanks for your help
    Tom
  • evanhevanh Posts: 15,169
    edited 2019-01-15 04:55
    The %P...P portion of the document hasn't been updated for the ES silicon. It is still showing the FPGA only.

    My best attempt at filling this in is here - https://forums.parallax.com/discussion/comment/1452036/#Comment_1452036

    EDIT: And you'll find the ADC sigma-delta modulator config in that same %P...P details.
  • Thanks for the link. It starts to make sense.
    Tom
  • So I did a little experimentation with the x1/x3/x10/x30/x100 ADC modes today, and found that
    they are pretty much identically sensitive to crosstalk noise, so I am guessing the ADC has constant
    current sensitivity but the input resistor is being switched in the different modes. So presumably the
    input impedance gets lower with each step increase in sensitivity?

    I couldn't find any documentation of the input impedances for the ADC modes, I'm wondering
    what they are nominally, and what relative accuracy they have?

    My other question I have is what happens if I change just the input pin selector in the pin mode whilst
    setup for ADC conversion - does this interrupt the behaviour, or is this a valid way to implement analog
    switching of the ADC within a sampling period (I'm thinking of down-conversion of a differential signal).
  • evanhevanh Posts: 15,169
    Selecting a different bitstream as input to the smartpin counters has no impact on ADC bitstream generation. So, yep, no problem turning on four ADCs and chopping between them with a single smartpin.

    Regarding impedances, Chip did say the higher gains have lower internal impedance. But they don't appear to the input though. It's built with lots of transistors and capacitors. I'm not sure if there is any resistors. It was spoken of in that big filter topic when Chip went to town adding even more than intended.
  • evanhevanh Posts: 15,169
    edited 2019-02-26 15:03
    Oh, if you meant the voltage source within the custom pin control, ie: VIO/GIO/PinA/PInB, then yes, this is an analogue switch. There is only a single sigma-delta circuit though.
  • evanh wrote: »
    Oh, if you meant the voltage source within the custom pin control, ie: VIO/GIO/PinA/PInB, then yes, this is an analogue switch. There is only a single sigma-delta circuit though.

    Excellent - I did wonder if whether transmission gates were used (I should never have doubted Chip!)

  • jmgjmg Posts: 15,144
    Mark_T wrote: »
    So I did a little experimentation with the x1/x3/x10/x30/x100 ADC modes today, and found that
    they are pretty much identically sensitive to crosstalk noise, so I am guessing the ADC has constant
    current sensitivity but the input resistor is being switched in the different modes. So presumably the
    input impedance gets lower with each step increase in sensitivity?
    yes.
    Mark_T wrote: »
    I couldn't find any documentation of the input impedances for the ADC modes, I'm wondering
    what they are nominally, and what relative accuracy they have?
    Should be easy to measure, with a current meter to GND/VIO.
    That gives the feedback resistor value, and shows pin-pin variations, and temperature variations.
    The input resistors are a ratio down from that. Tempco from a resistor ratio will be somewhat better than the resistor alone.

    Mark_T wrote: »
    My other question I have is what happens if I change just the input pin selector in the pin mode whilst
    setup for ADC conversion - does this interrupt the behaviour, or is this a valid way to implement analog
    switching of the ADC within a sampling period (I'm thinking of down-conversion of a differential signal).

    because this is sigma-delta, I'd image that is live. Main issue would be if something else was reset by a write to the config ?
  • jmgjmg Posts: 15,144
    evanh wrote: »
    Regarding impedances, Chip did say the higher gains have lower internal impedance. But they don't appear to the input though.

    Chip posted a circuit some time ago IIRC.
    I think that has resistors straight to the pin, and analog switches select different resistors and include the CAL resistors to VIO and GND (note not the same resistor is used),
    Easy enough to check, with a meter and a signal generator with a larger series resistor, to find the Pin-bias point (50% VIO) and the effective pin-loading with gain.
    I think the ADC will work best with lowest impedance external drive, and that reduces crosstalk too.
  • I think the adjacent pin settings for A and B are only digital alas, so an external 74HC4052 is my next idea for a Tayloe style mixer/down converter. Or maybe I've missed a trick
  • jmgjmg Posts: 15,144
    Mark_T wrote: »
    I think the adjacent pin settings for A and B are only digital alas, so an external 74HC4052 is my next idea for a Tayloe style mixer/down converter. Or maybe I've missed a trick

    Yes, adjacent is Digital only, so if you need same-pin analog you will need an external switch.
    Something like a HC4052 would also be good for carrier sync Rx of low levels, because it switches and filters outside of the P2 die.
  • evanhevanh Posts: 15,169
    edited 2019-02-27 02:23
    That voltage source selector in my previous post only applies to the ADC. They can only be selected along with the ADC_MODE setting in the %P...P bits. ADC always produces a bitstream that can usefully go to a smartpin or a streamer.

    PS: I'm hesitant to say the bitstream is the IN signal. Not because it isn't but because it has to pass through both the digital input selector and smartpin before presenting as IN to the cogs and streamers.
  • Mark_T wrote: »
    I think the adjacent pin settings for A and B are only digital alas, so an external 74HC4052 is my next idea for a Tayloe style mixer/down converter. Or maybe I've missed a trick

    You can bring pin B across as an analog, but only 1x (no x3 x10 x30 x100 etc)
    Whether thats useful for your mixer, I don't know
  • Ah, now that is useful, I'll try it. I found the ADC circuit after a lot of trawling of long threads :)
    https://forums.parallax.com/discussion/download/124079/Prop2_ADC_functional.png
  • evanhevanh Posts: 15,169
    That diagram isn't entirely accurate. Chip agreed it was a general approximation.
Sign In or Register to comment.