adafruit / Adafruit_CircuitPython_ADS1x15

CircuitPython drivers for the ADS1x15 series of ADCs.
MIT License
137 stars 59 forks source link

Confusing 12 bit value and voltage returns. #44

Closed sampazzer closed 4 years ago

sampazzer commented 4 years ago

Hi.

Sorry first time I've kinda done this.

I was massively confused about how my result for chan.value was above 2047 as I'm using the 12 bit ADC and have set it up as per the example code for the 12 bit ADS1015.

I've had a decent look at the code and it looks like everythings bit shifted << 4 and then the voltage calculation used for 32767 (16bit) instead of having a pure 12 bit calculation.

I saw the following function in the ads1015.py:

    def _conversion_value(self, raw_adc):
        raw_adc = raw_adc.to_bytes(2, "big")
        value = struct.unpack(">h", raw_adc)[0]
        return value >> 4

Do i call this separately after the read has happened and call ADS1015._conversion_value(chan.value) ?

or can I just bitshift the chan.value >> 4 ?

I hope this makes sense. Thanks. Sam.

caternuson commented 4 years ago

The CircuitPython AnalogIn API has standardized on returning 16 bit values for everything: https://circuitpython.readthedocs.io/en/latest/shared-bindings/analogio/AnalogIn.html#analogio.AnalogIn.value The attempt there is to make the behavior consistent regardless of ADC resolution - a technical detail which is "hidden" to make things more beginner friendly. But this of course can end up being confusing for those who know about ADC resolution and expect the return to match, etc.

In general, you shouldn't call anything with a leading underscore. Those functions are considered internal use only (aka private). Python doesn't have any protection mechanism (like C++), so it is simply a naming convention.

For your use case - why do you need the actual ADC value in its native resolution?

sampazzer commented 4 years ago

Hi. Thanks for your swift and thoughtful response. I guess it doesn't really matter in application. I'm just now mapping my soil moisture sensor 0..100% between the min and max 16 bit ADC values that are returned. As you said it was just a bit confusing as I was expecting a much smaller number. As I seem to remember I think the old library returned the 12bit equivalent. I just wanted to make sure I wasn't doing anything stupid! Again thanks.

adityarp9 commented 4 years ago

The CircuitPython AnalogIn API has standardized on returning 16 bit values for everything: https://circuitpython.readthedocs.io/en/latest/shared-bindings/analogio/AnalogIn.html#analogio.AnalogIn.value The attempt there is to make the behavior consistent regardless of ADC resolution - a technical detail which is "hidden" to make things more beginner friendly. But this of course can end up being confusing for those who know about ADC resolution and expect the return to match, etc.

In general, you shouldn't call anything with a leading underscore. Those functions are considered internal use only (aka private). Python doesn't have any protection mechanism (like C++), so it is simply a naming convention.

For your use case - why do you need the actual ADC value in its native resolution?

Hi, I need the voltage values at each channel in a single ended mode. In that sense, for ADS1115, which is 16-bit, shouldn't I use the formula: Voltage = RAW_ADC * PGA_GAIN / 65535, to get the actual analog voltage, as you'd get on a multimeter?

caternuson commented 4 years ago

Use the voltage property on the ADC channel: https://github.com/adafruit/Adafruit_CircuitPython_ADS1x15/blob/5a719594f474c61c8bbc667d6a92fea611d06218/examples/ads1x15_simpletest.py#L22 Source for reference: https://github.com/adafruit/Adafruit_CircuitPython_ADS1x15/blob/5a719594f474c61c8bbc667d6a92fea611d06218/adafruit_ads1x15/analog_in.py#L67-L71 Datasheet details: ads

adityarp9 commented 4 years ago

Use the voltage property on the ADC channel:

https://github.com/adafruit/Adafruit_CircuitPython_ADS1x15/blob/5a719594f474c61c8bbc667d6a92fea611d06218/examples/ads1x15_simpletest.py#L22

Source for reference: https://github.com/adafruit/Adafruit_CircuitPython_ADS1x15/blob/5a719594f474c61c8bbc667d6a92fea611d06218/adafruit_ads1x15/analog_in.py#L67-L71

Datasheet details: ads

Wow, got it. Thanks so much for clarifying so promptly. Appreciate it :) Also, one more thing, how did you calculate the PGA gain constants for different gain values?

caternuson commented 4 years ago

Also, one more thing, how did you calculate the PGA gain constants for different gain values?

They are in the datasheet (linked above). Table 3.

adityarp9 commented 4 years ago

Also, one more thing, how did you calculate the PGA gain constants for different gain values?

They are in the datasheet (linked above). Table 3.

Alright, thanks! :)

haberma commented 4 years ago

Hi, I'm using ads1115 and I wonder why the raw counts value seems to have a resolution of 16. I.e. when I'm running the ads1x15_ads1115_simpletest.py example chan.value increases (or decreases) by steps of 16. As far as I understand it should have a resolutuion of 1 for the ads1115. It seems to me that 4 bits get lost somewhere. Has someone observed something similar?

tannewt commented 4 years ago

@haberma Please open a new issue. This issue has already been closed.