/*
 * Project: 7-Day 360-Degree Medicine Dispenser
 * Team: ME Group 4
 * Hardware: Continuous Rotation Servo
 *
 * BEHAVIOR:
 * - Button Press -> Spins the wheel just enough to drop 1 pill.
 * - Switch OFF -> Disables the button (Safety).
 */

#include <Servo.h> // Include the Servo library for controlling the motor

// --- PIN DEFINITIONS ---
const int switchPin = 2; // Digital pin connected to the Safety Switch (D2)
const int buttonPin = 3; // Digital pin connected to the Dispense Button (D3)
const int servoPin = 9;  // Digital PWM pin connected to the Continuous Rotation Servo (D9)

Servo myServo; // Create a Servo object to control the motor

// --- CALIBRATION REQUIRED ---
// Since this is a continuous rotation servo, we control distance by TIME (milliseconds).
// This value determines how long the servo runs to rotate exactly 1/7th of a turn (one pill slot).
int dispenseTime = 300; // Start with 300ms, adjust this value until it aligns perfectly.

// --- SERVO SPEED DEFINITIONS ---
// Continuous rotation servos use speed values (0-180) instead of angle degrees.
const int STOP_SPEED = 90;  // 90 is usually "Stop." If it creeps, fine-tune to 89 or 91.
const int RUN_SPEED = 180;  // 180 is Full Speed One Way. Adjust to 0 if it spins the wrong way.

void setup() {
  Serial.begin(9600); // Initialize serial communication for debugging
  myServo.attach(servoPin); // Connect the Servo object to the physical pin (D9)
  
  // Set the button and switch pins as inputs with internal pull-up resistors.
  // This means the pin reads HIGH by default, and LOW when pressed/switched ON.
  pinMode(switchPin, INPUT_PULLUP);
  pinMode(buttonPin, INPUT_PULLUP);

  // Ensure motor is stopped immediately on startup
  myServo.write(STOP_SPEED);
  Serial.println("System Ready. 360 Mode.");
}

void loop() {
  // Check Safety Switch state (Active LOW: LOW means the switch is ON/Enabled)
  if (digitalRead(switchPin) == LOW) {
    // --- ON MODE (Dispenser is active) ---
    
    // Check if the Dispense Button is pressed (Active LOW)
    if (digitalRead(buttonPin) == LOW) {
      dispensePill(); // Execute the dispensing sequence
      
      // Anti-repeat/Debounce: Wait for the user to release the button
      // This prevents multiple dispensing actions from a single long press.
      while(digitalRead(buttonPin) == LOW) {
        delay(10);
      }
    }
  } else {
    // --- OFF MODE (Safety Switch is HIGH) ---
    // The safety switch is in the OFF position.
    
    // Ensure the motor is stopped while the safety switch is off
    myServo.write(STOP_SPEED);
  }
}

// Function to handle the motor sequence for dispensing one pill
void dispensePill() {
  Serial.println("Dispensing...");

  // 1. Start the motor rotating
  myServo.write(RUN_SPEED);

  // 2. Wait exactly enough time (the calibrated value) for the slot to move
  delay(dispenseTime);

  // 3. Stop the motor precisely
  myServo.write(STOP_SPEED);
  
  Serial.println("Dispensed.");
}
