/*
Controlling a servo position using a potentiometer (variable resistor)
by Michal Rinott <http://people.interaction-ivrea.it/m.rinott>
modified on 8 Nov 2013
by Scott Fitzgerald
http://www.arduino.cc/en/Tutorial/Knob
*/
#include <Servo.h>
enum State { START, LED_ON_START, LED_ON_END, LED_OFF_START, LED_OFF_END, END };
enum ServoState { READ_PORT, SET_SERVO, WAIT, SERVO_END };
int ledpin = 13;
int ledstate = LOW;
int leddelay = 1000;
int start, ended = 0;
State state = START;
int relaypin = 12;
class ServoX: Servo {
public:
ServoX(int servo_pin, int pot_pin);
virtual ~ServoX() {}
void Init();
void Calc();
private:
int m_pin, p_pin;
ServoState m_state;
int old_val, val;
int start_wait, end_wait, duration;
};
ServoX::ServoX(int servo_pin, int pot_pin)
: m_pin(servo_pin), p_pin(pot_pin), old_val(0), val(0), start_wait(0), end_wait(0), duration(15)
{
}
void ServoX::Init() {
attach(m_pin);
m_state = READ_PORT;
}
void ServoX::Calc() {
int mval;
switch (m_state) {
case READ_PORT:
val = analogRead(p_pin); // reads the value of the potentiometer (value between 0 and 1023)
if (old_val - val) {
m_state = SET_SERVO;
}
break;
case SET_SERVO:
mval = map(val, 0, 1023, 0, 180); // scale it to use it with the servo (value between 0 and 180)
write(mval); // sets the servo position according to the scaled value
old_val = val;
m_state = WAIT;
start_wait = millis();
break;
case WAIT: // waits for the servo to get there
end_wait = millis();
if (end_wait - start_wait > duration) {
m_state = SERVO_END;
}
break;
case SERVO_END:
m_state = READ_PORT;
break;
}
}
int servo_pin = 9;
int pot_pin = 0;
ServoX myservo(servo_pin, pot_pin);
void setup() {
myservo.Init();
}
void loop() {
myservo.Calc();
switch (state) {
case START:
start = millis();
state = LED_ON_START;
break;
case LED_ON_START:
ledstate = HIGH;
digitalWrite(ledpin, ledstate);
digitalWrite(relaypin, ledstate);
state = LED_ON_END;
break;
case LED_ON_END:
ended = millis();
if (ended - start > leddelay) {
state = LED_OFF_START;
start = ended;
}
break;
case LED_OFF_START:
ledstate = LOW;
digitalWrite(ledpin, ledstate);
digitalWrite(relaypin, ledstate);
state = LED_OFF_END;
break;
case LED_OFF_END:
ended = millis();
if (ended - start > leddelay) {
state = END;
start = ended;
}
break;
case END:
state = START;
break;
}
}