Need a low frequency (can preset at each value of 15Hz to 25Hz) PWM signal

Exactly, like that. Just calculate the on/off periods. The same if you would use timer interrupts, then the moment the interrupt is called set the pin and reset the timer to reflect onTime or offTime as appropriate.

unsigned int period = 500; // 500 ms period.
float dutyCycle; // 20% duty cycle.
unsigned long lastChange = 0;
bool signal = LOW;

void loop() {
  dutyCycle = map(analogRead(potPin), 0, 1023, 1500, 8500) / 10000.0; // returns 0.15-0.85 based on the analog reading 0-1023.
  unsigned int onTime = period * dutyCycle;
  unsigned int offTime = period * (1 - dutyCycle);
  if (signal == HIGH) {
    if (millis() - lastChange > onTime) {
      signal = LOW;
      lastChange += onTime;
    }
  else {
    if (millis() - lastChange > offTime) {
      signal = HIGH;
      lastChange += offTime;
    }
  }
  digitalWrite(outPin, signal);
}

This should do. Not tested or even compiled.

1 Like