Final Project: Steeply!

Concept Description

For my final project, I wanted to build a structure that helps brew the perfect cup of tea. Steeply lowers a tea bag into a mug of hot water and lifts it back out once the steeping time is done. At the end, a buzzer plays a melody to alert the user that the tea is ready.

Steeply Project Image

Technical Implementation

Schematic

Circuit Schematic Diagram

Schematic Description: The three main components of the circuit are the IR receiver, the servo motor, and the buzzer. The IR receiver is connected to the Arduino's pin 3, the servo motor is connected to the Arduino's pin 9, and the buzzer is connected to the Arduino's pin 12. The IR receiver is used to receive the signals from the remote control. The servo motor is used to lift and lower the tea bag, and the buzzer is used to play the melody when the tea is ready.

Circuit

Physical Circuit Setup

Circuit Description: As shown in this image, the buzzer is wired on the breadboard while the IR receiver and servo motor are connected to the arduino/breadboard using connecting wires. I chose to wire the passive buzzer on the breadboard because it is easier to wire and it is a small component. It wasn't necessary to have it mounted on my actual structure because its only purpose is to play a melody when tea steeping is done, which can be heard through the box it is contained in. However, the IR reciever did need to be mounted on the structure because the signal from the remote control cannot be obstructed by anything.

Code

Arduino Code


            // Steeply code using IR remote

            // Include the necessary libraries for the Servo motor and IR remote
            #include IRremote.h
            #include Servo.h

            // Assign each object to its pin on the Arduino
            const int IR_RECEIVE_PIN = 3;     // IR receiver OUT pin
            const int servoPin = 9;           // Servo pin
            const int buzzerPin = 12;         // Passive buzzer pin

            // Create servo object
            Servo teaServo;

            // Pre-set tea steep times based on tea type: green, herbal, or black
            // Using 'UL' makes the number an Unsigned Long, which matches Arduino's
            // millis() timing type. This ensures long delays work correctly!
            // U = unsigned = positive integer only
            // L = long = 32-bit integer on Arduino
            const unsigned long GREEN_TIME  = 120000UL;   // 2 minutes
            const unsigned long HERBAL_TIME = 480000UL;   // 8 minutes
            const unsigned long BLACK_TIME  = 300000UL;   // 5 minutes

            // Set the two servo positions that I will be using
            const int UP_POSITION = 90;      // Tea bag lifted
            const int DOWN_POSITION = 0;     // Tea bag lowered

            // Have a default tea selection 
            unsigned long selectedSteepTime = GREEN_TIME;   // default green

            // Create a boolean variable to track the state of the button to prevent
            // automatic repeating of the cycle
            bool steepInProgress = false;     // Prevents repeating cycle

            // IR Remote button values according to my serial monitor
            const int BTN_GREEN = 12;   // user pressed "1"
            const int BTN_HERBAL = 24;  // user pressed "2"
            const int BTN_BLACK = 94;   // user pressed "3"
            const int BTN_PLAY = 64;    // user pressed "PLAY"

            // Setup function 
            void setup() {
              Serial.begin(9600);

              // Start IR receiver
              IrReceiver.begin(IR_RECEIVE_PIN, ENABLE_LED_FEEDBACK);

              // Attach servo and set its initial position
              teaServo.attach(servoPin);
              teaServo.write(UP_POSITION);

              // Print this message to the serial monitor to help with debugging
              // and to know exactly what step the computer is at in the code
              Serial.println("Steeply Ready! Use remote to choose tea type.");
            }

            // Main loop
            void loop() {

              // Check if any IR signal has been received
              if (IrReceiver.decode()) {

                // If a button on the remote has been pressed, print exactly which
                // button was pressed 
                int command = IrReceiver.decodedIRData.command;
                Serial.print("Button pressed: ");
                Serial.println(command);

                // Figure out what tea has been selected via the remote
                // Set the steep time according to which button has been pressed
                if (command == BTN_GREEN) {
                  selectedSteepTime = GREEN_TIME;
                  Serial.println("Tea type selected: GREEN (2 min)");
                }

                if (command == BTN_HERBAL) {
                  selectedSteepTime = HERBAL_TIME;
                  Serial.println("Tea type selected: HERBAL (8 min)");
                }

                if (command == BTN_BLACK) {
                  selectedSteepTime = BLACK_TIME;
                  Serial.println("Tea type selected: BLACK (5 min)");
                }

                // Start steeping tea if the user has pressed "play" on the remote
                if (command == BTN_PLAY && !steepInProgress) {
                  steepInProgress = true;
                  startSteeping(selectedSteepTime);
                }

                // Prepare IR receiver for next signal
                IrReceiver.resume();
              }
            }

            // Function to start the tea steeping process
            void startSteeping(unsigned long steepTime) {
              Serial.println("Starting steeping process");

              // Lower the tea bag slower than the default servo speed
              Serial.println("Lowering tea bag slowly...");

              // Decide direction: +1 if need to increase, -1 if need to decrease
              int step;
              if (UP_POSITION < DOWN_POSITION) step = 1;
              else step = -1;

              // Move from UP_POSITION toward DOWN_POSITION one degree at a time
              for (int pos = UP_POSITION; pos != DOWN_POSITION; pos += step) {
                teaServo.write(pos);
                delay(15);   // the delay affects the speed of the motion!
              }
              // Ensure final exact position
              teaServo.write(DOWN_POSITION);

              delay(500); // brief pause once fully lowered

              // Wait for steep time
              Serial.print("Steeping for ");
              Serial.print(steepTime / 1000);
              Serial.println(" seconds");

              delay(steepTime);

              // Now lift the tea bag slowly (reverse direction)
              Serial.println("Lifting tea bag slowly...");

              // Reverse step for lifting (invert the direction)
              step = -step;  

              for (int pos = DOWN_POSITION; pos != UP_POSITION; pos += step) {
                teaServo.write(pos);
                delay(15);   
              }

              // Ensure final exact position
              teaServo.write(UP_POSITION);

              delay(500); // pause once lifted

              // Play the buzzer melody when tea is steeped and the bag is 
              // lifted out of the cup
              playMelody();

              // Reset for the next cup of tea
              steepInProgress = false;
              Serial.println("Steep complete! Ready for next tea");
            }

            // Function to create a little melody for the passive buzzer 
            // when steeping is over. I wanted to do this so that the sound
            // isn't so jarring or "unattractive" when the tea is done steeping! 
            void playMelody() {
              Serial.println("Playing melody...");

              // Set the tone of the buzzer by mapping it to certain notes
              // small delay to create a small break between each note
              tone(buzzerPin, 660, 200);   // E5
              delay(250);

              tone(buzzerPin, 880, 200);   // A5
              delay(250);

              tone(buzzerPin, 990, 200);   // B5
              delay(250);

              tone(buzzerPin, 1320, 350);  // E6
              delay(400);

              noTone(buzzerPin);
            }
          

Code Explanation: The code for this project is relatively simple. It uses the IRremote library to receive the signals from the remote control. It also uses the Servo library to control the servo motor. The code is split into three main functions: setup(), loop(), and startSteeping(). The setup() function is used to initialize the IR receiver and the servo motor. The loop() function is used to check if any IR signal has been received. The startSteeping() function is used to start the tea steeping process. Lastly, the the playMelody() function is used to play the melody when the tea is ready.

Final Product Construction

Physical Circuit Setup

Final Product Description: Due to time constraints, I used household items to create the structure for Steeply. I cut holes in my iPad box to mount the IR receiver and the servo motor. The wires of the servo motor are hidden by the toilet paper roll. The servo controls the stick that the tea bag is attached to. All the circuitry is hidden in the iPad box!

Technical Writeup

Steeply is an automatic tea-steeping device built with an Arduino Uno, a small servo motor, an IR remote receiver, and a passive buzzer. The user picks a tea type using a remote control, Steeply lowers the teabag into hot water for the correct amount of time, and then lifts it back up when it’s done. A short melody plays to let the user know their tea is ready.

The system works like this:

The servo lowers the teabag into the cup by rotating to a “down” angle. The Arduino then keeps track of the steeping time using millis(), which lets it count time without freezing the program. When the timer is finished, the servo moves back to the “up” angle, lifting the teabag out of the water, and the buzzer plays a melody to signal that the tea is done.

Sensors/inputs:

Outputs (What the Arduino controls) Libraries Used These libraries make the project much easier by handling all the complicated parts of decoding IR codes and moving the servo smoothly.

Design Decisions This setup gives users a simple, hands-off way to make tea while also keeping the Arduino code and wiring straightforward.

Demo Video

Quick demo video to show functionality

Demo Description: These videos show Steeply in action. As you can see, the servo motor lowers the tea bag after the user selects their tea type and presses play. The servo motor also lifts the tea bag once steeping is done, and the passive buzzer plays a melody to alert the user.

If I Had More Time

If I had more time to keep improving Steeply, there are several features and design upgrades I would want to add:

Overall, these additions would make Steeply look cleaner, feel more refined, and offer an even better user experience.