12v to arduino pin - zener diode?

Hello, I am a noob with all this and starting on a project and learning at the same time. I dont know all the terms and items I can use but I read a little but I still need to make sure if I understood correctly or I am totally gonna fry my arduino :slight_smile:

So I have an illuminated ON-OFF switch that will turn on a 12V circuit. So the voltage from the switch will be 12V, connected directly to a 12V 1.2ah battery.

I want my arduino to know when the switch is on or off. After reading some, I found that I could possibly use a zener diode.

Would connecting a wire to the on-side of the switch to a 5.1v zener diode (1N5338B??) and to the pin works? Pin would be INPUT_PULLUP?

Will that work or will my arduino explode? :slight_smile: - Or maybe you would have a solution for me...

Sorry for my noobness.. I need to start somewhere

Hi there!

My guess is that some smoke is going to make an appearance, which is not good as smoke is an unwanted guest in most (if not all) electrical applications.

Below is a schematic of how your button/switch can be connected safely.

In addition, I would not set the pin as INPUT_PULLUP. Just regular INPUT is fine.

Good luck!


thank you very much
I prefer no smoke :slight_smile:

Make 2 voltage dividers , R4 = 10k, R5 = 2K. Connect them to U6, one to terminal #1 the second one to terminal # 2. Connect to one divider to A0 the second one to A1.
When switch is open there willbe some voltage difference between those dividers, when is closed the difference = 0V

Below is a schematic of how your button/switch can be connected safely.

Not so sure a 5.1volt zener is a good protection.
Max pin voltage is not 5volt (for a 5volt Arduino), but VCC + 0.3volt.
That makes the zener useless when the Arduino supply is <= 4.8volt or off.
When the Arduino is off, and that zener circuit is connected to the pin, >= 10mA will flow into the pin through the internal pin protection diodes.

Maybe better to limit voltage and current, by using a voltage divider that can never put >1mA into the pin.
Say 12k for R4 and 8k2 for R5 (minimum values).
Since this is a digital (not analogue) pin, much higher values can be used. 120k:82k will also be fine.

If you want to avoid any current flowing into the pin, then use an external schottky clamping diode between pin and VCC.

If you are using other means to power the arduino, you still must connect the ground wire of the 12V system to the arduino GND pin.

a Zener is one of the worst ideas. Use an N-channel MOSFET that you can turn on with 12 volts to path your signal pin to ground.

MOFET- Schematic.jpg

Overkill, but possible. If used correctly (not like the diagram).
Source must go to ground (not to pin), and internal pull up must be enabled.

Another possible problem is the voltage on that 12V battery will, probably, not always be exactly 12V. You didn’t say what the battery chemistry is [e.g. is it Lead Acid? NiMH? NiCad? LiIon? Alkaline???]. But, in any case the voltage will be higher when fully charged, and lower when drained.

You also didn’t appear to divulge the type of Arduino – so, I’ll assume Uno.

So, here’s a couple of possibilities:


In the upper one [“A0” input] – read the forward voltage across the diode [a 1N914 or 1N4148], using a repeated analogRead() call.

  • Lower parts count.
  • Simpler code (?)


  • Time intensive analogRead.
  • Polling instead of Interrupt.
#define USE_INTERNAL_REF 1  // Set to '0' to use VCC as the ADC reference
#define IN__PWR_SENSE A0

const int PWR_SENSE__THREAH = (int)(0.7*1024/1.1/2); // ~half way between full forward voltage & 0
const int PWR_SENSE__THREAH = (int)(0.7*1024/5.0/2); // ~half way between full forward voltage & 0
int pwr_sense = 0;

void setup() {
  // Make the ADC use 1.1V as the reference [instead of 5V]. This will cause a 
  // greater difference between 0V and full diode forward voltage.

void loop() {
  pwr_sense = analogRead(IN__PWR_SENSE);
  if (PWR_SENSE__THREAH <= pwr_sense)
    // Then 12V is applied!
    // Power switch is open!!

In the lower circuit, when the Power Switch is closed, the D3 input goes from HIGH to LOW. Else, it goes from LOW to HIGH. In either case, an Interrupt is generated, which causes a reading of the D3 input, so the Sketch can know it’s state. The transistor can be a 2N3904 [or similar].


  • Interrupt driven
  • Perhaps more noise immune.


  • Higher parts count.
  • Slightly more complex code.
// This little demonstration sketch reacts to changes to the Power Switch
// and indicates those changes with the built in LED.

#define IN_PWR_SENSE 3
volatile byte state = LOW;

void setup() {
  pinMode(IN_PWR_SENSE, INPUT);  // Not really needed, but I'm paranoid, so there!
  // Make sure the voltage at D3 is stablized before enabling the interrupt.
  // Otherwise, we might get a false interrupt on power up.
  attachInterrupt(digitalPinToInterrupt(IN_PWR_SENSE), SwitchState, CHANGE);

void loop() {
  // Let the world know, that we know, what that infernal switch did!
  digitalWrite(LED_BUILTIN, state);

 * This is an Interrupt Callback Function.  It gets called whenever the 
 * D3 pin changes from HIGH to LOW -- OR  -- from LOW to HIGH
void SwitchState() {
  state = digitalRead(IN_PWR_SENSE);

BTW: None of this is tested!

Any cheapo NPN would work well.... ReverseEMF 's 2nd idea is fine

emitter -> gnd, collector -> input using inputpullup, base via >10k resistor to switched 12v.

Yeah, you should really use a b-e resistor, but I don't think leakage will be a problem.

Note the signal is inverted.


I use this:

There's a hundred ways to skin this cat...


Hi there!

My guess is that some smoke is going to make an appearance, which is not good as smoke is an unwanted guest in most (if not all) electrical applications.

Below is a schematic of how your button/switch can be connected safely.

In addition, I would not set the pin as INPUT_PULLUP. Just regular INPUT is fine.

Good luck!

Probably should use more like a 4V Zener. 5.1V Zener will, likely, allow too high a voltage to reach the Arduino input.

Plus zeners are b* awful.

Need a standing current of typically 5-10mA to get their specc'd volts

+/- 5% at best.

Slope resistance poor .


Bad temperature coefficient

Poor drift over time .......

Shall I go on?

Avoid - there are much better bandgap based devices around these days.

Hooray for Bob Widlar!


Wow lots of different ways haha… thanks all. I dont fully understand all of them. I will look more in depth on the other posts but right now I did a little fritzing based on the first couple answers I got and read a little on voltage divider.

Ok so I may set something on fire with this but we’ll see. (dont forget I am learning all this at the same time… so all these fancy acronyms and expert talks… I dont always understand )

  1. Battery is Lead Acid, 12V 1.2ah
  2. ON-OFF Switch turns on a 12v circuit
  3. my Arduino UNO R3 wants to know when its on or off

Ok so Hopefully I got it right… let me know if my resistor values make sense as well (or placement)
R1 is 10k and R2 is 1k… doing the formula for voltage divider, this would give me a 1.09v out (not sure how much you need to read the switch state)

I have attached the fritzing image
Am I in the right direction?


for digital pins.
Make close to 5V
For analog 1V is ok


Stick to post 8 #2 circuit.


First of all, do get rid of Fritzing and get a proper circuit diagram software (KiCAD, EagleCAD, etc). Learn to draw proper circuit diagrams and benefit for the rest of your life, instead of later coming back to projects and wondering what the relationship is between the colourful spaghetti on the screen and the rat's nest on your PCB, then what the actual values/types of the components are, and finally how the actual circuit is actually put together as those diagrams are generally unreadable.

To reliably read a digitial pin as HIGH you have to provide 2.7V or so. Target 4V so you have a good margin both ways. A two-resistor divider is fine for this.

Increase resistor values - you really don't need to waste that much current in your voltage divider. 200k and 100k would work great: 4V to the pin at 12V; up to 4.7V when fully charged (14V) and down to 3.3V when nearly dead (10V). You leak a mere 0.04 mA of your precious battery charge.

Thanks for the info. I will look into these apps for diagrams.
So R2 100k and R1 200k (didnt find any 200k… I guess i can just use 2x100k)

Or use a 220k, a more common value indeed than 200k. Will still give you good values (3.1V-4.4V for the 10-14V battery output).