I know it’s been a few months, but thought I’d chime in here.
You mentioned that you’re using a microswitch to control the input. I’m going to guess you’re using an SPST switch, the kind with only two leads on it. (Or maybe an SPDT or other switch but only using two of the leads, which effectively turns it into an SPST switch.)
That kind of circuit generally needs a pull-up or pull-down resistor. An input without anything connected has no specific voltage, not even 0. We refer to these as “floating” inputs.
An analogy that I use is this: it’s like a feather. If somebody holds the feather at five meters above the ground, and you measure the feather’s height, you get a measurement of five meters. If somebody pulls it to the ground, you get a measurement of zero meters. But if nothing’s pulling the feather in any direction, then its height is random; it depends on the air currents, the behavior of the guy measuring it, the local gravity, where it was last, etc.
In the same way, a pin that’s not connected to anything becomes random. It gets stray electrons moving to and fro, it gets tiny currents from radio waves and other nearby circuits, and so forth. This is a floating input, and it’s the principle behind some decent random number generators.
To avoid this situation, we use a pull-up or pull-down resistor. This is attaching a very loose spring to the feather. (I’m stretching the analogy, but I hope you’ll bear with me.) If you attach one end of the spring to the feather, and the other end to the ceiling, then the feather gets pulled up. Somebody can still pull it down, but once they let go, the feather goes back towards the ceiling. You can also attach the spring between the feather and the floor, if you want to pull the feather to the ground. Now you can reliably know where the feather will be if nobody’s pulling it one way or another.
Now, for your design, you probably are connecting the switch between 5v and the pin. You expect that when you close the switch, the pin reads 5v. But when you open the switch, you probably expect the pin to read 0v. To do that, you need a pull-down resistor.
You can’t use the internal resistors in the mode you need, so what do you do? You can use an external resistor. You connect a 10kohm resistor between the pin and ground. (You still have your switch between the pin and the 5v line.) Now, when you close the switch, the 5v line (which has almost no resistance) is pulling the pin to 5v. The path to ground has so much resistance that it doesn’t affect the voltage as long as that big, wide-open 5v path is available. (It actually does give a path from 5v to ground, but through a 10kohm resistor, that path only will drain 0.5 mA of current. Just don’t let there be a path straight from 5v to ground without a resistor, or you can cause some damage.) Then, when you open the switch, any stray voltage left over on the input will work its way through the resistor to ground and you’ll read a nice, clean 0v. (You can see this circuit at https://www.arduino.cc/en/tutorial/button).
You can actually improve on that idea a little bit. I just proposed putting the switch between the input and 5v, and a pull-down resistor between the input and ground. What if you reverse these? Instead, you put a pull-up resistor between the input and 5v, and put your switch between the input and ground. Now, your input will sit at 5v most of the time. (You might worry about wasting electricity like that, but the input barely lets any electricity at all flow. We refer to it as a “high impedance” input.) But when you close the switch, it gets pulled straight to ground.
How is this an improvement? Because it opens the door for us to use the internal resistor on the chip, instead of an external one. The internal pull-up resistor is placed (by the manufacturer, not us) between the 3.3v supply and the input. Our switch would go from the input to ground.
Now that we’re using the built-in 3.3v supply, instead of an external 5v supply, we don’t have to worry about the level shifting requirement to not use the internal pull-up resistor.
Indeed, over Christmas break I built a project that had a switch configured just like that. I had the switch between the input pin and ground, and no external pull-up resistor or connection to the power supply or anything. (I mean, my microcontroller was still connected to the power supply of course!) In the code, you tell it
pinMode(name, INPUT_PULLUP);. With that, the chip will connect its built-in pull-up resistor; that will keep the voltage at a stable 3.3v when the switch is open, but will still let the voltage drop to ground when it’s closed.
(One other note: you can generally use any resistor from about 4.7kohm to 100kohm or so for a pull-up or pull-down resistor, if you don’t have a 10kohm handy. The internal resistor on the Photon is 40kohm. Lower resistance is compatible with more stuff, but higher resistance wastes less power. 10kohm is what I usually use as a good middle-of-the-road choice.)
Just remember that you’re not allowed to use the internal pull-up or pull-down resistors when you’re connecting something at 5v. Only use it if your connections stay between 0 and 3.3v. In my final proposed design, you have the switch connecting to ground (0v), so you’re fine.
I hope this clears up pull-up and pull-down resistors. If you built this circuit and it didn’t work, I hope this helps explain why, and gives you an idea of how to proceed. I had the same confusion when I first started building digital circuits and tried to control them with switches.
By the way, a lot of digital outputs (like the ones in I2C) have a similar design: there’s a digital switch (a transistor) that connects them to ground to output a
LOW logic level, but they just leave the output floating for a
HIGH level. This is called “open drain” or “open collector” (depending on the type of transistor), and it’s why you’ll also see references to pull-up resistors when connecting certain board’s inputs to other board’s outputs.