I am working on a small project. I need to read the voltage being sent from a oxygen sensor in a car (this car is not fuel injected). I need it read it very fast 100 times a sec (if that is possible).
My problem is that the O2 sensor outputs 0-1V depending on the air/fuel mixture. I searched the forums and found a post talking about using an op amp to multiply the voltage by 5 for an analog pin on the arduino. But they did not provide an example.
Can someone point me in the right direction on using the op amp to multiply the voltage, or is there a better solution?
The Arduino can be supplied a VRef value of less than 5V. The value returned by the analogRead function is determined by the ratio of the input voltage to VRef. So, you may not need an amp at all, unless you are also reading other sensors that are outputting up to 5V.
So unless I can limit that to one pin i don't think that would be an option.
Well to a degree you can. Software commands can change the A/D reference used on the run before reading each channel. ( analogReference() - Arduino Reference ) Using external op amps is also viable but there is no single op-amp device or circuit that covers all cases. perhaps a list of analog voltage ranges you wish to cover would be helpful.
If you are going to have extensive A/D requirements then perhaps you should look into using external A/D converter/multiplexers. Some of these have build in programmable gain stages and many offer more the 10 bits of resolution. The built in Arduino A/D pins are very useful and easy to use, but they are not close to current state of the arts in instrumentation A/D capabilities. The +/- 2 bits of accuracy specification should be looked at closely to see that it will meet the expectations of your application.
If you want to use an opamp I can suggest the AD627 instrumentation opamp. I used it in an RTD bridge to make a temperature measurement which is read by my Arduino.
The AD627 can be powered from a singled ended 5V supply and can output to the rail voltage (i.e. all the way to zero and 5V).
Gain is super simple. In fact, for your case, it's perfect. The gain is 5X if you don't connect anything between pins 1 and 8.
Connect the high side of your O2 sensor to pin 3 and the low side to pin 2.
Connect pin 4 to ground and pin 7 to +5V. Connect pin 5 to ground (to give you a zero based output) and pin 6 to your Arduino analog pin. Viola!
I would place a 0.1uF cap between pin 7 and ground to decouple the power supply. I use ceramics but others may have a different opinion.
It's an instrumentation amp meaning that the output on pin 6 is the gain X the differential between pins 3 and 2. The advantage of a differential amp is that in a noisy environment where you're likely to pick up signals on your wires, the amp will reject the common mode, meaning you can get a clean signal. Just make sure that the two wires to your sensor are either a twisted pair or are kept bundled together so they see the same EMI conditions.
I bought mine at Digikey for less than $8USD. Make sure you get the package style you want as they come in SMT and DIP versions.
Good luck!
PS: One thing that I forgot to mention is the bandwidth. It's got a -3dB rolloff at 80kHz. I don't know how fast your signal is changing but if it's got a lot of high frequency content that you want to measure you need to consider the filter effect of the opamp. You mentioned a sampling rate of 100Hz so it's probably not something to worry about.
Just a note that the Arduino's ADC can convert around 10,000 times a second with the standard clock prescaling I believe - 100Hz sampling frequency isn't a problem
lefty- So let me get this straight . I could change the reference voltage, then take the measurement off the pin, then set it back? I thought you would set it and it would be locked in for the duration of the application. Not sure why I thought that though. Also, if I get to wanting more precise measurements i will look into that...Thanks
mike- thanks I will look into that if I can't get the idea lefty suggested to work
P18F4550- no it is a specifically built (gutted...turbo charged...nitrous...methanol...chevy 350) drag racing car
MarkT- thanks I'm pretty new to the physical computing world. At the most how fast could I poll that pin? If I used lefty's idea of changing the ref value polling the pin then changing it back?
MarkT- thanks I'm pretty new to the physical computing world. At the most how fast could I poll that pin? If I used lefty's idea of changing the ref value polling the pin then changing it back?
Best to check with the ATmega datasheet, but I think that can change the ADC reference source, then do 1 dummy conversion to allow things to settle, then take real readings thereafter. I think the available reference settings are either Vdd or Vref pins or the internal 1.2V reference. IIRC an ADC conversion takes 13 ADC clocks and the ADC clock is set to about 150kHz.
I think the available reference settings are either Vdd or Vref pins or the internal 1.2V reference. IIRC an ADC conversion takes 13 ADC clocks and the ADC clock is set to about 150kHz.
I think I read the Mega board (mega1280 chip) also has an additonal internal 2.56 volt reference, but it's not yet supported by the Arduino core software. I think it might be a addition that might be added someday to the core.
Not sure why you're concerned about a reference V different than 5.0V. If you're reading 0-1V then I'll presume you're reading a narrowband oxygen sensor. This sensor indicates more-or-less a binary rich or lean AFR condition. So you don't need high resolution from the ADC. You can simply read the 0-1V signal against the 5V reference. Values below an ADC value of 92 will indicate rich, and above 92 will indicate lean.
Just for commentary, the ADC has 1023 steps. Over 5V this is gives you a 5mV resolution. Over 0-1V you'll have 200 steps. And since your sample rate is so low you could actually gain some resolution through averaging.
Correct me if I've made some wrong assumptions about your app. But even if I have I suspect 5mV is plenty resolution.
In short, I suggest a better solution is to simply connect the output of your O2 sensor to one of the analog inputs of the Arduino and be done.
So Mark and Lefty can one of you explain this to me like I'm a 4 year old. How would i used the analog reference to poll the 0-1v output? I get how to change it to internal to ref 1.1v should i just accept that it will be .1 volt off in the scale.
Is it a good idea to switch the ref like that then poll then switch it back?
Mitch- I see what your saying....so basically if i poll that analog pin i should get anywhere from 0-204.8? Thus giving me the voltage that it is at...right?
I guess i should explain this project. Let me start off by saying i have a deep understanding of software (my job). All the hardware stuff is where I'm ignorant.
Recently i have dabbled into messing with physical computing. My dad is into drag racing. Over dinner the other night he mentioned one of his buddies had a air/fuel recorder. So we thought it would be a fun project to strap an ardunio in the drag car and start adding sensors to record the information during the pass. Going that fast doesn't leave room for you to keep an eye on boost pressure, air/fuel mix, rpms...etc. So for now all i want to do is hook up the O2 sensor and read the voltage. Record it then look at it after each pass.
So Mark and Lefty can one of you explain this to me like I'm a 4 year old.
Not sure a normal 4 year old would be a good subject to explain all this. ;D
Anyway if you change to the 1.1 volt internal reference (and do the 'dummy read' to allow the mux to settle) then you have a input scale that reads a 0-1.1vdc as a 0-1023 integer. You would could then utilize the mapping function to scale this integer to the actual measurement range you are using: X= map(rawadreading,0,1023, 0, 1100); This would result in a variable X that is reading the actual millivolts value of the input signal. That should result in the near best A/D resolution that the 10bits A/D can have.
@slingle - yes, that idea will work (ADC values ranging 0-204). You might have trouble storing enough data onboard the arduino without adding extra memory. Any sort of datalogging I've done I relied on running serial output simultaneously to pull the acquired data off-chip. Maybe you don't have the ability to send a laptop along for the 13s ride though.
On another note, since you mentioned drag racing I suspect a wideband oxygen sensor will be more useful. This sensor will output a voltage from 0-5V that is pretty linear for AFRs from 7:1->22:1.
Check out the LC-1 from innovate motorsports.
@ Mitch - Yeah I thought about the storage problem. Even with only recording 6.83 seconds of data . I'm sure as the project grows so will the data requirements. I would prefer not to include a laptop. I did find a few SD card controllers that seem like they will work.
The O2 sensor is just one that was laying around the shop. I will look into finding a wideband sensor. For the extra measurements.
Thanks everyone. Sorry I over complicated the situation.