Introduction: A Tiny Tea Timer (TTT) Machine for Arduino and ATtiny
The TinyTeaTimmer (TTT) is an implementation for a small accessory that can easily be assembled and programmed using a switch, a button, 1 or 2 LEDs, a small servo motor and an Arduino board or an ATTiny processor.
You can find the sketch files in the attached zip file.
There are several implementations and stories about this kind of helpful machine. I realized one together with my daughter and found a lot of material on these sites:
The project was inspired by these articles on instructables and other web sites. These articles focus on the
mechanical and electrical installation and are really worth to be read. In this article I like to focus on the software part of a TeaTimer.
This implementation avoids complicated electronic parts but still offers the capability of programming different brewing times. It just has one switch to turn on and off and only needs one press button for setting up the brewing time. The LED is really optional (but somehow beautiful) and you may include a second LED to show that the timer is switched on.
Step 1: Functionality Design and Programming
The idea of the functionality of the Arduino Script can be seen in this graph.
- After switching on the power the servo motor moves to the initial position and waits for a tea
bag to be attached.
- Then the button is pressed several times – one time for each brewing minute.
- When the button is not pressed more than 2 seconds the servo motor moves to the brewing
position and counting starts.
- When the brewing time is over the servo motor moves back to end position (same as the starting position) and power can be switched off.
I have provided 2 versions of the script.
The first one is implemented for a standard Arduino board and was in use for some time and is great for making
changes to the program without a programmer. The second one is implemented for using an ATtiny85 processor.
It started as a simple version very similar to the software scripts you can find in the other examples. But it turned out that there had to be some additions to make it really useful for everyday usage se I had several more requirements to be implemented. These enhanced versions are available here.
A small state machine
The program always needs to know the current situation from the time when the power was switched on until the brewing time is over. Therefore there is a global variable named state that can take the appropriate value corresponding to the situation:
In the picture above you can see how the states are used. It is a straight forward implementation except of the repeating when the button is pressed multiple times during the programming phase.
To have a good readability the possible state values are defined in the constant section of the script:
#define STATE_INIT 0x00 ///< Waiting for first button down
#define STATE_DOWN 0x10 ///< The button is pressed
#define STATE_UP 0x11 ///< The button is released so increment the tea-time by one.
#define STATE_ENTER 0x21 ///< entering the brewing phase by showing the number of minutes
#define STATE_BREW 0x22 ///< enter the tea bag and wait until end of brewing time
#define STATE_END 0x99 ///< brewing time ended.
Servo / tea bag positions
The positions that we need for the servo have to be found by trial and error because they depend on the concrete design of the tea timer and the servo. For a simple design 2 positions are enough (INITIAL and ENTER). They are defined in the constant section of the script:
#define TEABAG_INITIAL 95
#define TEABAG_ENTER 65
#define TEABAG_DIP 70
#define TEABAG_OUT 83
These are the positions for the initial state to attach a tea bag, the brewing position, a small movement that was requested by some users and the out position, not too high so that the last drops may fall into the tea pot. In the end the servo is moved to the initial position to detach the tea bag.
Moving the servo slowly
The most wished enhancement from the first version was to make the servo moving slowly instead of the simple "as quick as possible" version implemented in first version. Therefore the tbSetPosition method doesn't move the servo directly but instead records the destination position in a global variable. Then from time to time by calling the tbCheckPosition function the current position of the servo is modified by 1 in the desired direction. Finally, when the servo has reached the destination position the servo is detached to save energy.
The variables tbPosition and tbPositionNext store the current and the desired position.
Moving the servo under heavy load
The first version detached the servo immediately after moving it to the new position. However with heavy load the servo doesn’t reach its final destination in a reliable way. This was solved by using the specific timer variable tbLastMove that is always set to the current time after moving the servo.
The servo is detached 400 msec. after the last movement.
Watching the time
The easiest way for controlling the time dependent functions is to use the millis() function that returns the number of milliseconds passed since the startup.
I use this function to get the “current time” and compare it to the last time when something interesting has happened.
Every time the loop() function starts, the now variable is set and the duration of the current phase is calculated by using the variables:
unsigned long now;
unsigned long started;
unsigned long duration;
This approach is by far better than using the delay() function for implementing the overall timing mechanism. However, sometimes it is just easier to use delay() for example for switching the LED on and off or waiting some milliseconds until the servo got moved.
There are some timing constants defined in the header of the sketch that you might adjust to your needs:
#define MSECS_TO_START 2000 ///< When button is not pressed since 2 seconds, the start brewing.
#define MSECS_FOR_DROPS 10000 ///< the number of seconds the bag is nearby over the tea pot.
#define MSECS_TO_DETACH 400 ///< after 400 msecs of no movement the servo is detached to save energy.
The minimum time in milliseconds that a button press has to last for being taken serious is programmed as 50. It happens often that a button doesn't switch the signal in a proper way but bounces once or twice before closing completely. These small fast sequences are just ignored.
Before starting the LED blinks once for every brewing time minute.
Reset and try again
Sometimes it happens that the TTT doesn't start correctly because the tea bag jumps off or doesn't like to go diving the number of programmed minutes was wrong. In this case you have to switch off and on again.
I included more comments in the source code. Read and modify…
Step 2: Using an ATTiny85 Processor
Here is the schema of the board I built using an ATtiny85 processor.
Most of the place is needed to build the power adaption from a 9V battery to the 5V needed by the servo and the ATtiny processor.
The bipolar capacitors need to have any capacity from 1µF to 100µF and should be able to handle 12 V or more.
The ceramic capacitor next to the chip should have 100nF.
The 7805 needs no heat sink with this load.
The software you need for compiling and uploading this to an ATtiny85 processor I used can be found at:
Because I used the 1.6.1 ide of Arduino environment I had to select the ide-1.6.x branch before downloading. You should put these files into your Sketches\hardware folder.
The Servo library for ATtiny processors I use is available at: https://github.com/solderspot/Servo8Bit/trunk.
You should put these files to your Sketches\libraries\ folder.
Step 3: Mechanics, Soldering and Wires
Here are some more pictures for you from the final machine and the Arduino breadboard used for implementing and a detailed look to the electronics and cabling.
The layout of the electronic parts for the ATtiny85 breadboard are very similar to the schema shown above.
The Arduino UNO board you can see on the last picture was used to implement the features on the desktop.