#define POTENTIOMETER A0 // potentiometer pin
int potentiometer; // potentiometer reading
unsigned long onTime, offTime, totalTime = 20000; // PWM time a 20ms pulse cycle
bool onTimeFlag, offTimeFlag; // indicate xTime has finished
unsigned long currentMicros, previousMicros = 0; // timers
const byte servoPin1 = 9; // servo pin
const byte servoPin2 = 10;
void setup() {
pinMode(servoPin1, OUTPUT); // assign servo data pin
pinMode(servoPin2, OUTPUT);
digitalWrite(servoPin1, HIGH); // begin "ON" pulse
digitalWrite(servoPin2, HIGH);
}
void loop() {
potentiometer = analogRead(POTENTIOMETER); // read the potentiometer
// onTime = map(potentiometer, 0, 1023, 1000, 2000); // map potentiometer to 1000us to 2000us (1ms to 2ms)
onTime = map(potentiometer, 0, 1023, 450, 2550); // map potentiometer to 450us to 2550us for simulator
offTime = totalTime - onTime; // calculate offTime (LOW) signal
currentMicros = micros(); // start a new pulse timer
// EVENT 1 - PWM OFF - occurs at 1m to 2ms (1000us to 2000us) after start to end the HIGH pulse
if (currentMicros - previousMicros >= onTime) { // bypass this for condition 1000us to 2000us
if (onTimeFlag == 0) { // test if onTime has previously been tested
digitalWrite(servoPin1, LOW); // set pulse OFF for offTime
digitalWrite(servoPin2, LOW);
onTimeFlag = 1; // onTime is finished, do not enter this condition until end of offTime
}
}
// EVENT 2 - PWM ON - occurs every 20ms (20000us) to start a new pulse
if (currentMicros - previousMicros >= offTime) { // bypass this for condition 18000us to 19000us
onTimeFlag = 0; // offTime is finished at 20ms. Reset onTimeFlag
digitalWrite(servoPin1, HIGH); // set pulse ON to begin onTime
digitalWrite(servoPin2, HIGH); // set pulse ON to begin onTime
previousMicros = currentMicros; // previousMicros is new reference time "zero"
}
}
/*
Servo PWM without library
Most 180 degree servos use a pulse train with 5% to 10% duty cycle at 50 kHz (50000 pulses per second)
1ms to 2 ms (1000us to 2000us) ON, 18ms to 19ms OFF (18000us to 19000us) over 20ms (20000us)
_ _ x
_| |___________________| |___________________x ( 0 degrees = 1.0ms HIGH) / (19.0ms LOW)
__ __ x
_| |__________________| |__________________x ( 90 degrees = 1.5ms HIGH) / (18.5ms LOW)
___ ___ x
_| |_________________| |_________________x (180 degrees = 2.0ms HIGH) / (18.0ms LOW)
- start timer
- write PWM HIGH = begin EVENT 1
- check timer for 1ms to 2ms
- write PWM LOW = end EVENT 1
- wait 19ms to 18ms (note this is the inverse of 1ms to 2ms)
- any number of EVENTs can be started and ended at any time
*/