Arduino – How to use a 12 V input on a digital Arduino pin

arduino

I am creating a controller for a 12 V system using an Arduino Uno microcrontroller. For the outputs I am using a relay shield to switch the 12 V components. I have a 12 V toggle switch that turns on some 12 V components in the system and I want to use a trigger signal off of this same switch to send to an Arduino digital input. I know that the Arduino can only handle 5 V max. What would be the best way to step down the 12 V coming off of the switch to the 5 V for the input?

EDIT: The system is for use in a car. Would the amperage of the car battery need to be lowered somehow as to not blow up the components?

Best Answer

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.