Detect switch to ground

Hi all,

I'm fairly new to Arduinos and have limited experience with electronics in general.

I've run into a perplexing challenge. I have an existing switch to ground (automotive) and am trying to use its state on a pin to signal other activity with an Arduino Uno. I have no difficulty with 5V-powered switches, but detecting a closed circuit to ground appears to have bested me.

In the attached circuit (_ground_switch_pnp.jpg), the red area is not accessible (i.e. I can't insert anything between the switch and its connection to ground). Any solution must occur between the switch and the rest of the circuitry.

Code to test is typical for using switches to light up LEDs:

int pinLed      = 4;
int pinSwitch   = 11;
int switchState = 0;

void setup() {
  pinMode(pinLed, OUTPUT);
  pinMode(pinSwitch, INPUT);
}

void loop() {
  switchState = digitalRead(pinSwitch);
  if (switchState == HIGH)
    digitalWrite(pinLed, HIGH);
  else
    digitalWrite(pinLed, LOW);
}

I've tried various values for R3, as well as trying to introduce 5V into this arrangement. I also tried inserting a small PNP transistor switched by the ground (as in attached _ground_switch_pnp.jpg). No joy. Yet...

I'd like to keep the parts count down as low as possible.

Any and all suggestions are appreciated.

Dirk

dephwyggl:
Any solution must occur between the switch and the rest of the circuitry.

The "rest of the circuitry"? Are you saying, other than your Arduino, something is connected to the non-ground side of the switch?

I think all you need to do is declare pin 11 as INPUT_PULLUP so it's going to be high until the switch is closed, at which point it will go low. (So you will probably want to reverse your logic in the if, assuming you want the led to be on when the switch is closed.)

pinMode(pinSwitch, INPUT_PULLUP);

You can lose your resistor.

manor_royal:
I think all you need to do is declare pin 11 as INPUT_PULLUP so it's going to be high until the switch is closed, at which point it will go low. (So you will probably want to reverse your logic in the if, assuming you want the led to be on when the switch is closed.)

But not before answering Coding Badly's question. If there is another circuit

  1. ahere most probably already IS a pull-up, because that is the only thing with which the switch would make sense and
  2. another pull-up mightmess stuff up.

But not before answering Coding Badly's question.

True. What's not clear when OP says "switch to ground (automotive)" is if he's putting the Arduino in a car, where yep there will be some circuitry extant, or if he just meant it was a repurposed automotive switch.

That said, to say "between the switch and the rest of the circuitry" just means to me where he has his resistor, but who knows.

[quote author=Coding Badly date=1484467058 link=msg=3084980]
The "rest of the circuitry"? Are you saying, other than your Arduino, something is connected to the non-ground side of the switch?[/quote]

How about "between the switch and the Arduino"? (There is going to be more circuitry, but if I'm not able to do things like detect the state of a switch to ground...)

At this stage, I need to be able to determine the state of S1 with the Arduino. All other circuitry can wait until that's been done.

manor_royal:
I think all you need to do is declare pin 11 as INPUT_PULLUP so it's going to be high until the switch is closed, at which point it will go low. (So you will probably want to reverse your logic in the if, assuming you want the led to be on when the switch is closed.)

pinMode(pinSwitch, INPUT_PULLUP);

You can lose your resistor.

Tried, and works. I knew it had to be something really simply I was missing. ...plus, I get to decrease my parts count by one. Thank you!

Aside: The "you can lose the resistor" bit is something foundational to Arduinos - and maybe electronics generally - I don't understand. When I'm told ("read somewhere") that setting a pin to INPUT_PULLUP sets it "HIGH", I tend to think that it will now provide current to anything attached to it. I would be loathe to simply short that to ground. I looked around and it does appear that a pin set to INPUT_PULLUP can simply be grounded though. With my limited knowledge of Arduinos and electronics, I just don't understand why or how this works.

Related to "You can lose your resistor": It's possible this pin may be shorted to ground before the Arduino is powered up. Are there any precautions I should take for this? (I don't think there is, but would like to make sure.)

Clarifications:

  • This is going into a car, and re-purposes an existing switch (S1). It's just that the physical switch and where it grounds is not accessible.
  • The resistor (and any other support stuff for detecting the state of S1) - if needed at all - will be attached (eventually via a custom shield) to the Arduino.
  • I am dedicating a pin (not necessarily 11) to detecting the state of S1. (There is one more external switch identical to it which will be re-purposed in a similar manner, along with 2 more "+V" switches which source 11-15V. These "+V" switches - which use 100k/47k voltage dividers before the pin to which they're attached - are working.)
  • I mentioned using an Arduino Uno and then provide circuits illustrating the use of a Nano. I'm testing with an Uno and will be implementing with a Nano. Most of what I'm doing is unlikely to encounter difficulties translating between the two, but rest assured, I will breadboard with the Nano before implementation.

To everyone who replied: Wow. The level of participation in this forum is astonishing; thank you all.

Dirk

dephwyggl:
Aside: The "you can lose the resistor" bit is something foundational to Arduinos - and maybe electronics generally - I don't understand. When I'm told ("read somewhere") that setting a pin to INPUT_PULLUP sets it "HIGH", I tend to think that it will now provide current to anything attached to it. I would be loathe to simply short that to ground. I looked around and it does appear that a pin set to INPUT_PULLUP can simply be grounded though. With my limited knowledge of Arduinos and electronics, I just don't understand why or how this works.

The pullup is roughly equivalent to a 10K resistor. The current it provides is micro-amps. Just enough power to sense the switch and nothing else. Shorting a few micro amps to ground at 5V will use just micro watts of power. That's not going to overheat the switch. 8)

But, the automotive environment is considered to be relatively harsh for electronics. It is possible for large spikes of nearly unlimited current to be passed to your wiring. Consider what might happen if your battery is flat and someone (possibly you) connects jumper cables backwards. Every single input and output from your Arduino box must be protected to take more than +/-12V at any time. (There is a standard for this - I think it's actually +36V to -24V must be protected.)

Remember that inside the Arduino chip, there's protection diodes on every input which stop that pin voltage going more than 0.7V above +5V or 0.7V below 0V. Those protection diodes are very good but they can only pass a limited amount of current. For your nominal 12V inputs, the 100K resistor in the voltage divider makes a very good current limiter. Those inputs will have absolutely no problem with the specified fault conditions.

Your 'ground' inputs don't have that protection. The 1K resistor shown in the original .jpg is a good way to achieve that protection, although it's not enough to protect the full specified range. If you increase the value for more protection, you have to consider that it makes a voltage divider with the pullup resistor.

MorganS:
The pullup is roughly equivalent to a 10K resistor. The current it provides is micro-amps. Just enough power to sense the switch and nothing else. Shorting a few micro amps to ground at 5V will use just micro watts of power. That's not going to overheat the switch. 8)

But, the automotive environment is considered to be relatively harsh for electronics.

[...]

Your 'ground' inputs don't have that protection. The 1K resistor shown in the original .jpg is a good way to achieve that protection, although it's not enough to protect the full specified range. If you increase the value for more protection, you have to consider that it makes a voltage divider with the pullup resistor.

Thank you, Morgan! Exactly what I was looking for. The switching ground explanation helps tremendously with my understanding.

I am always thinking about how to protect the Arduino - particularly on the ground side. I thought, if - as you say - a resistor inline with the ground switch can contribute as a voltage divider with the internal 10k pull-up, perhaps a value of 4.7k (analogous to the +V switches) would work. Sure enough, it does. :wink:

As I'm also looking to increase efficiency, I'm thinking R1 at 4.7k on pin D4 makes for somewhat less current draw on that pin as well. However, reliability may be of more concern than efficiency; the wire run from R1 to S1 may be longish (2-10 feet) in the "noisy" automotive environment. Anything (more/else) I should do to ensure reliability here?

See attached for additional circuitry. A few notes and questions on this:

  • red area is inviolate (do not realistically have access to anything in here); note that wire runs to S1, S2, S3 and ground are perhaps 2-10 feet, and the run to LOAD could be 20+ feet
  • I'll likely be using something like the LM2575T-5 instead of Fritzing's PQ1CY1032Z
  • blue area is in development; I'd like to be able to view this as a TO-220-like component; a fully filtered, switching 5V power supply providing at least 0.5A (it'll be powering some other 5V devices)
  • D9ab is drawn the way it is because Fritzing doesn't have the MBR20100CT; it is dual 10A diodes with a common cathode in a TO-220 package
  • D0a, DOb, D9ab are there to ensure that S2 and S3 can be open/closed in any combination without connecting to each other
  • speaking of D0a and D0b, does anyone know of a small, maybe TO-92-like/sized, package with dual schottky 50-100V, 1A diodes with a common cathode? (I can use 1N5819s, but have shield size restrictions and am trying to save space wherever possible)
  • orange area is in development (there will be more on this in a different topic)

Any and all comments and suggestions are welcome. :slight_smile:

Dirk

There's an image guide somewhere in the forums here, which shows how to attach a picture and the edit your post to show the picture inline. Here's your picture, so that we don't have to download it to see it.

Well, thanks for using the schematic view of F**ing. That is much better than the usual breadboard view. Is it possible to use ground symbols for all the ground connections? That saves a lot of wires crossing your schematic.

I understand the "involate" area but can you be sure that there's no other connections there? I would hate to see +12V on S1 because it's still connected to (and controlling) some other device.

What's the input voltage tolerance on the LM2575? Can it handle the +36 -24V range? It is definitely worth considering a fuse between the input power and your stuff - make sure the fuse rating is low enough to blow before D0 blows. I like to use a P-type MOSFET on the input power, wired so that reverse polarity switches the MOSFET off, protecting the circuit. Then I don't need diodes at all.

Personally, I use the Pololu switching regulators to replace the entire blue area of your diagram. They are simple 3-terminal devices (or 4-terminal for the ones with a shutdown input, but you don't have to connect to that pin.) They are pretty reliable within the automotive voltage range, although I haven't tested them to the limits.

The high-side drive to the output load (yellow area) is not going to work like that. You need +12V to turn the MOSFET off and that's more than the Nano can output. There's lots of great chips available to do this for you. Personally I like the BTS716G. It's almost bulletproof in the automotive environment and it is so simple to use. SMD only but big enough to solder by hand if necessary.

I don't understand the switch logic. Two switches, either of which supplies power but only one is connected to an Arduino input. Normally you would power the Arduino from the car's "ignition" or "Acc" circuit which is on when the key is on. Then the switches are only control inputs and don't carry the power supply current.

MorganS:
Well, thanks for using the schematic view of F**ing. That is much better than the usual breadboard view. Is it possible to use ground symbols for all the ground connections?

You're welcome; sure; and inlined:

MorganS:
I understand the "involate" area but can you be sure that there's no other connections there? I would hate to see +12V on S1 because it's still connected to (and controlling) some other device.

For that specific switch, there are no other connections. (Not 100% sure of the other two switches, but will triple-check all external connections before finalizing this project's design.)

MorganS:
What's the input voltage tolerance on the LM2575? Can it handle the +36 -24V range? It is definitely worth considering a fuse between the input power and your stuff - make sure the fuse rating is low enough to blow before D0 blows. I like to use a P-type MOSFET on the input power, wired so that reverse polarity switches the MOSFET off, protecting the circuit. Then I don't need diodes at all.

Personally, I use the Pololu switching regulators to replace the entire blue area of your diagram. They are simple 3-terminal devices (or 4-terminal for the ones with a shutdown input, but you don't have to connect to that pin.) They are pretty reliable within the automotive voltage range, although I haven't tested them to the limits.

I appreciate your comments on this. I've seen mention of Pololu. I've redesigned the power supply section to use one of these (again, Fritzing doesn't have one of those, but the LM2931 is a reasonable way to represent one). What I'm not sure of at the moment is what to use for the protection MOSFET. I chose the IRF9Z34N because I have a few of them, but would be happy to sub in something that eliminates the need for D0c and R0...

MorganS:
The high-side drive to the output load (yellow area) is not going to work like that.
[...]

I'm aware of this. For me (perhaps less so for others) this is a trickier area and will be addressed later on (likely in a separate topic).

MorganS:
I don't understand the switch logic. Two switches, either of which supplies power but only one is connected to an Arduino input. Normally you would power the Arduino from the car's "ignition" or "Acc" circuit which is on when the key is on. Then the switches are only control inputs and don't carry the power supply current.

You're absolutely right. A few points:

  • there will be a 1A fuse added before Q0b, as well as a 7.5A fuse after each of JP6 and JP7
  • the +V switch (S7; was S2) is indeed IGN (+12V when ignition is on)
  • I got the other +V switch (S6; was S3) wrong; it's actually switched to ground like S1 (now S2)
  • I need S6 to provide "parallel" power to that provided via S7 (not to worry; there is a method to this apparent logical madness :wink: ). So, I did a little digging and came up with the green area. Unfortunately, this doesn't work; as soon as I close S2, the Uno's main power LED goes dim - I'm pretty sure this was a prelude to the potential release of some magic smoke and likely curtailed longevity of the Uno. :slightly_frowning_face:
  • My intent is to provide the "power up" info for S6 and S7 to the Arduino so I know which is powering things. (Didn't think the previous iteration needed the extra clutter seeing as I thought those switches were identical.) I'm not sure either of these are needed; they may be dropped (depends on programming).

Thank you for your ongoing comments, suggestions, et al, Morgan.

Cheers!
Dirk

Actually, on review, the connection between JP7 and pin D7 may not be used, but the connection between JP6 and pin 6 is required.

Edit (add explanation): S6 powers up the Arduino as well as triggering specific programming. This programming is not needed when only S7 is closed. S6 and S7 can be closed at the same time, but that is of little consequence. ...though I may change my mind as having the "both-closed" info may be of value...

Dirk

Some revisions:

  • D0a and D0b have been replaced with a dual SBR which should eliminate the need for the reverse voltage protection MOSFET and supporting bits. (I'd like to see a TO-220 cased, lower current version of the 5A piece there now...)
  • I'd like to see as little voltage drop as possible between S6/S7 and Q3, so D3ab (was a dual schottky) has been replaced with another SBR
  • I have no idea how to get the "S6 power provision" section working; what I have here is only an idea of how I think it might be done, but seem to be having difficulty getting a transistor to switch on when an Arduino pin (6 in this case) is shorted to ground

As always, suggestions and comments are most welcome.

Cheers!
Dirk

Your choice of the IRF9Z34N looks pretty good as the P-type protection/switch MOSFET. I use the FDD6637 in that position. I haven't done a close comparison of the datasheets. But the IR datasheet shows Vgs is allowed to be +/-20V, so it is pretty well protected against over and under voltage.

A P-type switches off when its gate is drawn high. It's on when the gate is LOW. So just connect the gate of Q0b to S6. Add a pullup of 1M or so, to take care of static electricity zapping the gate when the switch is open.

For a reference design on how to select power from two different power sources without dropping a lot of voltage, have a look at the Arduino schematics. (Uno, Mega, Due etc.) They have a neat little system to select USB power or the onboard 5V regulator. You don't need to have your main power coming through diodes and wasting power there.

Rev 5:

MorganS:
Your choice of the IRF9Z34N looks pretty good as the P-type protection/switch MOSFET. I use the FDD6637 in that position. I haven't done a close comparison of the datasheets. But the IR datasheet shows Vgs is allowed to be +/-20V, so it is pretty well protected against over and under voltage.

I've replaced this with the dual SBRs at D0ab; power must be isolated between S6 and S7 on the car side, hence D0ab and D3ab. ...unless there's a simple, real-estate conscious way to use MOSFETs for the same purpose which provide significant improvement on Vf. I'm looking at possible ways to simplify some of this (maybe a single, dual SBR arrangement to feed both the power supply and Q3), but in the mean time, this works. ...I think (corrections, suggestions welcome). (Note: What was Q0b is now Q0a.)

MorganS:
A P-type switches off when its gate is drawn high. It's on when the gate is LOW. So just connect the gate of Q0b to S6. Add a pullup of 1M or so, to take care of static electricity zapping the gate when the switch is open.

I should have known that (the Q3 circuitry - which you'll see when this support stuff is done - uses this to good effect). :blush: What I'm not sure of is my selection of a 2N6491 to provide power when S6 is closed. Everything on the far side of D3ab (Q3 and other stuff to come) will require up to 15 Amps. Switching performance is not an issue here, but while the 2N6491 appears to be able to do this, I'm not sure if I'm reading the specs right for its base voltage (I think it indicates 1.3-5V).

I'm wondering about R0, R6 and their "connection" to pin 6. Any concerns here?

MorganS:
For a reference design on how to select power from two different power sources without dropping a lot of voltage, have a look at the Arduino schematics.
[...]

I'm only concerned about (attempting to minimize) voltage drop going into Q3. Voltage drop on the power supply side is moot (there I'm going from a nominal 14.5V to 5v via a switching regulator). Switching from a Schottky to an SBR helps with this.

Notes:

  • Some of this project may be affected by the length of the wire runs between the external stuff, and this project. The project itself will comprise the Arduino and a shield containing the the D24V10F5 and everything else in close proximity. However, everything to the left of JP# may have longish (2-20 feet) wire runs.

  • I'm wondering if it would be worthwhile to add some largish caps between JP0 / JP7 and ground. (C0 helps, but I'm thinking trapping spikes earlier on may be worthwhile.) I don't believe any of this will be of huge concern, but I like to anticipate what I can...

Cheers!
Dirk

It's not usually necessary to add large caps to DC input power. The car battery is also a very very large capacitor so you don't need much.

C0 is recommended for the Pololu regulator to reduce the inrush current going into the regulator's caps when it's switched on. By requiring some current to charge C0 during switch-on, the input voltage will sag down due to the resistance of the power wires. So the regulator sees a voltage rise that takes a millisecond or more instead of a hard switch-on in a nanosecond. After that time, C0 does nothing.

If you are using a lot of current at Q3, then you need to calculate the voltage drop over your long wires. 20ft is significant - you can easily loose 3 volts there. There's lots of online calculators to help you pick a suitable wire gauge.

Thank you for your comments, Morgan.

MorganS:
It's not usually necessary to add large caps to DC input power. The car battery is also a very very large capacitor so you don't need much.

C0 is recommended for the Pololu regulator to reduce the inrush current going into the regulator's caps when it's switched on. By requiring some current to charge C0 during switch-on, the input voltage will sag down due to the resistance of the power wires. So the regulator sees a voltage rise that takes a millisecond or more instead of a hard switch-on in a nanosecond. After that time, C0 does nothing.

I was just thinking that placing them closer to the source of spikes may be worthwhile, but in hind sight, the distances involved here are negligible.

MorganS:
If you are using a lot of current at Q3, then you need to calculate the voltage drop over your long wires. 20ft is significant - you can easily loose 3 volts there. There's lots of online calculators to help you pick a suitable wire gauge.

I have no control over anything to the left of the JP connector; wire size there is what it is. I was only wondering if there is anything I can do on the right to mitigate any "long wire" issues. I really don't think there is, but never hurts to have a second opinion - especially from someone who clearly knows significantly more than I do about these things. :smiley:

Speaking of second opinions, here is what I think could be the last iteration of the support circuitry. The only major change from the last one is that D0ab and D3ab have been replaced with a single SBR (D0ab) that feeds all 12 volt wiring (instead of having significant duplication of wiring and rectifiers), and D0ab has been upped to a 30A version of what was at D3ab before:

Comments, suggestions, etc. are most welcome.

Cheers!
Dirk

So Q3 is still "future"? It's not going to work that way around. Look at the intrinsic body diode shown in your schematic. Current will flow through that when the MOSFET is "off".

MorganS:
So Q3 is still "future"? It's not going to work that way around. Look at the intrinsic body diode shown in your schematic. Current will flow through that when the MOSFET is "off".

Yes, Q3 and "black box" are coming soon. 8) I'm aware it won't work the way it's currently shown (hence the "black box"). I'm working on cleaning up some previous work done in this area and will post a new topic with a link from this one.

I am always thinking about how to protect the Arduino - particularly on the ground side. I thought, if - as you say - a resistor inline with the ground switch can contribute as a voltage divider with the internal 10k pull-up, perhaps a value of 4.7k (analogous to the +V switches) would work. Sure enough, it does. :wink:

As I'm also looking to increase efficiency, I'm thinking R1 at 4.7k on pin D4 makes for somewhat less current draw on that pin as well. However, reliability may be of more concern than efficiency; the wire run from R1 to S1 may be longish (2-10 feet) in the "noisy" automotive environment. Anything (more/else) I should do to ensure reliability here?

Ferrite Cores