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.
Happy crafting!