Go Down

Topic: Using built-in ADC to read voltage variance of about 10 mV (Read 553 times) previous topic - next topic

168gr

I have a pressure transducer sensor that outputs a voltage between 1445 mV and 1458 mV when a pressure is applied in my range of interest.

I don't have the option of using a different transducer, as this is part of an existing piece of equipment.

Using an Uno, external reference with 3.3 V applied to the AREF pin, the onboard 10 bit ADC is reading a range of about 6 different values (roughly 483 - 490).

Is there a way, without using an external ADC with more than 10 bits of resolution, to get more resolution in this narrow range of voltages?

Perhaps using an op amp to make a voltage subtractor to subtract 1400 mV and get my signal down to 45 - 58 mV range and then amplifying that 10x, so the ADC is working with a range of 450 - 580 mV? Is this insane?

Seems like there ought to be something I can do to zoom in on that narrow range of interest with the built-in 10 bit ADC.

Thank you.

raschemmel

Arduino UNOs, Pro-Minis, ATMega328, ATtiny85, LCDs, MCP4162, keypads,<br />DS18B20s,74c922,nRF24L01, RS232, SD card, RC fixed wing, quadcopter

wvmarle

Get a pressure sensor that's more suited to the job at hand.

Your "range of interest" is 13 mV on a total of 1450 mV, so <1%. Assuming your sensor goes from 0-5V that'd be 0.3% of the full scale. That's bound to drown in the noise.

Now if you give more information - like what you're actually trying to measure, why such an insanely narrow range, which sensor you're planning to use, etc, you have a much better chance of actual helpful suggestions.
Quality of answers is related to the quality of questions. Good questions will get good answers. Useless answers are a sign of a poor question.

MarkT

I have a pressure transducer sensor that outputs a voltage between 1445 mV and 1458 mV when a pressure is applied in my range of interest.
This kind of output requires a Wheatstone bridge circuit and an instrumentation amplifier - like a loadcell does.  (Its probably a strain gauge being used to measure pressure by its effects on
a container?)
[ I will NOT respond to personal messages, I WILL delete them, use the forum please ]

168gr

The pressure transducer is a commercial / proprietary part I can't change. It's a medical device used to measure blood pressure from catheters placed in arteries. There are no schematics available that I can find.

I've had to reverse engineer how the thing works. It has 4 wires, two of which are power and ground from the commercial monitor, that I've measured to supply about 1.9 V.

When power is applied, and pressure to the sensor varies, I can measure a voltage on the other two wires that changes a small amount, in what appears to be a linear fashion. That's what I'm reading on the ADC.


I have an ads1115 already actually, and wanted to avoid using it for this, because there's another sensor on the i2c bus, and the library for that doesn't seem to want to play nice with other stuff on the bus. Or maybe I'm just using it wrong.

raschemmel

Quote
I have an ads1115 already actually, and wanted to avoid using it for this, because there's another sensor on the i2c bus, and the library for that doesn't seem to want to play nice with other stuff on the bus. Or maybe I'm just using it wrong.
I'm not sure what connection there is between any I2C devices you are using and the ads1115.

The only code you need for the ads1115 is:


Code: [Select]
#include <Wire.h>
#include <Adafruit_ADS1015.h>

Adafruit_ADS1015 ads1015;

void setup(void)
{
  Serial.begin(9600);
  Serial.println("Hello!");
  
  Serial.println("Getting single-ended readings from AIN0..3");
  Serial.println("ADC Range: +/- 6.144V (1 bit = 3mV)");
  ads1015.begin();
}

void loop(void)
{
  int16_t adc0, adc1, adc2, adc3;

  adc0 = ads1015.readADC_SingleEnded(0);
  adc1 = ads1015.readADC_SingleEnded(1);
  adc2 = ads1015.readADC_SingleEnded(2);
  adc3 = ads1015.readADC_SingleEnded(3);
  Serial.print("AIN0: "); Serial.println(adc0);
  Serial.print("AIN1: "); Serial.println(adc1);
  Serial.print("AIN2: "); Serial.println(adc2);
  Serial.print("AIN3: "); Serial.println(adc3);
  Serial.println(" ");
  
  delay(1000);
}


I don't see how this would interfere with your I2C code.
I could be wrong. I am just saying that at this point I am not seeing an issue.
Arduino UNOs, Pro-Minis, ATMega328, ATtiny85, LCDs, MCP4162, keypads,<br />DS18B20s,74c922,nRF24L01, RS232, SD card, RC fixed wing, quadcopter

168gr

This kind of output requires a Wheatstone bridge circuit and an instrumentation amplifier - like a loadcell does.  (Its probably a strain gauge being used to measure pressure by its effects on
a container?)
Thag would make some sense. Maybe I'm approaching this all wrong.

As I wrote above, the inner workjngs of the sensor are not clear and I'm reverse engineering this thing.

If I apply 3.3 V to the power and ground wires, and measure the resistance on the other two, the resistance varies from about 1850 - 1900 ohms across my pressure range.

Should I be trying to measure the variability in resistance instead of the variability in voltage?

168gr

I'm not sure what connection there is between any I2C devices you are using and the ads1115.

The only code you need for the ads1115 is:


I don't see how this would interfere with your I2C code.
I could be wrong. I am just saying that at this point I am not seeing an issue.
Well - I am new to this. It's possible I could make it work.

However, the ads1115 code in the library appears really inefficient. Each read call in the example actually opens and closes a new i2c instance for just the one read. It allows you to switch between ADCs easily but it was murder on performance when I tried to use more than one of them. I need sample rates in the 500+ Hz range for the sensor on the i2c bus already.

It'd be fine if I could get by with samples every 100 ms or so, but I can't. The waveform analysis for the underlying application (measurement of pulse transit times and other physiologic relationships) needs data every millisecond or two.

wvmarle

How about asking the supplier on a device to read this? Or is your hospital really happy to have hobby/DIY circuits reading their medical devices?

Without knowing the actual nature of the sensor pretty much everything else is guesswork.
Quality of answers is related to the quality of questions. Good questions will get good answers. Useless answers are a sign of a poor question.

168gr

This is bench research in an animal lab. The disposable monitors pieces are the same ones that are used on people. None of this is going to touch a person, as much as I'd sometimes like to gratuitously stick needles in people I work with. :)

And yes, we have monitors that read these sensors, and some monitors will even output a data stream (if you pay $$$$$$ for software packages and more proprietary parts and copyright enforcement dongles). But the monitors do all kinds of filtering and preprocessing and there's lag and the timing of the measurement of one parameter fed from one monitor can't be counted on to be synced with the measurement from another monitor. At least, not with millisecond precision.


So unfortunately the answer is essentially building the sensors ourselves. There's some time and money and effort saved by using pieces of the proprietary systems we plug into people in the hospital, which is why we're reverse engineering this thing.

raschemmel

Sorry, I actually didn't realize the ADS1115 was an I2C device. I see your point about efficiency but you
should still be able to use it for your application, although you also still need the wheatstone bridge.
You can use the programmable gain feature in the ADS1115 to amplify the bridge output.
Arduino UNOs, Pro-Minis, ATMega328, ATtiny85, LCDs, MCP4162, keypads,<br />DS18B20s,74c922,nRF24L01, RS232, SD card, RC fixed wing, quadcopter

Wawa

An ADS1115, with it's 256mV range at max gain, still isn't enough for Wheatstone bridge applications.
The HX711 might be more suitable.
Or the ADS1232.
Leo..

Paul__B

It has 4 wires, two of which are power and ground from the commercial monitor, that I've measured to supply about 1.9 V.

When power is applied, and pressure to the sensor varies, I can measure a voltage on the other two wires that changes a small amount, in what appears to be a linear fashion. That's what I'm reading on the ADC.
So in fact, it is a balanced strain gauge and you need to use a standard HX711 strain gauge amplifier module like this:

168gr

So in fact, it is a balanced strain gauge and you need to use a standard HX711 strain gauge amplifier module
Excellent - thank you so much. I appreciate your (everyone's) help.

168gr

So in fact, it is a balanced strain gauge and you need to use a standard HX711 strain gauge amplifier module like this:
I bought this exact HX711 amplifier off Amazon ( https://www.amazon.com/gp/product/B06WP9RML9/ ) and received it today.

The good news - it works. I'm getting useful data out of it.

The bad news - it's way, way too slow. The best sampling rate I can get out of it is about 10-11 Hz. I did some profiling of the HX711 library for Arduino (https://github.com/bogde/HX711) and it really seems to be the chip and not something I can optimize in code.

Each read takes about 89 ms, of which 85 ms is spent in this loop waiting for the chip to become ready:

Code: [Select]

long HX711::read() {
        // wait for the chip to become ready

        while (!is_ready()) {
                // Will do nothing on Arduino but prevent resets of ESP8266 (Watchdog Issue)
                yield();
        }


Even if the chip was always ready and reads took 4 ms, that'd still be too slow. I'm aiming for better than 500 Hz (2 ms) sampling.


Can someone recommend a higher performance (faster) strain gauge amplifier than the HX711?

Go Up