adafruit / Adafruit_ADS1X15

Driver for TI's ADS1015: 12-bit Differential or Single-Ended ADC with PGA and Comparator
Other
298 stars 307 forks source link

differential read channel 0_3 and 1_3 #70

Closed fubbel63 closed 2 years ago

fubbel63 commented 3 years ago

ADS1115: There is no function, but the define for differential reading channel 0 and 3 respectively channel 1 and 3. This is a good feature, when your reference of the channels is not 0 Volt and you have two channels.

The code is simple:

in .h: private: int16_t readADC_Differential(uint16_t channels);

in .cpp: // renamed and changed from Adafruit_ADS1X15::readADC_Differential_0_1() int16_t Adafruit_ADS1X15::readADC_Differential(uint16_t channels) { // Start with default values uint16_t config = ADS1X15_REG_CONFIG_CQUE_NONE | // Disable the comparator (default val) ADS1X15_REG_CONFIG_CLAT_NONLAT | // Non-latching (default val) ADS1X15_REG_CONFIG_CPOL_ACTVLOW | // Alert/Rdy active low (default val) ADS1X15_REG_CONFIG_CMODE_TRAD | // Traditional comparator (default val) ADS1X15_REG_CONFIG_MODE_SINGLE; // Single-shot mode (default)

// Set PGA/voltage range config |= m_gain;

// Set data rate config |= m_dataRate;

// Set channels config |= channels;

// Set 'start single-conversion' bit config |= ADS1X15_REG_CONFIG_OS_SINGLE;

// Write config register to the ADC writeRegister(ADS1X15_REG_POINTER_CONFIG, config);

// Wait for the conversion to complete while (!conversionComplete()) ;

// Read the conversion results return getLastConversionResults(); }

// simple wrapper functions int16_t Adafruit_ADS1X15::readADC_Differential_0_1() { return readADC_Differential(ADS1X15_REG_CONFIG_MUX_DIFF_0_1); // AIN0 = P, AIN1 = N }

int16_t Adafruit_ADS1X15::readADC_Differential_2_3() { return readADC_Differential(ADS1X15_REG_CONFIG_MUX_DIFF_2_3); // AIN2 = P, AIN3 = N }

int16_t Adafruit_ADS1X15::readADC_Differential_0_3() { return readADC_Differential(ADS1X15_REG_CONFIG_MUX_DIFF_0_3); // AIN0 = P, AIN3 = N }

int16_t Adafruit_ADS1X15::readADC_Differential_1_3() { return readADC_Differential(ADS1X15_REG_CONFIG_MUX_DIFF_1_3); // AIN1 = P, AIN3 = N }

caternuson commented 3 years ago

What's the use case for needing 0_3 and 1_3 that prevents wiring to and using 0_1 and 2_3 which is currently supported?

fubbel63 commented 3 years ago

You measure two voltage with an same ground, but not 0 Volt as ground and need high gain, because you have little voltages...

eg. you have two analog voltages (eg. Audio left/right) the ground of the signals is VCC/2 --> connect the analog ground to IN3 and the signals to IN0 and IN1.

If you have only 0_1 then you measure only the difference, the stereo signal difference. If you read single ended, you can't measure little values, because you must you a low gain (the offset is VCC/2). If you read 0_3 and 1_3 then you don't measure the offset between ADS-GND and IN3 and your gain can be sixteen - it's fine for small signals.

See Datasheet ADS111x Page 14/15.

We use the changed library for measurement of photodiodes - there are little values, but an relative high offset. See: https://www.digikey.de/de/articles/how-to-design-stable-transimpedance-amplifiers-automotive-medical-systems

The transimpedance-amplifier need an reference in the middle of vcc, or other in the near of middle -> simple design for the amplifier. Alternative you can use an negativ and an positiv voltage for the amplfier (not good, bound ref to ADS ground) and an inverter for both outputs... Then you have problems with negativ input voltages (to ground) at the ADS inputs and other...

caternuson commented 3 years ago

eg. you have two analog voltages (eg. Audio left/right) the ground of the signals is VCC/2 --> connect the analog ground to IN3 and the signals to IN0 and IN1.

Would this work? analog ground -> IN1 and IN3 signals -> IN0 and IN2

MrF83 commented 2 years ago

But this feature would be extremely helpful if one needs 3 channels with one base potential different to ground. Without it you have to use 2 adc's instead of one. Respectively if you need 6 channels you would get away with only 2 chips. That would sometimes help a lot.

fubbel63 commented 2 years ago

Thanks MrF83,

You are right. It'a not helpful, if you connect the analog ground at two inputs, because you left the fourth channel...

@Carter: In your example, you can only measure 0_1 and 2_3, but not the difference between the channels, I need 1_3. 0_1 and 2_3 have gain 1, 2 or whatever, but the difference is a little signal, you need gain 16 for high resolution. And: you use all four channels, but you need only 3 channels. If there is another little(!) offset betwenn the grounds of the channels, then you need all 4 A/D- channels. With all four functions you can measure and calculate with high resolution (= high gain).

It's simple code change, ADS1X15_REG_CONFIG_MUX_DIFF_0_3 and ADS1X15_REG_CONFIG_MUX_DIFF_1_3 are defined in the header a long, long time.

Best Regards

caternuson commented 2 years ago

Cool. Thanks for all the info. Interesting to see what the use case is for that arrangement. We can add support for this.

Dose anyone here want to try and PR the change? Could just copy/paste existing functions, rename, and make necessary code changes. This begs to be refactored, but can worry that later.

MrF83 commented 2 years ago

Have done it. Hope everything is alright.

caternuson commented 2 years ago

Thanks for the PR @MrF83

This has been added and is in the 2.3.0 release. Please give it a try: https://github.com/adafruit/Adafruit_ADS1X15/releases

caternuson commented 2 years ago

Closing. Support added with #73.