Protecting Arduino inputs from external inputs

MalcolmV8:
In fact I will probably start using that anyways so I can learn more about it while experimenting. It should prevent the monitoring input from ever going high even if the Arduino's pin goes high as the op-amp would not be bi directional. Unless I'm missing something?

Correct.

BTW, respect for substantial thought and consideration as to what would happen in case of faults. You know your project's environment, and that's good to hear.

SirNickity:
BTW, respect for substantial thought and consideration...

Ditto.

In that case I'd use the op-amp impedance buffer as Paul has suggested. In fact I will probably start using that anyways so I can learn more about it while experimenting.

In addition, an op-amp allows you to condition the signal. For example, if your TPS is also 0V to 2V you could amplify the voltage to (almost) the full range of the analog-to-digital converter (0V to 5V) greatly increasing the sensitivity.

SirNickity:
Correct.

BTW, respect for substantial thought and consideration as to what would happen in case of faults. You know your project's environment, and that's good to hear.

Thanks. I spend a lot of time working with car's electronics and tuning. A big hobby of mine.

That's very cool and I'll have to keep that in mind for future additions. My TPS is a 0-5 volt so I'd just use the impedance buffer part of it initially.

Paul__B:
If you do not need scaling, then you just connect your input voltage through a 47k resistor to the "+" or non-inverting input of one op-amp and the output - which of course goes to the Arduino - through another 47k resistor to the "-" or inverting input. As the LM324 is running from the same 5V as the Arduino, its output cannot exceed that. There is a problem however - the LM324 cannot drive its output to the full supply voltage anyway, so you probably need something like a LMC6482 or LMC6484.

Paul I picked up the LMC6482 as you had suggested and this is how I wired it up. I'm not sure it's right because reading your description you say "through another 47K resistor" at one point but I'm not sure where you are referencing? I've been googling around and when I see op amps connected up a lot of them have additional resistors and capacitors around them and I'm not entirely sure I understand why. Some look like because they are scaling the output differently from the input and others look like they are conditioning or cleaning up inputs. Such as taking a noise sine wave input and making it a clean square wave output etc. I just want to get a more informed opinion on this. Here's how I have it wired up now.

Thanks for any input.

As you have it: You'll current-limit the input, but you might want to use an input protection diode here (after the resistor) to clamp over/under voltages. The AVR has those built-in. The op-amp probably doesn't.

You might also need a resistor to ground, also on the inside between the resistor and + input. This provides a default input to the op-amp when the signal is missing or high-impedance. (Otherwise, the input will float, and the output could be anything from Vcc to Gnd.) The downside is, you effectively create a voltage divider, so your input voltage will be a little lower. How much depends on the ratio of resistor values you choose. You want the ground resistor to be high-value enough to minimize this effect, and low-value enough to overcome noise.

The resistors and caps you typically see between the output and - input of the op-amp are there to condition the signal. You can use a voltage divider to scale the output down (as seen by the - input) so the op-amp corrects for the "error" and scales the output up by a corresponding amount. This is how you create voltage amplification. The lower you get the - input to look, the higher the output gets to compensate. You can use caps to make this effect frequency-dependent.

For DC applications, this isn't very useful except for one thing: Noise. You can "short" the output to the - input via a cap. That way, anything above DC has a gain of 1 (output=input), while your voltage divider affects DC at whatever ratio you set with the resistors.

SirNickity thank you for the response. I thought the 47K input resistor would protect the op amp from over voltages the way the arduino does but you bring up a good point there.
Here is the data sheet for the op amp

http://www.mouser.com/ds/2/282/snos674c-122978.pdf

It does say it can handle up to 15 volts but that's supply. I'm not really sure what happens though if the supply has 5 volts (coming from the +5V out of the arduino) and the input goes to 12 volts?

I would like to avoid a voltage divider if at all possible. My requirements are to have as minimal impact on the source I'm monitoring and also read it as accurately as possible. I'm aware of floating input when nothing is connected and in this project that's completely acceptable as I will always have something connected. I do wonder if I need a 5.1 volt zener diode after that 47K resistor connected to ground so if I accidentally put 12 volts on that input instead of the 0-5 volts it doesn't blow the op amp. Assuming that op amp will blow. I still need to decipher that data sheet.

To balance the inputs to the op-amp (and obtain the most faithful operation including over temperature changes), you should have an equal resistance to each input, so you should have a 47k resistor in series with the "-" input just as you do with the "+". That's all.

Op amps have effectively the same protection diodes on their inputs (unless especially designed not to in order to permit a wider input voltage range) so with the 47k in series, that is no more a problem than for the ATmega. Actually, it would be rather more correct to explain that ATmega devices have effectively the same protection diodes on their inputs as op-amps. :smiley:

And if the input is floating, then the output will follow it, and echo that voltage to the Arduino input. Since you have constrained this to the 0 to 5V range of the Arduino, that is of no concern so you do not need to introduce any further complication to the circuit on this account.

(If you seriously believed this mattered, you would just put a 2 megohm resistor from your signal input - before the 47k resistor - to ground - as long as loading your sensor in this manner did not matter.)

Ah thanks Paul. That's great news. So this is all I need and I am golden :slight_smile:

Paul__B:
Op amps have effectively the same protection diodes on their inputs (unless especially designed not to in order to permit a wider input voltage range) so with the 47k in series, that is no more a problem than for the ATmega.

Did not know that, but I guess it makes sense if they're rated to withstand any ESD at all... :slight_smile:

MalcolmV8:
My requirements are to have as minimal impact on the source I'm monitoring and also read it as accurately as possible.

What is the voltage range of the source, what is the source resistance, and how fast will the voltage be changing? You may be better off using just the series resistor, and no op amp.

dc42:

MalcolmV8:
My requirements are to have as minimal impact on the source I'm monitoring and also read it as accurately as possible.

What is the voltage range of the source, what is the source resistance, and how fast will the voltage be changing? You may be better off using just the series resistor, and no op amp.

The source is 0-5 volts. How fast does the voltage change? humm I'm not sure how to answer that. I watch it change on a gauge or DVM before, fairly rapid? I know that's not much of an answer.

As for the op amp I'm not really seeing the benifit either. The original reason for using the op amp is more of a physical hardware barrier in case there was ever a bug in my code which made the arduino pin (A0) go high instead of doing an analogread() and sending 5 volts to the source it was monitoring. Although that seems unlikely. Wouldn't I have to declare that pin as output first? Like
pinMode (A0, OUTPUT);
and then set it to high
digitalWrite(A0, HIGH);

The more I look into it, to me it seems that pin could not be "accidentally" set high. It would have to be intentional with at least two statements referencing A0 instead of say pin 13 or another numeric usually used on the digital pins.

It would take a change to the data direction register, or having the input pullup enabled. Both single bits in different registers. Unlikely? Yes. Impossible, given the RF and horrible supply rail situation in a car? Not entirely.

I was looking to do something similar but decided to go a different route that I believe is much safer.
Take a look at this:
http://arduinodev.com/hardware/

You would use the OBDII adapter to read the car's sensors without any additional wiring.
For my project I have purchased an OBDII splitter so that the adapter can remain behind the dash.
I am going to use the Throttle Position, MAP, and Speed data from the adapter (OBDII) as well as a temp sensor (wired to the arduino) to activate an intercooler sprayer.

He has kits as well.

Paul

PaulH:
I was looking to do something similar but decided to go a different route that I believe is much safer.
Take a look at this:
Hardware Products | ArduinoDev.com

You would use the OBDII adapter to read the car's sensors without any additional wiring.
For my project I have purchased an OBDII splitter so that the adapter can remain behind the dash.
I am going to use the Throttle Position, MAP, and Speed data from the adapter (OBDII) as well as a temp sensor (wired to the arduino) to activate an intercooler sprayer.

He has kits as well.

Paul

I've seen those. I actually have a blue tooth version (not from that site but similar) that I use for other projects. This particular project I'm working on isn't going that route though. Not all sensors I need to tie into are available on the ODB2 port so it'd be a half an half type thing. Also I don't like to tie up the ODB2 port on something I'm installing more permanently as I often put other sensors and gauges on there. Good info though and always an option for certain projects.

OK update.

So I went and redesigned my circuit boards to house the LMC6482 op amps as it was suggested. Essentially now I have the boards setup like this.

The problem is now the inputs are so noisy. Don't mind Eagle labeling that op amp, it's just the closest I could find for circuit board design. It is indeed the LMC6482. I can put a clean steady 0.9 volts on one of my inputs and the Arduino is bouncing like crazy from 0.47 volts to around 1.17 volts. It's fluctuating so fast you can't even read the numbers, I had to take a screen shot. Where as with my old design that simply used a 47K resistor to the input without any op amp the Arduino read the voltage as clean and stead as I supplied it. What gives?

  1. Make sure you have a decoupling capacitor across the power pins of the op amp. 0.1uF ceramic should be fine.

  2. Try connecting a capacitor (0.1uF of 0.01uF) in parallel with the 47K feedback resistor.

  3. Check your wiring.

dc42:

  1. Make sure you have a decoupling capacitor across the power pins of the op amp. 0.1uF ceramic should be fine.

Ahh didn't even know about that capacitor. Will see what I can get added in there. It's using the 5 volt power source from the Arduino. I take it that's a noise supply?

dc42:
2. Try connecting a capacitor (0.1uF of 0.01uF) in parallel with the 47K feedback resistor.

Will try that too.

dc42:
3. Check your wiring.

That's all correct. I ordered new circuit boards from a board house to include the op amps. They take about a month to arrive, hence the delay.

MalcolmV8:
Ahh didn't even know about that capacitor. Will see what I can get added in there. It's using the 5 volt power source from the Arduino. I take it that's a noise supply?

Noise on the supply isn't the issue,the issue is that the op amp may be unstable without it. It's shown in Fig. 2 on the TI datasheet.

Thanks buddy. I made some modifications tonight. I put a 0.1uF across the power pins of the op amp and it made no difference. I then added a 0.1uF across the feed back resistor (between pins 1 & 2 in my diagram above) and that fixed it. Smooth steady voltage now. Thank you for that help.

Now that the voltage is stable I can see it's a little off though. So typically when I feed it the Arduino typically has a very small margin of error. I build lots of these testing modules if you will and on average I have to feed 0.94 volts for the Arduino to read 0.90 volts. Some Arduinos require 0.94, some 0.95 and the highest I've had is 0.96 volts. However going through the op amp I see I have to feed it 1.04 volts to for the Arduino to register 0.90 volts. I know op amps can do scaling and its got me thinking am I inadvertently scaling the voltage without meaning to? How do I correct this difference? I need the Arduino to correctly read the voltage for my projects.

Thanks again for the input so far.
Malcolm