How can I use a 12 V input on a digital Arduino pin?

Good news! This going to be cheap! :-)

A simple resistor divider will bring the 12 V down to the 5 V an Arduino can digest. The output voltage can be calculated as

\$ V_{OUT} = \dfrac{R2}{R1+R2} V_{IN}\$

Resistor values in the range of 10 kΩ are a good choice. If your R2 is 10 kΩ then R1 should be 14 kΩ. Now 14 kΩ is not a standard value, but 15 kΩ is. Your input voltage will be 4.8 V instead of 5 V, but the Arduino will see that still as a high level. You also have a bit of headroom in case the 12 V should be a bit too high. Even 18 kΩ will still give you a sufficiently high 4.3 V, but then you have to start thinking about the 12 V a bit too low. Will the voltage still be seen as high? I would stick with the 15 kΩ.

edit
You mention an automotive environment, and then you do need some extra protection. The car's 12 V is never quite 12 V, but most of the time higher, with peaks several volts above the nominal 12 V. (Actually nominal is more like 12.9 V, at 2.15 V per cell.) You can place a 5 V zener diode in parallel with R2, and this should cut off any voltage higher than the zener's 5 V. But a zener voltage varies with the current, and at the low input current the resistors give you it will cut off at lower voltages. A better solution would be to have a Schottky diode between the Arduino's input and the 5 V supply. Then any input voltage higher than about 5.2 V will make the Schottky diode conduct, and the input voltage will be limited to the 5.2 V. You really need a Schottky diode for this, a common P-N diode has a 0.7 V drop instead of the Schottky's 0.2 V, and then the 5.7 V maximum input voltage may be too high.

Better
Michael's optocoupler is a good alternative, though a bit more expensive. You often will use an optocoupler to isolate input from output, but you can also use it to protect an input like you want here.

enter image description here

How it works: the input current light the internal infrared LED, which causes an output current through the phototransistor. The ratio between input and output current is called CTR, for Current Transfer Ratio. The CNY17 has a minimum CTR of 40 %, which means you need 10 mA input for 4 mA output. Let's go for the 10 mA input. Then R1 should be (12 V - 1.5 V) / 10 mA = 1 kΩ. The output resistor will have to cause a 5 V drop at 4 mA, then that should be 5 V / 4 mA = 1250 Ω. It's better to have a bit higher value, the voltage won't drop more than 5 V anyway. A 4.7 kΩ will limit the current to about 1 mA.

Vcc is the Arduino's 5 V supply, Vout goes to the Arduino's input. Note that the input will be inversed: it will be low if the 12 V is present, high when it isn't. If you don't want that, you can swap the position of the optocoupler's output and the pull-up resistor.

edit 2
How doesn't the optocoupler solution solve the overvoltage issue? The resistor divider is ratiometric: the output voltage is a fixed ration of the input. If you have calculated for 5 V out at 12 V in, then 24 V in will give 10 V out. Not OK, hence the protection diode.

In the optocoupler circuit you can see that the right side, which connects to the Arduino's input pin doesn't have any voltage higher than 5 V at all. If the optocoupler is on then the transistor will draw current, I used 4 mA in the example above. A 1.2 kΩ will cause a 4.8 V voltage drop, due to Ohm's Law (current times resistance = voltage). Then the output voltage will be 5 V (Vcc) - 4.8 V across the resistor = 0.2 V, that's a low level. If the current would be lower the voltage drop will be smaller as well, and the output voltage will rise. A 1 mA current, for instance, will cause a 1.2 V drop, and the output will be 5 V - 1.2 V = 3.8 V. The minimum current is zero. Then you don't have a voltage across the resistor, and the output will be 5 V. That's the maximum, there's nothing there which will give you a higher voltage.

What if the input voltage would become too high? You accidentally connect a 24 V battery instead of 12 V. Then the LED current will double, form 10 mA to 20 mA. The 40 % CTR will cause 8 mA output current instead of the calculated 4 mA. 8 mA through the 1.2 kΩ resistor would be a 9.6 V drop. But from a 5 V supply that would be negative, and that's impossible; you can't go lower than 0 V here. So while the optocoupler would very much like to draw 8 mA, the resistor will limit that. The maximum current through it is when the full 5 V is across it. The output will then be really 0 V, and the current 5 V / 1.2 kΩ = 4.2 mA. So whatever power supply you attach the output current won't go higher than that, and the voltage will stay between 0 V and 5 V. No further protection needed.

If you expect overvoltage you'll have to check if the optocoupler's LED can handle the increased current, but the 20 mA will not be a problem for most optocouplers (they're often rated at 50 mA maximum), and besides, that's for double input voltage, which probably won't happen IRL.


For voltage independency, use a resistor to regulate the current and a Zener to regulate voltage, like this:

schematic

simulate this circuit – Schematic created using CircuitLab

With a 30k resistor, this will output 4.99V and use only about 234uA @ 12Vin.
In this case:
R1 is consuming 234uA x (12V - 4.99V) = 1.64mW
D1 is consuming 234uA x 4.99V = 1.17mW

Total power consumption: 2.81mW (when input is high)


A good way to isolate the 12V switch signal would be to pass it through an opto coupler. The circuit would be configured similar to the following.

enter image description here

Vi in the diagram represents the 12V in your circuit that is switched by your switch (S1). Select R1 to limit the current through the D1 part of the opto coupler to a level that is within the ratings of the component that you select.

Opto couplers are not the fastest components in the world, especially the cheapest ones, but for the case of a slow action like a human controlled switch, the speed of the coupler is of little concern.

Tags:

Arduino