This is part of the Arduino-based Digital Clock series. This post is the sixth post in the series. For the previous post in this series, go to Part 5.
As I said in Part 4, now I have included the Low-Power library by Rocket Scream Electronics. I only used the powerDown function because that is the one with the lowest current draw. For my digital clock, there are 2 ways for the Arduino to wake up from the powerDown function:
- Watchdog timer.
- External interrupt.
I used the watchdog timer because the digital clock needs to wake up every one second to update the LCD screen to show the current time, and also to to wake up because of oncoming alarm. As for the external interrupt, I used it to handle button presses. Thanks to these, now the Arduino spent most of its time in powerDown, so we save quite a bit of power. Unfortunately for my purpose the external interrupt / button presses requires additional components.
Debouncing External Interrupt from Analog Buttons
Previously I used the Analog Buttons library to handle button debouncing. But now that the Arduino is mostly in powerDown, button presses doesn’t work right. This is because Analog Buttons use millis for debouncing, however powerDown stops millis. I attempted to solve this problem by using a 74HC14D IC from Nexperia, which is a hex inverting Schmitt trigger IC. Basically this is the hardware solution for debouncing. More information about using Schmitt trigger to solve debouncing by Jack G. Ganssle.
For my project I used the Schmitt triggers in 2 stages:
- Stage one: as a sort of buffer for the analog buttons (but with Schmitt action).
- Stage two: apply low pass filter to the output of stage one, and pass it into another Schmitt trigger.
I used these two stages because I used the buttons in analog multiplexing configuration. If I just used one stage with the low pass filter, the low value button press will have perceivably different “speed” compared to the high value button press. For example with just the low pass filter: the high value button press will charge the capacitor with 5V, meanwhile the lowest value button press will charge the capacitor with - say - 3V. This also apply with button release / capacitor discharge. So by adding a Schmitt action before the low pass filter, my intention is to make every button press feel they have the same “speed”.
The 74HC14 has 6 Schmitt trigger inputs, I only used 2. The other 4 is tied to ground as suggested by SN74HC14 datasheet by Texas Instruments (interestingly enough, Nexperia datasheet doesn’t say anything about what to do with unused inputs).
Also this means I no longer need the Analog Buttons library.
Previously I used LM7805 as power supply for the project. As I said in Part 4, I wanted the project to run from 18650 cell. To make this happen, I use a TP4056 charger module (with protection) and a MT308 adjustable boost converter module. I just soldered some headers to the through hole so that the modules can be used on a breadboard. They don’t line perfectly with breadboard holes, but they’re usable.
Unfortunately now I have to add another breadboard just for the power supply, and the battery holder is loose.
Less Relevant Change
Another change from Part 5, the buttons now uses diode based voltage divider instead of resistors. No special reason for this: I just wanted to see if it works and it did. All diodes in this project are 1N400x general-purpose diode. I used 1N4001 because I got a hundred of those.
Everything above (other than the diode based voltage divider) were done in the name of reducing the current draw. So first I measured current draw with the LM7805 (done before replaced with the TP4056 + MT3608):
Current Draw Measured from the Output of the LM7085 (@ 5V)
This is control measurement.
- With lowest LCD backlight: 4.8mA - 8.32mA
- With lowest LCD backlight and alarm on: 47.06mA - 48.77mA
- With highest LCD backlight: 21.75mA - 25.38mA
- With LCD backlight and alarm on: 63.8mA - 64.4mA
- Normal usage (LCD backlight at 75% turn): 5.99mA - 9.49mA
These are already better compared to Part 5.
Current Draw Measured from the Output of the MT3608 module (@ 5V)
- With lowest LCD backlight: 1.54mA - 4.92mA
- With lowest LCD backlight and alarm on: 37.87mA - 38.36mA
- With highest LCD backlight: 17.53mA - 20.64mA
- With LCD backlight and alarm on: 51.08mA - 52.64mA
- Normal usage (LCD backlight at 75% turn): 2.62mA - 6.23mA
Wow! Those are significant savings. Not as big as I hoped for, but still better than control.
Unfortunately current draw measured from the output of the MT3608 will not be the same as when measured from the cell terminals. This is MT3608 works by stepping up the voltage output. That means I have to measure again from the cell terminals.
Current Draw Measured from the Output of the TP4056 module (@ 4.047V)
Did I said from the cell terminals? Nope, too much trouble. I will measure from the output of TP4056 module.
- With lowest LCD backlight: 2.66mA - 7.68
- With lowest LCD backlight and alarm on: 61.6mA - 64.3mA
- With highest LCD backlight: 26.67mA - 31.66mA
- With LCD backlight and alarm on: 86.9mA - 88.9mA
- Normal usage (LCD backlight at 75% turn): 4.11mA - 9.18mA
So the low current usage is better than control, but the high current usage is worse.
But there’s more. The output of the TP4056 module is essentially the same as the cell voltage (minus a tiny voltage drop). And the cell voltage depends on how much charge it has. A full cell have more charge than a flat cell, and as such a full cell have higher voltage than a flat cell. That means the current draw also depends on how full is the cell. There’s no way I can check the entire range of cell voltage vs its current draw. That will require a sort of logger, something I don’t have.
Besides, there’s no point logging those when I know I am very unlikely to be able to reduce the current draw even further.
(This problem has been solved. Read update below.)
Under high current draw condition such as full LCD brightness or during alarm on, the button press often does not register. I measured the breadboard power rails under these conditions:
- Full brightness: 4.827V
- Full brightness and alarm on: 4.47V
This is probably due to loose connections becase I am using breadboards and loose wires. The voltage drop could result in unreliable ADC reading, which results in button press being ignored in checkButtons function. Or maybe the voltage drop prevents level transition on the 74HC14 Schmitt trigger and thus prevents the external interrupt to be triggered on the Arduino.
I don’t know for sure yet. I’ll check that later. (Read update below)
- I have updated the PlatformIO project source code.
- Here are where I got the Fritzing parts from:
The problem really was the loose connections on the breadboards. I changed the holes on the breadboard to which I plugged the 5V output of the MT3608 and the voltage drop decreased:
- Full brightness: 4.979V
- Full brightness and alarm on: 4.919V
After that the button presses are rarely missed by the Arduino. And when it is being missed, long (not hard) press usually make it registers.