Reducing PWM Output Pin Frequency to 10Hz

Hi,

As stated above, is there a way to reduce the PWM output pin frequency of all pins to 10Hz?

I have tried searching for libraries and user submitted functions, but the lowest that I have been able to get was 30Hz, after using them. ( I am verifying this on an oscilloscope )

Thanks!.

Just us blink without delay technique. Very simple for 50mS high, 50mS low signal. Output can be on any pin then.

byte pin2 = 2; // output pin
byte level = 0; // flag to track high/low level
unsigned long currentTime;  // could use micros also for more precise timing
unsigned long previousTime;
unsigned long halfPeriod = 50; // milliseconds, or use 50000 for microseconds
unsigned long elapsedTime;
void setup(){
pinMode (pin2, OUTPUT);
}
void loop(){
currentTime = millis(); // capture the current time
elapsedTime = currentTime - previousTime; // how much time elapsed since last pass thru loop
if (elapsedTime >= halfPeriod) { // time to change levels?
  previousTime = previousTime + halfPeriod // set up for next level change
  level = 1-level; // will change 1,0,1,0,1,0 ...
  digitalWrite (pin2, level);
  } // end time check
// do other stuff while waiting for next level change - the "blink without delay" part!
} // end loop, go back and capture the time again

Make sense?
I took this to extremes, using arrays to keep track of button presses (not used here, but easily added), 13 levels, 13 halfPeriods, and 13 outputs all changing at once here to make a 13 note Arduino piano on a '1284P (which has 32 IO vs 20 IO on a '328P). Sketch, schematic, and youtube video all included.

You can also use a quick and dirty trick something like this example on individual pins

setup() {
pinMode( 7, OUTPUT ) ;
pinMode( 8, OUTPUT ) ;
}

loop() {
digitalWrite( 7 , (millis()%100 < 50) ? (HIGH) : (LOW) ) ; // 10 Hz 50% duty cycle Pin 7
digitalWrite( 8 , (millis()%100 < 33) ? (HIGH) : (LOW) ) ; // 10 Hz 33% duty cycle Pin 8
}

I wonder how the resulting assembly code varies between the 2 methods.

CrossRoads:
I wonder how the resulting assembly code varies between the 2 methods.

I guess modulus arithmetic is not so nicely implemented, but at 10 Hz on a 16MHz processor I don't think any one will notice.

6v6gt:
You can also use a quick and dirty trick something like this example on individual pins

setup() {
pinMode( 7, OUTPUT ) ;
pinMode( 8, OUTPUT ) ;
}

loop() {
digitalWrite( 7 , (millis()%100 < 50) ? (HIGH) : (LOW) ) ; // 10 Hz 50% duty cycle Pin 7
digitalWrite( 8 , (millis()%100 < 33) ? (HIGH) : (LOW) ) ; // 10 Hz 33% duty cycle Pin 8
}

glitches on rollover because powers of 2 are not evenly divisible by powers of 10.

Jiggy-Ninja:
glitches on rollover because powers of 2 are not evenly divisible by powers of 10.

An important point. At the millis() rollover, which occurs once approximately every 50 days, when the 4 byte counter reaches the decimal value of 4,294,967,295, there will be 5 mS truncation of the 10Hz cycle (5% cutting into the off part of the duty cycle).
Depending on the OP’s application, this could be a make or break criterion.

Thanks for the replies guys. I've just settled for turning a pin on and off, something like a soft pwm. I've just used the delay functions to generate my positive and negative pulse widths.

So, all your Arduino is doing is softPWMing the pins? No other job??? Because that will be impossible with delay(). Seems a bit like a wast to me :stuck_out_tongue: