Shop OBEX P1 Docs P2 Docs Learn Events
ADC resolution — Parallax Forums

ADC resolution

jaspastjaspast Posts: 12
edited 2023-06-02 19:42 in Propeller 2

In this quick byte (https://www.parallax.com/simple-analog-input/) @"Ken Gracey" described how to use a smart pin as an ADC--described as a 14-bit ADC.

However, I only get 8-bit resolution out of the same setup: counts range from 600~900 for a voltage of 0-3.3 V. (It will display values as low as 200, but only when the voltage is changing.)

How can I get more resolution out of a smart pin ADC? I'm teaching quantization, so it's important for a 14-bit sensor to register as 4096 (edit) 16384 counts.

Comments

  • evanhevanh Posts: 16,027

    Floating at over 8000 reading for me. Try a different pin on another header. It's a little too easy to short the 5 volts and blow up pins.

  • RaymanRayman Posts: 14,744

    I think you need to use the SINC2 filtering mode to get 14 bits.

    Ken's code appears to be SINC2 sampling mode...

    I'm trying to remember how to do it... Maybe change

    pinstart(_pin, p_adc_1x | p_adc, 13, 0) 'init ADC pin

    to

    pinstart(_pin, p_adc_1x | p_adc, %1_1111, 0) 'init ADC pin

  • evanhevanh Posts: 16,027
    edited 2023-06-02 17:33

    The value of 13 sets the mode correctly, and provides a full numerical range of 16385 (0 .. 16384).

    The SInc2 "filtering" mode with 13 (%01_1101) would produce the max 27 bits and need trimmed down. Err: Maybe it would roll over badly when near 3.3 volts since it is really producing 28 bits I think. The hardware accumulators are limited to 27 bits. That might be a problem with 13 in Sinc2 "sampling" mode too ...

  • RaymanRayman Posts: 14,744
    edited 2023-06-02 17:28

    Ok, think it should be %1_1101 after looking at docs, for SINC2 filtering mode...
    But that doesn't change the range, I don't think... just the accuracy...

  • RaymanRayman Posts: 14,744

    BTW: Somebody messed up the font in the silicon hardware docs.
    Hope they can fix it:
    https://docs.google.com/document/d/1gn6oaT5Ib7CytvlZHacmrSbVBJsD9t_-kmvjd7nUR6o/edit#heading=h.3aif7i997trh

  • evanhevanh Posts: 16,027
    edited 2023-06-02 19:50

    Huh, I guess that figures. After some testing ... The filter mode diff'ing never exceeds 16384. Man, that means trimming down to 27 bits is superior to scaling up to 32 bits since trimming can't roll over. So I now have to fix my own decimation programs.
    Doh! Compiling the wrong program ....

    EDIT: Okay, interesting. Chip has done something odd with the X parameter for the "filtering" modes. Its mode of operation is not the same as when specifying a Y parameter. With a Y parameter, readings behaviour is like "sampling" mode but at greater resolution and obviously needs diff'ing to convert the decimations into samples..

    When Y = 0 however, eg: pinstart(_pin, p_adc_1x | p_adc, %1_1100, 0), things get weird. It looks like there is a signed offset or something. And there is the discovered, by Vons I think, a roll-over problem as well. Whereas none of that happens when specifying a Y value.

    EDIT2: Uh-no, Vons discovered there is another roll-over when trying to use full range of all 27 bits via Sinc3 with decimation period of 512 clocks. The fix for that case is to use Y = 511 instead.

  • I tried again on a different header, and now I get 3000~7700. That's certainly more reasonable. Thanks!

  • evanhevanh Posts: 16,027
    edited 2023-06-02 19:53

    It should be double that still. 8192 is the ideal centre reading at 1.65 Volts.

  • RaymanRayman Posts: 14,744
    edited 2023-06-02 20:14

    Using Ken's code I get range 2_300 to 13_300 from gnd to +3.3 and 7_800 when floating
    @jaspast Maybe you didn't connect to 3.3?
    Your range looks close to what I get from GND to floating...

  • RaymanRayman Posts: 14,744
    edited 2023-06-02 20:21

    There's this thread that discussed the modes:
    https://forums.parallax.com/discussion/173364/p2-adc-timing/p1

    Also, there's a Prop Tool example called jm_ez_analog_demo.spin2 that makes calibrated ADC measurements.
    (you might need to change "field" to "fieldX" or something in jm_serial.spin2 for it to compile.

  • RaymanRayman Posts: 14,744

    The filtered mode is a bit more complicated...
    There's an assembly example in the P2 "Hardware Manual" though.

  • evanhevanh Posts: 16,027

    Just make sure the Y (WYPIN) parameter is used in the "filter" modes.

  • RaymanRayman Posts: 14,744

    Just remembered that I made a C adc driver for all the modes for the P2C code generator project...

    466 x 503 - 24K
  • RaymanRayman Posts: 14,744

    Not finding a Spin2 example that does filtering...
    Tried to make one from the assembly example, but doesn't work with inline assembly for some reason...

  • The P2's ADC is unusual in that its range extends above VDD and below VSS, theoretically about -0.85v to 4.15v (though body diodes prevent getting the whole way). So if you need 16384 discrete levels in the 0 to 3v3 range, you need to aim for 24824 count buckets

    This causes confusion and results in issues like described in the comments on the quick byte

    • connecting +5v onto a pin (which is beyond abs max), and wondering why they still don't see 4096
    • connecting to ground and not seeing a value of several hundred rather than something near zero
      I think these basics need to be described on that same page and/or in the example code comments
  • @Rayman said:
    Using Ken's code I get range 2_300 to 13_300 from gnd to +3.3 and 7_800 when floating
    @jaspast Maybe you didn't connect to 3.3?
    Your range looks close to what I get from GND to floating...

    I was connecting to the extra pin on the header- I thought that was 3.3, but I now realize I should have put a multimeter on it.

  • evanhevanh Posts: 16,027
    edited 2023-06-03 01:54

    @Rayman said:
    Not finding a Spin2 example that does filtering...
    Tried to make one from the assembly example, but doesn't work with inline assembly for some reason...

    I did a modified version of Simple_ADC.spin2 from this Quick Bytes for Chip to examine - https://forums.parallax.com/discussion/comment/1551209/#Comment_1551209

    It's using an extra cog to deal with the needed decimation timing. So not really a worthwhile real use case since better to do that in pasm and allow it to cover greater configurable decimation rates.

    EDIT: Doh! I hadn't tested that code in Pnut and had a syntax bug. Sorted now.

  • evanhevanh Posts: 16,027

    @Tubular said:
    The P2's ADC is unusual in that its range extends above VDD and below VSS, theoretically about -0.85v to 4.15v (though body diodes prevent getting the whole way). So if you need 16384 discrete levels in the 0 to 3v3 range, you need to aim for 24824 count buckets

    Using the 3x gain on the analogue frontend is a way to test out the full numerical scale behaviour. I used that today to verify there is no roll-over effect as long as full range fits within 27 bits.

Sign In or Register to comment.