Setting PWM Frequency - 5Hz

Hi there,

I've been researching for the past hour, but can't find any solid info on reducing the Arduino PWM frequency down super low, like 5-10Hz for instance. I don't know enough about the nitty gritty of the timers etc.

I just need to run an Arduino Nano output pin at 5-10Hz and don't know the best way to go about it.

Does anyone have any code they could share that would do this?

It's purely to test a component that I know runs at 5Hz.

Hopefully this is easy enough to achieve.

Thanks in advance!

Are you looking for code that uses a hardware timer?
I think that implementation with software is sufficient for such low-frequency PWM.

1 Like

To be honest I'm not sure on what the best way would be.

If there is a simple piece of code that can be implemented to set the PWM output frequency, then that would be perfect. Simple is best🙂

Like this?

void setup() {
  pinMode(10, OUTPUT); // Must use D10
}

void loop() {

  //myPwm(duty-cycle, pwm-frquency);
  /*
    Low-frequency PWM Output at D10
    Set dutycycle must between 0   and 255 (0 is continuous LOW, 255 is continuous HIGH)
    Set frequency must between 0.5 and  50 (decimal point capable)
  */

  myPwm(127, 7.5); //e.g. (127/255)50% duty with 7.5 Hz
  delay(5000);
  myPwm(13, 10); //e.g. (13/255)5% duty with 10 Hz
  delay(5000);
  myPwm(204, 5); //e.g. (204/255)80% duty with 5 Hz
  delay(5000);
}

void myPwm(unsigned char duty, float freq) {
  TCCR1A = 0x21;
  TCCR1B = 0x14;
  OCR1A = 0x7A12 / freq;
  OCR1B = OCR1A * (duty / 255.0);
}

There is a lot of waste because it is simple.

You want to look at the prescaler register for the clock on the timer associated with the pin you want to use. However don’t use Timer 0 as that will screw up a lot of things like the baud rate and delay values.

I am not sure if it will go that slow, look in the data sheet for the chip. The code to alter this register will only be one line long.

As a new user, are you REALLY looking for 5Hz PWM, or just a 5Hz frequency generator?

Both are valid requests, but with your apparent experience it seems less likely you actually need PWM..

What’s your project and device that needs this signal ?

How about just identifying that for us?

Timer 2 (and Timer 0) won't go that slow. They bottom out near 32 Hz. You have to use Timer1.

16 MHz / 5 Hz = 3.2 million counts.
3200000 / 65536 = 48 so you need a prescale greater than 48 to fit TOP into 16 bits.
The prescale choices are 1, 8, 64, 256, and 1024 so we choose 64.
3200000 / 64 = 50000 (TOP+1)

Pick the Fast PWM mode that has TOP in a register: WGM 14: ICR1 or WGM 15: OCR1A.
Then set ICR1 or OCR1A to 49999.

You can use one of the 'Phase Correct' PWM modes but they count half as fast so you have to use half the count to get the same rate: 24999.

Why do you need to use timers?

Converting your above Text Codes into Arduino Codes for @boostedbg -- the OP. (not tested)

//5 Hz PWM signal with 50% duty cycle using TCNT1 at DPin-9 (Fig-1)
#define OC1A 9

void setup() 
{
  Serial.begin(9600);
  
  pinMode(OC1A, OUTPUT);  //5 Hz with 50% DC signal will appear on DPin-9
  TCCR1A = 0x00;   //reset
  TCCR1B = 0x00;   //TC1 reset and OFF
  //fOC1A (DPin-9) = clckSys/(N*(1+ICR1)); Mode-14 FPWM; OCR1A controls duty cycle 
  // 5 = 16000000/(64*(1+ICR1)) ==> ICR1 = 49999
  TCCR1A = (1<<COM1A1)|(1<<WGM11); //non-inverting DSFPWM, Mode-14
  ICR1 = 49999;
  OCR1A = 25000;   //~= 50% duty cycle
  TCCR1B = (1<<WGM13)|(1<<WGM12)|(1<<CS11)|(1<<CS10); //Mode-14, /64; TC1 in ON
}

void loop() 
{

}

pwmMode14nonInvert
Figure-1:

Your comments say WGM 14 but your code says WGM 15.

You also forgot to set the COM bits to enable PWM.

Corrected the codes of Post-10.

Thanks,

Yes, it has to be both 5hz & PWM. The device I am trying to use shows this in it's schematic.

It is a Toyota 12v motor driver for a variable vane turbo

@johnwasser Thanks for your help yet again mate :slight_smile:

Thank you @GolamMostafa & @johnwasser can confirm the output of pin 9 is 5hz.

In regards to changing the DC, what values would need changing?

Thank you for your help @chrisknightley , I can confirm this code also works a treat!

For those wanting to know, I am trying to replicate this signal in order to test the unit which this is the given diagram for.
PWM Spec VNT

I am using this IC Driver to up the voltage to 12v.

Configured the chip as follows;

-5v Arduino output to Pin 1
-13-14v Into Pin 9
-Ground into pin 10
-Output voltage via pin 18

I don't think you would need sub microsecond accuracy for a motor driver... but you can still reach 4 microsecond resolution with only using micros(). You don't need to use timers for this.

1 Like

Use blink LED program

I’d look back at Reply #2
Software PWM will be trivial to pull this off.