Your question is so close to my own project, for a second I thought it was something I posted awhile back, go figure. I don't expect you to gain from my answer, me coming along to find your question some 2 years, 5 months later. It may be of help to others who pass by this way in the future. I am currently working on the exact same variable duty cycle controller and will offer up my findings.
The following programming code is the result of apx. 5 months of study into the Arduino programming as well as a long failing attempt at getting control through a series of 555 timer chip builds. I shit canned the 555 timer chip & Darlington transistor method. I thought it was too crude, and all 'engineering' schematics never allowed me to have anything more than a 50% duty cycle control. I wanted control over all PWM variables. Today I will be purchasing a metal case, or making one that can hold apx. 5-6 potentiometers allowing me to adjust every possible variable within the PWM domain of parameters (there are more variables than what I have in this code below). I will give you some details in the code first, that will give you some idea of the obsessively precise control I'm demanding from my PWM project:
Getting into the heart of the variable HIGH/LOW control. Be sure to read everything you can to understand fully why these functions are needed. Also, know that with 10 bits the 1023 value allows a resolution of .0043 volt increments (really nice):
void loop()
{
Potentiometer1 = analogRead(PotHzHIGH);
Potentiometer1 = map(Potentiometer1, 0, 1023, 1023, 0);
Potentiometer1 = constrain(Potentiometer1, 500, 1023);
Potentiometer2 = analogRead(PotHzLOW);
Potentiometer2 = map(Potentiometer2, 0, 1023, 1023, 0);
Potentiometer2 = constrain(Potentiometer2, 500, 1023);
Potentiometer3 = analogRead(Pot5Volts);
Potentiometer3 = map(Potentiometer3, 0, 1023, 1023, 1023); //Hold at 12Volts
Potentiometer3 = constrain(Potentiometer3, 0, 1023);
//Potentiometer3 can either be locked at 12volts with the map function, or
//you can use a Potentiometer to varry the voltage. I illistrate the
//constant at 12 volts with the map function - low/high both set to
//1023 & 1023
digitalWrite(PotHzHIGH, HIGH);
//turn it ON delayMicroseconds(PotHzHIGH);
//Keep ON for Potentiometer1=PotHzHIGH Microseconds
//1000 microseconds = 1millisecond; 1000ms = 1second
digitalWrite(PotHzLOW, LOW);
//turn it OFF delayMicroseconds(PotHzLOW); //Keep OFF for
Potentiometer2=PotHzLOW Microseconds
//1000 microseconds = 1millisecond; 1000ms = 1second;
//Largest value within the delayMicroseconds function: 16383microseconds
//Largest value when converted to milliseconds is 16.383ms, or axp. 1/20th of
//...a second
}
//other things to understand about the above program. It is possible to
//have the LOW written with: delayMicroseconds(PotHzLOW+100);
//or delayMicroseconds(PotHzLOW*1.1);
//You can add an additional potentiometer to be the multiplier of the LOW.
//these added controls prevent the LOW from ever being less than the high.
//this can come in handy if you wish to work within duty cycles that are
//between 1% & 50%. It is of interest to me because I am dealing with
//high frequencies.
timkasey1@gmail.com