I'm not very advanced in Arduino "core" functions, so I need your help.

I'm using a Solid State Relay in order to control a heating element, with a PID Library (PID_v1.h) to obtain the OUTPUT of the PWM.

The code itself is not a problem, so that I'll not post it here.

Summarizing, this is the code where I send the PWM to the Relay: analogWrite(RELAY_OUT, outputValue);

I've found in this article that: "The analogWrite function is used to set the duty cycle of a PWM pulse train that operates at approximately 500 Hz. Thus, with a frequency = 500 Hz, the period is = 2 ms."

My concern is that the response time of the relay (FOTEK SSR-60 DA) is 10ms (to turn on or to turn off), but I DO NOT KNOW how to configure Arduino PWM to work accordingly to this Relay, in a period greater than 10ms.

I've found in some pages some people changing the clock frequency in order to have a "fast pwm", but I need to know what values I have to use to get a "slow pwm", for a period greater then 10ms.

Can you help me with that? I've been searching a lot for this answer, but I could not find any "definitive"answer.

Thank you in advance!


  • 2
    I don't think you can PWM those FOTEK SSRs at 100Hz! They only turn on at the zero crossing and stay on the while half wave. So depending on how in sync your timer is with the 50Hz of the mains, the relay will be ON all the time, or OFF all the time.
    – Gerben
    Jan 26 '19 at 15:47
  • 1
    You need a different kind of PID. Most PID code have the option to use a on/off output instead of a analog value for PWM. For a heater the minimal time between a chance can be 5 seconds to 1 minute, depending on the fysical system. Have you read this page about the relay: playground.arduino.cc/Code/PIDLibrary If you want to use that Solid State Relay, then you have to ignore its response time (it is not how fast it can be turned on and off all the time) and you have to ignore everyone else who is still talking about PWM.
    – Jot
    Jan 26 '19 at 17:07
  • Do you know how fast the physical system is? Heaters are often controlled very slowly as compared to the ~10ms zero crossing response of a SSR. House-sized furnaces often have a duty cycle more than a minute, and electric ranges have duty cycles on the order of seconds. If the heater is on at full power, how fast can the temperature change? Sampling and adjusting should be 5-20 times faster than the process time constant, and you could use the PID_v1 output with your SSR to control a heater at, for example, a 5min by 10ms = 30000 step resolution.
    – Dave X
    Jan 26 '19 at 17:58
  • 1
    Thanks a lot guys! I've tried to implement the solution using the MEGA registers as you suggested, but I think I'll not use PWM with this SSR anymore. I liked the suggestion from @Jot and will implement a on/off control. As I'm going to heat 60 liters (15 gallons) of liquid in my beer machine, I believe the period from 1 to 5 min will suit to my needs. Thank you very much for all your fast and useful replies!
    – Everton JS
    Jan 27 '19 at 22:50

I'd suggest using the TimerOne library.

Call Timer1.initialize(10000) in setup. Then call Timer1.pwm(pin, duty); in your loop. Where pin is 11, 12, or 13 for the MEGA, and duty is between 0 and 1023.

  • As a physical interpretation, this sets a 10 second duty cycle, with 10/1024=9.78ms resolution, which matches the speed specs of the SSR.
    – Dave X
    Jan 26 '19 at 18:07

Use ATmega PWM registers directly, in order to achieve about 100Hz PWM (10ms period).

This is an example of 10ms PWM period with 50% duty cycle on Arduino Mega (Pin D11):

/* Setup PWM pin D11 as Output */
   pinMode(11, OUTPUT); //D11/PB5/OC1A 

   /* Timer/Counter Control Registers: TCCRxx */
   TCCR1A = 0;            //Clear register
   TCCR1B = 0;            //Timer/Counter stopped (CS12=0,CS11=0,CS10=0)

   TCCR1A = (1<<WGM11)  | //Fast PWM mode 16-bit (WGM13=1,WGM12=1,WGM11=1,WGM10=0)
            (1<<COM1A1);  //Set output HIGH during Duty Cycle peiod of OC1A

   TCCR1B = 2                     |   //Prescaler: divide by 8
            (1<<WGM12)            | 

   /* Set PWM frequency */
   ICR1   = 20000; // Period expressed in tick (10ms)

   /* Clear PWM counter */
   TCNT1  = 0;

   /* Set duty cycle to 50% */
   OCR1A  = 10000;  

I didn't test it, but I think that it's correct.

Read this and this for details.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.