The TIMESQUARE watch is activated by pressing either of the two side buttons. The time will be displayed for several seconds and the watch then turns off.
The ATmega microcontroller (MCU) spends most of its time in a very low-current power-down mode. The MCU pins to which the two buttons are connected were very carefully chosen — only these two pins support interrupt on change while asleep, which is used to revive the watch and enable the display.
To minimize components, the internal pullup resistors are used on these pins. The buttons then simply connect between the two pins and ground. When the switch is open (button not pressed), what would normally be an unstable “floating” input is instead “pulled up” to VCC, which the MCU reads as a high logic level. Pressing a button creates a much lower resistance connection to ground, which is read as a low logic level.
Although the TIMESQUARE MCU could monitor its own voltage, we’d prefer to keep the device running only the actual watch code being tested, so as not to color the results. A separate microcontroller — an Arduino Uno — will record the measurements to an SD card. The + output from the 3V battery is connected to an analog input pin on the Arduino, and the Arduino’s 3.3V output is routed to the AREF pin.
There are a couple of different ways this could be wired up. Given what we know from the pullup-vs-ground explanation above, we might be inclined to connect the watch input pin to one of the Arduino’s digital output pins, then call the digitalWrite() function, passing HIGH or LOW to simulate an open or closed button state…but this won’t work correctly! Most microcontrollers are opportunistic in finding usable voltage, and the watch will be perfectly happy to use power from the default HIGH logic state on that pin instead of the battery! This will skew the results horribly…it’s worse than useless.
The traditional way around this is to use an optocoupler such as a 4N35 to isolate the voltages. The digital output from the Arduino drives an infrared LED inside the 4N35, which activates a phototransistor on the opposite side — wired to the watch — effectively pressing the button without injecting additional current into that circuit. Cool.
We could just do that and call it done, but:
- I had no optocouplers on-hand, and didn’t want to wait for an order to arrive.
- There’s a technique I’ve been wanting to use in a tutorial forever…
Connecting directly to an Arduino digital pin (as was “wrongly” proposed), there is a way to simulate the button press without feeding current into the watch circuit. It’s not suited for every situation, but here it’s a fortunate side-effect of the pullup-and-button design of the circuit. The trick is to never set the output pin HIGH. Yet we can still control the watch. Buhhh?
As a “software guy” who only stumbled into electronics much later, the implication of an MCU pin’s “tri-state output” and “high-impedance state” eluded me for the longest time…my eyes would glaze over at the jargon. If you’re in that same boat, hopefully this will clarify the situation, while also solving the problem at hand…
My naïve interpretation of HIGH and LOW pin states used to imagine HIGH as providing 5 Volts out, and LOW as being essentially an open circuit, passing no voltage. Such a model makes perfect sense when you’re blinking an LED (a favorite pastime!), but it’s not accurate. Rather, HIGH is a connection to VCC, LOW is a connection to ground…or, in jargon terms, they source and sink current, respectively. To block the flow of current, we have to set the pin as an INPUT. That’s the third state in “tri-state output.”
Or picture it this way: in school they made us watch dull fire safety films, where we learned not to throw doors open, but feel for heat first (indicating fire on the other side). That’s a fair model for voltage and MCU pins. As an INPUT — door closed — we can sense heat (or not) outside without letting fire pass through; the door impedes the fire’s progress. The high-impedance state. As an OUTPUT — door open — fire can now pass either way, whether flowing in (LOW) or out (HIGH). Three states. Tri-state.
So that’s how we control the watch. Setting and leaving the Arduino pin’s state LOW, then switching between INPUT (open circuit) and OUTPUT (closing the connection to ground), we’re performing the very same function as the button, without passing any voltage from the Arduino to the watch. Our battery measurements should be fairly accurate now.
Do keep that optocoupler technique in mind though…it’s still a valid approach, and there are many other situations where they can be quite handy!
Here’s the completed testing fixture. It’s not much to look at…an Arduino, a Data Logging Shield, and wires soldered to the watch circuit’s positive and negative connections, and one button:
(Ignore the extra components in the prototyping area on the shield…it was previously in use for another project, but those have no influence here.)