Help with interfacing with pressure sensor

I'm working on a very simple "sip and puff" interface for students with disabilities, but I am having some trouble correctly interfacing with the pressure sensor (MPX12GP) I have chosen. I read the datasheet and thought I understood that the sensor output fluctuates in the range of 0-55mV, which made me think I could use a simple op-amp as a non-inverting amplifier to boost the signal to roughly the 0-5V range for reading through an Arduino.

I've attached a schematic of what I attempted to wire up on breadboard. What I found was that the output from the sensor hovers at around 2.5V (when supplied with 5V), and I am unable to measure any finer activity with my equipment (a basic multimeter).

I have a hunch that I may need to use an instrumentation amplifier with some sort of DC offset, but it has been quite some time since I've used one and I don't really know how to do that :stuck_out_tongue:

Could someone help me find a way to interface this sensor with an Arduino? I don't have any experience with interfacing with such low-voltage sensors, so please be gentle :slight_smile:

Here is the datasheet for the sensor I am using, model number is MPX12GP: http://www.freescale.com/files/sensors/doc/data_sheet/MPX12.pdf

I recently bought the below, a low level differential ADC module that would work well reading your sensor's low level signal +/- signal. Below is the sketch they provide for testing out the module, seems to work well. Much simpler then trying to build your own low level true differential amp.

http://www.ebay.com/itm/121022291106?ssPageName=STRK:MEWNX:IT&_trksid=p3984.m1439.l2649

//TM7709 24bit ADC module arduino sketch
//coldtears electronics

//default connection arduino UNO
//DRDY = 11
//ADIO = 12
//SCLK = 13

// tested to -253 -0- +253mv

#define TM7710_DRDY        3          
#define TM7710_ADIO        4          
#define TM7710_ADIO_OUT()  DDRB|=1<<4     
#define TM7710_ADIO_IN()   DDRB&=~(1<<4)  
#define Set_TM7710_SCLK()  PORTB|=1<<5
#define Set_TM7710_ADIO()  PORTB|=1<<4
#define Clr_TM7710_SCLK()  PORTB&=~(1<<5)
#define Clr_TM7710_ADIO()  PORTB&=~(1<<4)

unsigned char x[3];
long Result;
//float vref=5.00;
float vref= 6.5;  // adjust value to tune out device offset
                  // such that reading agrees with DMM reading

void TM7710_start(void)   
{
    Clr_TM7710_ADIO();
    delayMicroseconds(1);
    Clr_TM7710_SCLK();
    delayMicroseconds(1);
}

void TM7710_stop(void)    
{
    Clr_TM7710_ADIO();
    delayMicroseconds(1);
    Set_TM7710_SCLK();
    delayMicroseconds(1);
    Set_TM7710_ADIO();
    delayMicroseconds(1);
}
void TM7710_write(unsigned char dd)
{
    unsigned char i; 

    for(i=8;i>0;i--)
    {
        if(dd&0x80)
            Set_TM7710_ADIO();   
        else
            Clr_TM7710_ADIO();   
        
        delayMicroseconds(1);
        Set_TM7710_SCLK();       
        delayMicroseconds(1);
        Clr_TM7710_SCLK();      
        dd<<=1;                  
    }
}

unsigned char TM7710_read(void)
{
    unsigned char data=0,i; 

    for(i=0;i<8;i++)
    {
        Set_TM7710_SCLK();                   
        
        data=data<<1;                                  
        if((PINB&(1<<TM7710_ADIO))==(1<<TM7710_ADIO))  
        {
          data=data+1;
        }
        delayMicroseconds(1);
        Clr_TM7710_SCLK();
         delayMicroseconds(1);
    }
    return data;
}
void TM7710_Init()
{
   TM7710_ADIO_OUT();
   delay(100);
   TM7710_stop();
   TM7710_start();
   TM7710_write(0xBF);        
   //TM7710_write(0x20);      //Gain=128
   TM7710_write(0x00); //Gain=16
   TM7710_stop();      
}
void setup() 
{
DDRB|=1<<5 ;
delay(1000);
Serial.begin(57600);
Serial.println("TM7709 24bit ADC Module");
TM7710_Init();
}
    
void loop()
{ 
   // delay(2000); 
   while((PINB&(1<<TM7710_DRDY))==(1<<TM7710_DRDY)); 
   TM7710_start();
   TM7710_write(0x7F);        
   TM7710_ADIO_IN();          
   for(unsigned char j=0;j<3;j++)
   {
   x[j]=TM7710_read();
   }
   TM7710_ADIO_OUT();         
   TM7710_stop();
   Result=x[0];
   Result = Result * 256;
   Result = Result + x[1];
   Result = Result * 256;
   Result = Result + x[2];
   Result = Result - 6912000;
 //  Serial.print(" HEX =  ");
 //  Serial.println(Result,HEX);

   double volt = Result * vref /16 / 6912000;
    // double volt = Result / 6912000; 
    // volt = volt * .312; 

   printFloat(volt,6); 
   Serial.println(" V  ");

}

 void printFloat(float value, int places) {
 // this is used to cast digits
 int digit;
 float tens = 0.1;
 int tenscount = 0;
 int i;
 float tempfloat = value;

 // if value is negative, set tempfloat to the abs value

   // make sure we round properly. this could use pow from
 //<math.h>, but doesn't seem worth the import
 // if this rounding step isn't here, the value  54.321 prints as

 // calculate rounding term d:   0.5/pow(10,places)
 float d = 0.5;
 if (value < 0)
   d *= -1.0;
 // divide by ten for each decimal place
 for (i = 0; i < places; i++)
   d/= 10.0;
 // this small addition, combined with truncation will round our

 tempfloat +=  d;

 if (value < 0)
   tempfloat *= -1.0;
 while ((tens * 10.0) <= tempfloat) {
   tens *= 10.0;
   tenscount += 1;
 }

 // write out the negative if needed
 if (value < 0)
   Serial.print('-');

 if (tenscount == 0)
   Serial.print(0, DEC);

 for (i=0; i< tenscount; i++) {
   digit = (int) (tempfloat/tens);
   Serial.print(digit, DEC);
   tempfloat = tempfloat - ((float)digit * tens);
   tens /= 10.0;
 }

 // if no places after decimal, stop now and return
 if (places <= 0)
   return;

 // otherwise, write the point and continue on
 Serial.print('.');

 for (i = 0; i < places; i++) {
   tempfloat *= 10.0;
   digit = (int) tempfloat;
   Serial.print(digit,DEC);
   // once written, subtract off that digit
   tempfloat = tempfloat - (float) digit;
 }
 
  }

One way to remove the offset is to connect the currently grounded end of R1 to an offset voltage equal to the base output of the sensor (about 30mV it sounds like). Use another op-amp section as a voltage follower to provide the stiff bias voltage to R1.

@retrolefty: odd, the part referenced by that eBay page is the LTC2400, which costs $10.68 on Digikey :frowning: That would drive up the costs a bit too much for me. But surely there is a cheaper low-level ADC I can buy from Digikey to add to my design? Also, I'm afraid that source code is far beyond what I understand, it looks a LOT more complicated than just reading in an analog voltage.

@afremont: voltage follower? "Stiff bias voltage"? Sorry, I really don't have a clue about EE terminology. Am I reading the datasheet correctly? I didn't see anything in there about an offset voltage, just that it carried from 0mV to 55mV based on pressure.

zenwebb:
@afremont: voltage follower? "Stiff bias voltage"? Sorry, I really don't have a clue about EE terminology. Am I reading the datasheet correctly? I didn't see anything in there about an offset voltage, just that it carried from 0mV to 55mV based on pressure.

Sorry about that. The datasheet clearly shows that at 0 kpa the typical offset is 20mV but could be anywhere from 0 to 35mV. There is also a graph (figure 2) showing the same thing. The "typical" output range of the sensor is 20-75mV. The 55mV is the span of the sensor's output.

A voltage follower is just an op-amp with the output connected directly to the inverting (-) input. Whatever voltage is applied to the non-inverting input (+) will appear at the output but with the ability to supply a relatively large amount of current at a stable voltage (unlike what you'd get from a simple resistor divider). You could use a pot to adjust the voltage applied to the + input. You just want to apply the same voltage that is appearing at the output of the sensor at 0 kpa.

EDIT: If you look at your schematic, and pretend that R1 isn't there and that R2 was 0 Ohms, it would be a voltage follower. It still really is, it's just that the two resistors act like a divider and dump some of the feedback voltage to ground resulting in a fraction of the output voltage appearing at the inverting input. This forces the op-amp to drive the output to a proportionately higher value to get the result that it wants. Op-amps pretty much have a single track mind with only one goal: drive the output to some level that results in the voltage at the inverting input matching the voltage applied to the non-inverting input. The end effect is that the op-amp multiplies the voltage at the + input by 84 to get 1/84th of that voltage applied to the inverting input.

EDIT2: Since approx 20-30mV is appearing at the + input even at 0 kpa, it gets multiplied up to approx 2.4V. By removing one end of R1 from ground and forcing a bias voltage into the network, you can supply that 20-30mV to the inverting input so that the op-amp doesn't have to generate it at the output. This will allow the op-amp to lower the output to 0V since it no longer needs to supply the offset voltage to the inverting input until the output from the sensor begins to rise above the base level.

EDIT: I've been informed by my SO that the first paragraph might sound rude. That certainly wasn't my intent. :slight_smile: I tried to nice things up a little more. Sorry if I offended anyone.

zenwebb:
@retrolefty: odd, the part referenced by that eBay page is the LTC2400, which costs $10.68 on Digikey :frowning: That would drive up the costs a bit too much for me. But surely there is a cheaper low-level ADC I can buy from Digikey to add to my design? Also, I'm afraid that source code is far beyond what I understand, it looks a LOT more complicated than just reading in an analog voltage.

No, the reference to a LTC2400 in that listing is to a different module the also sell, which is single ended only not differential input, but I bought one of those also :wink: (I'm kind of a analog junky). The one I linked to is based on a TM7709 chip which appears to be an Asian manufacture. The seller also sells the chip alone:
http://www.ebay.com/itm/TM7709-24bit-analog-to-digital-converter-ADC-IC-load-cell-sensor-AVR-STM32-/121075340472?pt=LH_DefaultDomain_0&hash=item1c30a714b8

All the sketch is doing is reading the ADC module converting it to a floating point voltage value then sending it out the serial monitor. Most of the code length is because of converting the ADC digital value to floating point for display on the serial monitor. You you handle the ADC digital value (integer or floating point) is up to you and your application.

Lefty

@afremont - thanks for the awesome explanation, I wish it had been explained like that to me in the one electronics class I took in college! I was taught that op-amps work basically "because math", and I promptly forgot all of the equations after I left :stuck_out_tongue:

I realize now that I may not have a correct understanding of the sensor - I see a lot of references to it being a "differential" sensor, but I don't know what that means. The sensor has both a + and a - output pin, and I assumed that they would rise and fall based on positive or negative pressue to the sensor (sips and puffs), but do they actually need to be used together in some way to obtain a single number?

@retroleft - I will keep the solution in mind, but I'm curious if the op-amp method could work or not before I pursue it. The circuit and code complexity increases so dramatically when using a separate ADC that I want to be sure I need to use it first!

zenwebb:
@afremont - thanks for the awesome explanation, I wish it had been explained like that to me in the one electronics class I took in college! I was taught that op-amps work basically "because math", and I promptly forgot all of the equations after I left :stuck_out_tongue:

I realize now that I may not have a correct understanding of the sensor - I see a lot of references to it being a "differential" sensor, but I don't know what that means. The sensor has both a + and a - output pin, and I assumed that they would rise and fall based on positive or negative pressue to the sensor (sips and puffs), but do they actually need to be used together in some way to obtain a single number?

@retroleft - I will keep the solution in mind, but I'm curious if the op-amp method could work or not before I pursue it. The circuit and code complexity increases so dramatically when using a separate ADC that I want to be sure I need to use it first!

Certainly a proper external op-amp could be made to work. It needs to be of a true differential input type and be properly powered to allow a full 0-5vdc output swing, that can be tricky and limit your chip chooses if you wanted to power the opamp with just +5vdc and ground. And of course the gain must be carefully set to allow the full ADC measurement range you plan on using. The sensor is a basic Wheatstone bridge type and as such should be utilized with an instrumentation op-amp circuit.

Lefty

Perhaps I can utilize a pre-made instrumentation amplifier like this? http://www.digikey.com/product-detail/en/INA126PA/INA126PA-ND/300992

What is a "differential input type"? I had assumed that the separate + and - outputs from the sensor were independent and changed based on positive or negative pressure on the sensor, but are they supposed to be used together in some way?

That's cool. As for the term differential, it applies two different ways here it seems. There are 3 kinds of pressure sensors: absolute, gauge and differential. Differential pressure sensors have two pressure ports. Gauge sensors are differential sensors with one port exposed to the outside air. Absolute sensors actually have an internal reference that they compare against, so they are also differential pressure sensors.

Have the two outputs on the sensor is a different kind of differential, electrically speaking. It means that as one pin increases in voltage, the other does the exact opposite. You may need what is called an instrumentation amp to get the specified results from the sensor.

zenwebb:
Perhaps I can utilize a pre-made instrumentation amplifier like this? http://www.digikey.com/product-detail/en/INA126PA/INA126PA-ND/300992

That would work. But do realize that the chip would require at least +6vdc and -6vdc for it's power rails to be able to output 0-5vdc.

What is a "differential input type"? I had assumed that the separate + and - outputs from the sensor were independent and changed based on positive or negative pressure on the sensor, but are they supposed to be used together in some way?

Yes, both the sensor's + and - outputs are nominally at +2.5vdc output (assuming you are powering the device with +5vdc) and deviate from each other to about a maximum between 0 and + or - 55 millivolt depending on pressure amount being sensed, so it's the voltage difference between the + and - signal leads that represents the measurement value, not the absolute voltage on either signal. A true differential input amplifier will respond to just the difference in voltage between the two output leads, ignoring the nominal 2.5vdc output of each signal.

That make sense?
Lefty

@afremont: interesting, the Digikey page for the sensor I bought lists it as a "gauge" type sensor, which matches what you said. I will keep pursuing this instrumentation amp idea :slight_smile: Here is the Digikey product page for the sensor I bought: http://www.digikey.com/product-detail/en/MPX12GP/MPX12GP-ND/951783

@retrolefty: very right you are! I'm really looking for a single rail chip that will operate on USB voltage, so the whole PCB can function with just a USB connection. I'm struggling right now finding any instrumentation amp chips on Digikey that fit the bill. Maybe I need to make one out a dual-channel op-amp like the LM358 that I was already trying to use?

retrolefty:
Yes, both the sensor's + and - outputs are nominally at +2.5vdc output (assuming you are powering the device with +5vdc) and deviate from each other to about a maximum between 0 and + or - 55 millivolt depending on pressure amount being sensed, so it's the voltage difference between the + and - signal leads that represents the measurement value, not the absolute voltage on either signal. A true differential input amplifier will respond to just the difference in voltage between the two output leads, ignoring the nominal 2.5vdc output of each signal.

That make sense?
Lefty

I'm not doubting you, but can you point out where in the datasheet that it says the outputs are at 2.5V (1/2 Vcc) nominally?

zenwebb:
@afremont: interesting, the Digikey page for the sensor I bought lists it as a "gauge" type sensor, which matches what you said. I will keep pursuing this instrumentation amp idea :slight_smile: Here is the Digikey product page for the sensor I bought: http://www.digikey.com/product-detail/en/MPX12GP/MPX12GP-ND/951783

@retrolefty: very right you are! I'm really looking for a single rail chip that will operate on USB voltage, so the whole PCB can function with just a USB connection. I'm struggling right now finding any instrumentation amp chips on Digikey that fit the bill. Maybe I need to make one out a dual-channel op-amp like the LM358 that I was already trying to use?

He he, my original ADC module is looking better and better all the time now isn't it. :wink:
That little module is designed for easy interfacing to low level Wheatstone bridge sensors with minimum hassle. Don't be afraid of the software, it won't bite you. :wink:

Lefty

afremont:

retrolefty:
Yes, both the sensor's + and - outputs are nominally at +2.5vdc output (assuming you are powering the device with +5vdc) and deviate from each other to about a maximum between 0 and + or - 55 millivolt depending on pressure amount being sensed, so it's the voltage difference between the + and - signal leads that represents the measurement value, not the absolute voltage on either signal. A true differential input amplifier will respond to just the difference in voltage between the two output leads, ignoring the nominal 2.5vdc output of each signal. Neither signal is measured relative to ground, just measured between the two signal voltages, with zero pressure applied there will be zero voltage difference between the + and - pins.

That make sense?
Lefty

I'm not doubting you, but can you point out where in the datasheet that it says the outputs are at 2.5V (1/2 Vcc) nominally?

It doesn't, but it gives hints in the notes

  1. Full Scale Span (VFSS) is defined as the algebraic difference between the output voltage at full rated pressure and the output voltage at the
    minimum related pressure.

Algebraic difference meaning the algebraic sum of the + and - outputs, not either of the absolute specific voltages on the two signal pins.

Lefty

I guess that makes sense, since the - output can't really go negative. It stands to reason that it rides on a bias voltage. You can probably tell I don't have allot of experience with differential output sensors nor do I use op-amps like this normally. Thanks for mentioning that.

One of the reasons why I think a simple solution must exist is that I am basing my project off another sip and puff project that failed to raise funding on Kickstarter. You can clearly see on his shield that there is only a sensor, one resistor and an 8-pin DIP package of some kind: Sip'n Puff Ipod Dock

Problem is, he never released the source files for his project :frowning: So I'm left guessing at what exactly he did.

afremont:
I guess that makes sense, since the - output can't really go negative. It stands to reason that it rides on a bias voltage. You can probably tell I don't have allot of experience with differential output sensors nor do I use op-amps like this normally. Thanks for mentioning that.

That firms also sells the same pressure sensors with active electronics already installed inside and it outputs as I recall a 0-5vdc measurement range and it's temperature compensated to boot. Cost more but now you can probably appreciate why that is so.

Lefty

True, but they are pretty cost prohibitive for my application. I found one that costs $16.09: http://www.digikey.com/product-detail/en/MPX5010GP/MPX5010GP-ND/464055

But I'm still stumped about why that sip and puff iPod dock example (Sip'n Puff Ipod Dock) only has a single resistor and a 8-pin DIP IC. I e-mailed the creator about the sensor he used, and he pointed me to the uncompensated model. Curious about how to interface with this thing cheaply.

zenwebb:
True, but they are pretty cost prohibitive for my application. I found one that costs $16.09: http://www.digikey.com/product-detail/en/MPX5010GP/MPX5010GP-ND/464055

But I'm still stumped about why that sip and puff iPod dock example (Sip'n Puff Ipod Dock) only has a single resistor and a 8-pin DIP IC. I e-mailed the creator about the sensor he used, and he pointed me to the uncompensated model. Curious about how to interface with this thing cheaply.

Well perhaps he isn't trying to measure the actual pressure value analog voltage over it's complete range, but just detecting the difference between a sip and a puff. That could be done with two simple comparator op-amp sections (one 8pin dual chip) just looking for any positive differential above a certain value and any negative differential below a certain value, thus generating two digital output signals, one saying a puff is active the other saving a sip is active and both off if neither state is active.

Lefty