// Wire the servo like so
//
// 5V --- servo red
// GND --- servo brown/black
// 9 (PWM) --- servo orange/white

#include <Servo.h> // The basic Arduino servo library

Servo myservo; // Instance a servo object called "myservo" from the library

// Variables that remain constant
const int timeServoInterval = 2; // The time in milliseconds between 1 degree rotation steps
const int timeSimUserInterval = 1000; // Every two seconds, a simulated "user" triggers a new angle
const byte pinLED = 11; // Output pin for the LED

// Variables that can change
unsigned long timeNowServo = 0;
unsigned long timeNowUser = 0;
int angleCurrent;
int angleTarget;
bool LEDState = LOW; // State the LED is in

void setup()
{
  randomSeed(analogRead(0)); // Reading the voltage from a floating (unused) pin makes "better" random numbers
  myservo.attach(9);
  myservo.write(0);
  angleCurrent = myservo.read(); // Set an initial value to start from
  angleTarget = random(10, 170); // Set an initial value to start from

  pinMode(pinLED, OUTPUT); // Set the LED pin as an output
}

void loop()
{
  simulateUserInput();
  rotateServo();
}

void rotateServo()
{
  if (millis() - timeNowServo >= timeServoInterval) // Is it time to rotate the servo towards the new target angle?
  {
    timeNowServo = millis(); // Read the current time

    if (angleCurrent != angleTarget) // In case it was time; is the current angle different from the target angle?
    {
      if (angleCurrent <= angleTarget) // If it is; check if it is smaller than the target angle
      {
        angleCurrent ++; // If it is smaller, then increase the current angle by 1 degree
        myservo.write(angleCurrent); // And rotate the servo 1 degree towards the target angle
      }
      else // Otherwise
      {
        if (angleCurrent >= angleTarget) // Check if it is larger than the target angle
        {
          angleCurrent --; // If it is larger, then decrease the current angle by 1 degree
          myservo.write(angleCurrent); // And rotate the servo 1 degree towards the target angle
        }
      }
    }
  }
}

void simulateUserInput() // Sets target angle programmatically (later from pulse sensor)
{
  if (millis() - timeNowUser >= timeSimUserInterval) // Is it time to generate a new random angle?
  {
    timeNowUser = millis(); // If so, read the current time
    angleTarget = random(10, 170); // And generate a new random angle

    LEDState = HIGH; // Then set the LED's state to on

    digitalWrite(pinLED, LEDState); // And switch the LED
  }
  else // If it was not yet time
  {
    LEDState = LOW; // Then set the LED's state to off

    digitalWrite(pinLED, LEDState); // And switch the LED
  }
}