Digital input max voltage on nano

Hi Guys,

I have a project I built, had circuit boards made at a board house and have my original proto type up and working and about to assemble multiple more units when I realized a terrible mistake I made.

Pin D11 is configured as a digital input and has a 10K resister pulling it to ground. Also coming off D11 is a push button momentary switch connected to a 8 volt supply instead of 5 volts by mistake. Amazingly the board is still working and has not burnt up. Have I just gotten lucky from not using the button much? Or is that 10k pull down resister breaking up the voltage and saving my arduino? I thought those digital inputs could only work with a maximum of 5 volts?

I'm not sure if I need to scrap all these boards and order another batch with the voltage supply coming from the right place or if I'm good to go.

Thanks for any insight.
Malcolm

This post, over on Adafruit.com, seems to answer your question.

http://forums.adafruit.com/viewtopic.php?f=25&p=127848

This kind of information is in the ATmega328 datasheet. Absolute max for I/O pins is 0.5+VCC. So if your VCC is 5V then the absolute max is 5.5V as an input. However, you shouldn't rely on the "absolutes" because those often mean some damage is occurring. 6-8V is definitely in the area of causing failures.

As you have exceeded the "absolute maximum" of the Arduino's digital input pin, there is no question that some damage has occurred. That damage may not ever manifest in a way that you notice, if you are lucky, but it has occurred. That's the definition of the "absolute maximum" rating for a chip. You need to design a proper voltage divider to drop the input voltage below your Vcc, which is 5v for the Nano.

I'm confused by what Vcc is. Is that he voltage supply going to the VIN pin on the Arduino that actually powers it up? If so that's the 8 volt supply I'm using. So I power up my Arduino with 8 volts. I also sent 8 volts to pin D11 instead of using the 5 volt output from the Arduino to go to D11.

MalcolmV8:
Or is that 10k pull down resister breaking up the voltage and saving my arduino? I thought those digital inputs could only work with a maximum of 5 volts?

I think this question is based on a misunderstanding of how a voltage divider works. A pulldown resistor by itself is not going to act as a voltage divider. However, if you were to put another resistor in series with the switch, such that the input pin was between the pulldown resistor and the new series resistor, I believe that would be a voltage divider. You may be able to accomplish this without trashing your PCBs, with a little creative soldering.

Please see the attached schematics for an example of what I’m talking about. Out of laziness, I didn’t put in the switch, and simply put in an 8v supply, but the concept is demonstrated.

circuit.jpg

joshuabardwell:

MalcolmV8:
Or is that 10k pull down resister breaking up the voltage and saving my arduino? I thought those digital inputs could only work with a maximum of 5 volts?

I think this question is based on a misunderstanding of how a voltage divider works. A pulldown resistor by itself is not going to act as a voltage divider. However, if you were to put another resistor in series with the switch, such that the input pin was between the pulldown resistor and the new series resistor, I believe that would be a voltage divider. You may be able to accomplish this without trashing your PCBs, with a little creative soldering.

Please see the attached schematics for an example of what I’m talking about. Out of laziness, I didn’t put in the switch, and simply put in an 8v supply, but the concept is demonstrated.

My thought was that the digital input would be sinking current with a resistance of 20k to 50k ohms. Per this page http://arduino.cc/en/Main/ArduinoBoardNano. That’s where I was trying to fabricate the voltage dividing circuit in my head while trying to understand why my Arduino was not yet fried. It is possibly because my supply voltage to the Arduino is 8 volts but that depends on how accurately I understood the explanation above yours.

I think some creative soldering of a resister in line to the switch might be what I need.

MalcolmV8:
I'm confused by what Vcc is. Is that he voltage supply going to the VIN pin on the Arduino that actually powers it up? If so that's the 8 volt supply I'm using. So I power up my Arduino with 8 volts. I also sent 8 volts to pin D11 instead of using the 5 volt output from the Arduino to go to D11.

What Vcc means depends on context, however it usually refers to the supply voltage of a chip. (EDIT: the positive supply voltage of a chip.) In this case, I'm referring to the Vcc going into your AVR328 microprocessor, which is 5v. If we were talking about the voltage regulator circuit, however, Vcc might be 8v, and the output voltage would be 5v. Regardless, you can't send 8v unregulated power to a digital pin on the Arduino. You should almost always be feeding digital and analog input circuits from the Arduino's 5v supply. These circuits are almost always very low-current, so there is seldom any need to use an external supply. Feeding the digital input pin with an unregulated source is asking for trouble. You've got a nice, stable, regulated 5v supply--use it. One approach may be to use a razor-knife or something like that to cut the trace going from the 8v supply to the positive side of the switch circuit, then manually solder in a jumper wire to a convenient 5v supply point.

Also: you say that you're using external pulldown resistors on a digital input circuit. The Arduino has built-in pullup resistors that can be enabled by using pinMode(pinNum, INPUT_PULLUP). This is usually the preferable way of handling a digital input.

MalcolmV8:
My thought was that the digital input would be sinking current with a resistance of 20k to 50k ohms. Per this page http://arduino.cc/en/Main/ArduinoBoardNano. That's where I was trying to fabricate the voltage dividing circuit in my head

Sorry, but I don't think it works that way. If you look at the schematic I posted earlier, if you imagine the input pin as a 20k-50k Ohm impedance, there is no voltage dividing function between the far side of the input pin and the 8v supply. A voltage divider is formed when you have two different resistances in series. In this case, the input pin and the pulldown resistor are in parallel, so there is no voltage dividing function happening between them. But even if there was, the AVR's datasheet says you can't put more than Vcc + 0.5v = 5.5v onto an input pin. If the input pin's internal impedance somehow affected this rating, that would already be taken into account, and the 5.5v would still be exceeded by an 8v supply.

joshuabardwell:

MalcolmV8:
I’m confused by what Vcc is. Is that he voltage supply going to the VIN pin on the Arduino that actually powers it up? If so that’s the 8 volt supply I’m using. So I power up my Arduino with 8 volts. I also sent 8 volts to pin D11 instead of using the 5 volt output from the Arduino to go to D11.

What Vcc means depends on context, however it usually refers to the supply voltage of a chip. In this case, I’m referring to the Vcc going into your AVR328 microprocessor, which is 5v. If we were talking about the voltage regulator circuit, however, Vcc might be 8v, and the output voltage would be 5v. Regardless, you can’t send 8v unregulated power to a digital pin on the Arduino. You should almost always be feeding digital and analog input circuits from the Arduino’s 5v supply. These circuits are almost always very low-current, so there is seldom any need to use an external supply. Feeding the digital input pin with an unregulated source is asking for trouble. You’ve got a nice, stable, regulated 5v supply–use it. One approach may be to use a razor-knife or something like that to cut the trace going from the 8v supply to the positive side of the switch circuit, then manually solder in a jumper wire to a convenient 5v supply point.

Also: you say that you’re using external pulldown resistors on a digital input circuit. The Arduino has built-in pullup resistors that can be enabled by using pinMode(pinNum, INPUT_PULLUP). This is usually the preferable way of handling a digital input.

Thank you for the clarification. That makes a lot more sense now on the VCC part of it. The switch is not PCB mounted but with some short wires to the front panel of my enclosure so while not the cleanest looking way I can route that wire to a different spot on the board and do some adhoc wiring to the appropriate 5 volt source.

As for the built in resistors I did not know that. Very cool. So when I have a digital input that I don’t want to be floating like in my case when nobody is pressing the switch button I can simply (pinNum, INPUT_PULLUP) and it’ll be the same as me putting my external resistor on there and grounding the input to be sure it’s a 0 till someone presses the button? Or is that INPUT_PULLDOWN? I need to google that and go do some reading. Thanks again for the pointers.

BTW, if you decide to implement the voltage divider, be aware that you are reducing the current of the input circuit. I think this is unlikely to matter in this specific case, but in some cases, you might end up reducing the current to a level that makes the circuit excessively prone to noise. For example, it is sometimes desirable to use a higher pulldown resistor value, such as 100 kOhm. In that case, you would also need to use a 100 kOhm resistor for your voltage divider. This would significantly reduce the current through the input circuit. Yet another reason why simply running off the 5v supply from the Arduino is preferable.

MalcolmV8:
As for the built in resistors I did not know that. Very cool. So when I have a digital input that I don't want to be floating like in my case when nobody is pressing the switch button I can simply (pinNum, INPUT_PULLUP) and it'll be the same as me putting my external resistor on there and grounding the input to be sure it's a 0 till someone presses the button? Or is that INPUT_PULLDOWN? I need to google that and go do some reading. Thanks again for the pointers.

There is only INPUT_PULLUP, which enables pullup resistors that pull the floating input up to 5v. The AVR328 doesn't have built-in pulldown resistors. If you use the built-in pullup resistors, the only difference between that and pulldown resistors is that the circuit reads HIGH when the switch is not pressed and LOW when it is pressed. This is backwards from the way it works with pulldown resistors, and is a little counter-intuitive to some humans, who are used to thinking of LOW as "nothing" and HIGH as "something". But it's well worth it to avoid having to manually wire up pullup/down reisstors.

joshuabardwell:

MalcolmV8:
As for the built in resistors I did not know that. Very cool. So when I have a digital input that I don't want to be floating like in my case when nobody is pressing the switch button I can simply (pinNum, INPUT_PULLUP) and it'll be the same as me putting my external resistor on there and grounding the input to be sure it's a 0 till someone presses the button? Or is that INPUT_PULLDOWN? I need to google that and go do some reading. Thanks again for the pointers.

There is only INPUT_PULLUP, which enables pullup resistors that pull the floating input up to 5v. The AVR328 doesn't have built-in pulldown resistors. If you use the built-in pullup resistors, the only difference between that and pulldown resistors is that the circuit reads HIGH when the switch is not pressed and LOW when it is pressed. This is backwards from the way it works with pulldown resistors, and is a little counter-intuitive to some humans, who are used to thinking of LOW as "nothing" and HIGH as "something". But it's well worth it to avoid having to manually wire up pullup/down reisstors.

Reverse logic is a small price to pay. It saves on one resistor per such circuit, PCB space and all adds up if you're building something you're selling too.
So my switch simply need be connected from D11 to ground? Almost seems to easy. Then just reverse my logic and use the INPUT_PULLUP method.

To wire the switch using input_pullup, the circuit goes: Digital_Input_Pin -> Switch -> Ground. digitalRead() will return HIGH when the switch is not pressed and LOW when the switch is pressed. In your setup() function, you set the pinMode to INPUT_PULLUP. An alternative, older way of doing this is to use pinMode(INPUT) and then do digitalWrite(HIGH), so if you ever see that in code examples, it's the same thing.

Two observations.

It’s simply good design to have pushbuttons going to ground rather than to 5V - you do not want the 5V line extended anywhere you do not absolutely need it from a safety point of view; if it is accidentally is shorted to ground, you may damage the microntroller circuit, if it is accidentally shorted to some other component, you might just cause damage to that (though the amount of power in the Arduino circuit is pretty harmless in general), or it might accidentally become connected to an external power source.

And this is the reason that pull-ups - but not pull-downs - are provided in microcontroler designs. If you want even better protection of the input line itself, you provide a separate pull-up to it, and from the point that pull-up connects to the input signal, you put an isolating resistor of say, 47k between that and the Arduino input.

Secondly, you seem to misunderstand the Arduino inputs. These are CMOS gates with an impedance of hundreds of megohms, they will not load any external circuit as long as they are within the ground and supply (yes, 5V) voltage limits. Putting (just) a resistor in series will have virtually no effect on its function as an input (except when used in ADC mode).

You have probably got away with not damaging your chip - but it is hard to say. Protective diodes in the chip will attempt to clamp the input voltage to the Vcc line (or to ground if below).

Thanks guys. That has been very informative and helped me a lot.