====== Calculating parameters for PWM ======
{{ :files:img_warning-line_b.png?nolink |}}
{{ :en:hw:08_safety-instructions_pseudo-ISO-7010-info.png?nolink |(i)}}
**Note:** \\
This tutorial calculates values **PWM_Cycle** and **PWM_Prescale** that are used in Mervis. If you are not using Mervis, than this tutorial shows you only basic principles of PWM on Unipi devices.
===== Selecting a frequency =====
One of the parameters you need to set is the frequency of the PWM. You have to set this value according to your regulated system. The rule of thumb is - the slower the system you regulate is, the lower the frequency can be and vice versa. Take for example a large water heater. It can take up to several hours to heat a large tank of water to desired temperature, therefor we don't need high frequency regulation. Even tenths or hundredths of Hz will be sufficient. For regulating a LED light, we need to set the frequency to at least 100 Hz, because lower frequencies would be visible by naked eye.
Another thing considering the frequency is the switching element you are turning ''ON'' and ''OFF''. If it is a mechanical relay, you have to use very low frequency or you could destroy it. If it is SSR relay, MOSFET or IGBT transistor, you can set couple of kHz or even MHz (always refer to the datasheet of the component).
The frequency of the PWM in Unipi depends on the used resolution. See below.
===== Resolution of the PWM =====
Second parameter of the PWM is the **resolution**. This value indicates in **how many steps** we want to divide the regulation. If the resolution is 3, we can set the duty cycle to 3 values: 0 %, 50 % and 100 %. If the resolution is 11, we can set it from 0 % to 100 % in the steps of 10 %.
In Unipi controllers, you can set the resolution up to 65536 steps.
===== The duty cycle =====
The duty cycle, as mentioned above, is the actual value of the regulation. Typically, you will encounter PWM duty cycle represented as a percentage of the ''ON'' time in regard of the period. In the Mervis however, **the duty cycle is represented by the number of resolution steps**. Let's see how to calculate this value.
resolution - 1
duty_cycle [mervis] = ------------------- * duty_cycle [%]
100
{{ :files:img_warning-line_b.png?nolink |}}
{{ :en:hw:09_safety-instructions_pseudo-ISO-7010-attention.png?nolink |(!)}}
**Attention:** \\
The only correct values of duty_cycle [mervis] are between 0 and resolution - 1. These values you will set from the program.
=== 1. example ===
resolution = 101 steps (0-100 % in the step of 1 %)
duty_cycle [%] = 34
resolution - 1 101 - 1
duty_cycle [mervis] = ------------------- * duty_cycle [%] = ------------------- * 34 = 34
100 100
For resolution of 101 steps and desired duty_cycle of 34 % we need to set the duty cycle in Mervis to **34**. That was easy, let's try something more complicated.
=== 2. example ===
resolution = 6 steps (0-100 % in the step of 20 %)
duty_cycle [%] = 40
resolution - 1 6 - 1
duty_cycle [mervis] = ------------------- * duty_cycle [%] = -------------- * 40 = 2
100 100
For resolution of 6 steps and desired duty_cycle of 40 % we need to set the duty cycle in Mervis to **2**.
===== Calculations of Mervis configuration parameters =====
Unfortunatelly, you cannot set the **frequency** and the **resolution** values in the Mervis directly. The variables for configuring PWM in Mervis are called **PWM_Cycle** and **PWM_Prescale** and you need to calculate their values according to desired **resolution** and **frequency**:
PWM_Cycle = resolution - 2
4.8 * 10^7
PWM_Prescale = ------------------------------- - 1
frequency * ( resolution - 1)
{{ :files:img_warning-line_b.png?nolink |}}
{{ :en:hw:08_safety-instructions_pseudo-ISO-7010-info.png?nolink |(i)}}
**Note:** \\
The **PWM_Cycle** and **PWM_Prescale** variables are 16 bit words, therefor you can set only integer values 0 - 65535. If the result of your calculations is real number, you need to either round it, or change the parameters **frequency** or **resolution**.
Alternatively, to get the **resolution** and **frequency** from **PWM_Cycle** and **PWM_Prescale** values, use these equations:
resolution = PWM_Cycle + 2
4.8 * 10^7
frequency = ----------------------------------------
( PWM_Cycle + 1) * (PWM_Prescale + 1)
=== 1. example ===
Resolution = 11 (duty cycle 0-100 % with 10 % steps)
Frequency = 4 kHz
PWM_Cycle = resolution - 2 = 11 - 2 = 9
4.8 * 10^7 4.8 * 10^7
PWM_Prescale = ------------------------------- - 1 = --------------------- - 1 = 1199
frequency * ( resolution - 1) 4000 * ( 11 - 1 )
=== 2. example ===
Resolution = 41 (step 2.5 %)
Frequency = 0.1 Hz
PWM_Cycle = resolution - 2 = 41 - 2 = 39
4.8 * 10^7 4.8 * 10^7
PWM_Prescale = ------------------------------- - 1 = ------------------- - 1 = 119999999
frequency * ( resolution - 1) 0.1 * (41 - 1 )
{{ :files:img_warning-line_b.png?nolink |}}
{{ :en:hw:09_safety-instructions_pseudo-ISO-7010-attention.png?nolink |(!)}}
**Attention:** \\
As you can see, with given **resolution** and **frequency**, the **PWM_Prescale** is larger than its maximum value 65535. We either have to increase the **frequency**, **resolution** or **both**.
=== 3. example ===
Resolution = 10001 (step 0.01 %)
Frequency = 0.1 Hz
PWM_Cycle = resolution - 2 = 10001 - 2 = 9999
4.8 * 10^7 4.8 * 10^7
PWM_Prescale = ------------------------------- - 1 = ------------------------- - 1 = 47999
frequency * ( resolution - 1) 0.1 * (10001 - 1 )
{{ :files:img_warning-line_b.png?nolink |}}
{{ :en:hw:08_safety-instructions_pseudo-ISO-7010-info.png?nolink |(i)}}
**Note:** \\
With increased resolution, we are able to achieve lower frequencies and vice versa. For high frequency PWM, we need to sacrifice the resolution.
===== What is the magical 4.8 * 10^7 constant? =====
In calculations of the **PWM_Prescale**, we use constant 4.8 * 10^7. The constant represents 48MHz clock source for the internal timers/counters which together with PWM_Prescale and PWM_Count set the desired frequency