Section 09 · Practice Questions

Pulse Width Modulation (PWM)

One problem on PLC-based pulse-width modulation — duty-cycle control from 0 to 99, timer-based pulse generation from a fixed period, a guard against the zero-duty edge case, and constructing the corresponding output waveform from a sample input.

1Question
1Worked Solution
All practice sections

PWM in a PLC is just two cascaded timers whose presets are derived arithmetically from the duty-cycle input — pick a fixed period, then split it into ON-time and OFF-time using a single MUL/DIV pair.

Q1

PWM with a user-entered duty cycle (0–99)

Write a PLC program that performs Pulse-Width Modulation (PWM). The user enters a duty-cycle value in the range 0–99 that varies the width of the output pulse (i.e. the ON-time of the output). When the input value is 50, the high and low portions of the PWM waveform have equal duration, giving a square wave with a 50 % duty cycle. When the input value is 0, the ON timer may be replaced with a brief blink pulse to avoid an error condition. Include a sample input value and the corresponding output waveform.

ShowHide worked solution

Strategy

Choose a fixed period Tperiod (here 100 ms). The ON-time is then a simple proportion of the duty input, and the OFF-time is whatever’s left of the period:

T_ON = DUTY × T_period / 100 T_OFF = T_period − T_ON

Two cascaded TONs form a self-toggling loop: T1 runs while Q is OFF, T2 runs while Q is ON. The presets T_ON and T_OFF are recomputed live from the DUTY register, so changing DUTY on the fly changes the next half-cycle’s width immediately. A guard rung handles the DUTY = 0 case by substituting a tiny 5 ms blink — a TON with PRE = 0 is undefined on many platforms.

Ladder program
Rung 1 — calculate T_ON, with guard for DUTY = 0:
|---[ DUTY = 0 ]----(MOV 5, T_ON)----|                  ← 5-ms blink fall-back
|---[ DUTY > 0 ]----(MUL DUTY, 100, T_ON)----|
|---[ DUTY > 0 ]----(DIV T_ON,  100, T_ON)----|

Rung 2 — calculate T_OFF (period − T_ON):
|---[ ALWAYS ]----(SUB 100, T_ON, T_OFF)----|

Rung 3 — ON-phase TON (runs while Q is OFF):
|---[/Q]----(TON T1, PRE = T_ON)----|

Rung 4 — set Q after T1, seal until T2 finishes:
|---[ T1.DN ]----+----( Q )----|
|                |
|---[ Q ]---[/T2.DN]------------+

Rung 5 — OFF-phase TON (runs while Q is ON):
|---[ Q ]----(TON T2, PRE = T_OFF)----|

When T2.DN fires, the seal in Rung 4 drops, Q clears, T1 restarts — cycle repeats forever.

Sample waveform (DUTY = 30)

With Tperiod = 100 ms and DUTY = 30: T_ON = 30 ms, T_OFF = 70 ms. The output sits high for 30 ms then low for 70 ms, repeating indefinitely:

Q: ___|‾‾‾|________|‾‾‾|________|‾‾‾|________ 30 70 30 70 30 70 (ms)

Setting DUTY = 50 gives a symmetric square wave (50 ms ON, 50 ms OFF). Setting DUTY = 0 falls through to the 5 ms blink guard so the timer chain never sees a zero preset.

Final AnswerT_ON = (DUTY / 100) × Tperiod. Two cascaded TONs in a self-toggling loop produce the PWM waveform. Guard the DUTY = 0 case by substituting a brief blink pulse so the timers stay valid.