Build a DIY CD Tray Timer with Arduino: Step-by-Step Guide

Build a DIY CD Tray Timer with Arduino: Step-by-Step Guide

This project shows how to build a simple CD tray timer that automatically opens or closes a CD/DVD drive tray after a user-set delay. It’s useful for demonstrations, kiosk resets, timed media ejection, or just as a fun hardware-and-code exercise. The design uses an Arduino Nano (or Uno), a small servo motor or a linear actuator, a pushbutton to start/reset the timer, an optional potentiometer to set the delay, and a few basic components.

Parts and tools

  • Arduino Nano or Uno (or any Arduino-compatible board)
  • Micro servo (e.g., SG90) or a small 5–6V linear actuator (servo recommended for simplicity)
  • N-channel MOSFET or small relay (if you use a drive-control mechanism that requires higher current) — not needed for servo approach
  • Pushbutton (momentary)
  • 10 kΩ resistor (for button pull-down/pull-up)
  • 10 kΩ potentiometer (optional — to adjust timer)
  • Breadboard and jumper wires
  • 5V power supply (Arduino USB or separate 5V source if using many servos)
  • Small mechanical linkage (e.g., 3D-printed bracket, zip-tie, or plexiglass arm) to connect servo horn to CD tray
  • Hot glue, screws, double-sided tape for mounting
  • Basic tools: screwdriver, pliers, wire stripper

How it works (overview)

A servo is mounted to the CD drive bezel and connected by a small arm to physically push the tray open/closed. The Arduino reads the start button and optional potentiometer (sets delay). When the button is pressed, the Arduino starts a countdown; after the delay it moves the servo to the “eject” or “close” position. The button can cancel or restart the timer.

Safety and notes

  • Do not force the CD tray; ensure your linkage moves smoothly and does not stress the drive motor.
  • If using a laptop internal drive, be careful opening the case; prefer external USB drives for ease.
  • Servos draw current—power from Arduino USB is usually fine for one small servo; use a separate 5V supply if needed.

Wiring diagram (servo approach)

  • Servo signal → Arduino digital pin D9 (PWM)
  • Servo Vcc → 5V (Arduino or external 5V)
  • Servo GND → Arduino GND (common ground if external supply used)
  • Button → Arduino digital pin D2; other button leg → GND; use internal pull-up or external 10 kΩ to 5V
  • Potentiometer (optional) → middle pin to A0, left to 5V, right to GND

Arduino sketch

cpp

// CD Tray Timer - Servo version #include Servo trayServo; const int buttonPin = 2; const int potPin = A0;// optional delay control const int servoPin = 9; int buttonState = HIGH; int lastButton = HIGH; unsigned long debounce = 50; unsigned long lastDebounceTime = 0; bool timerRunning = false; unsigned long startTime = 0; unsigned long delayMs = 10000; // default 10s // servo angles - adjust to suit your linkage const int closedPos = 90; // tray closed resting position const int openPos = 0; // tray open position void setup() { pinMode(buttonPin, INPUT_PULLUP); trayServo.attach(servoPin); trayServo.write(closedPos); Serial.begin(9600); } void loop() { int reading = digitalRead(buttonPin); if (reading != lastButton) { lastDebounceTime = millis(); } if ((millis() - lastDebounceTime) > debounce) { if (reading != buttonState) { buttonState = reading; if (buttonState == LOW) { // button pressed (active LOW) // start or cancel timer if (!timerRunning) { // read pot for delay if present int potVal = analogRead(potPin); // map 0-1023 to 1-120 seconds delayMs = map(potVal, 0, 1023, 1000, 120000); startTime = millis(); timerRunning = true; Serial.print(“Timer started: “); Serial.print(delayMs); Serial.println(” ms”); } else { timerRunning = false; trayServo.write(closedPos); // ensure closed Serial.println(“Timer cancelled”); } } } } lastButton = reading; if (timerRunning) { unsigned long elapsed = millis() - startTime; if (elapsed >= delayMs) { // toggle tray trayServo.write(openPos); delay(1000); // allow movement // after open, reset state (or close after set time if desired) timerRunning = false; Serial.println(“Tray opened”); } } }

Mechanical mounting

  1. Identify a safe location on the drive bezel where a small linkage can push the tray without obstructing eject mechanism.
  2. Attach the servo to the drive’s side or to the drive bay frame using screws or double-sided tape.
  3. Connect servo horn with a small stiff arm (plastic or metal) to the tray face so movement of the horn pushes/pulls the tray. Aim for ~15–25 mm travel — adjust servo endpoints in code as needed.
  4. Test movement manually before powering the drive: gently move the tray by hand and confirm servo positions won’t bind.

Testing and tuning

  • Power Arduino and servo, ensure servo moves to closedPos on start.
  • Press button to start timer; observe that the servo moves to openPos after the set delay.
  • If tray requires two-stage motion, add intermediate positions and small delays in code.
  • Adjust closedPos/openPos values to match physical linkage limits.

Variations and improvements

  • Use a second button to choose open vs. close action.
  • Add an LCD/OLED to display remaining time.
  • Replace servo with a small geared DC motor + limit switches for smoother force transfer on larger trays.
  • Add Wi-Fi (ESP8266/ESP32) and a web UI to set timer remotely.
  • Use infrared remote or serial commands for control.

Troubleshooting

  • Servo jitter: ensure stable 5V supply and common ground.
  • Tray doesn’t move: check linkage alignment and servo torque.
  • Drive motor stalls: increase servo travel carefully or use gentler mechanical advantage.

If you want, I can provide a 3D-printable bracket design, a version using a relay/DC motor, or an ESP32 web-control sketch next.

Comments

Leave a Reply

Your email address will not be published. Required fields are marked *