PWM

The pwm functions generate a PWM (Pulse Width Modulation) signal on a logical obniz IO pin. Because the pin is specified by its logical obniz IO number, the same code runs on obniz Board as well as on the ESP32 family.

The number of PWM channels that can run at the same time is limited. Each call to pwm.start() reserves one channel, and pwm.stop() releases it.

Available for OS7.1.0 and later


pwm.start(io)

Starts PWM output on the specified IO pin.

The pin is reserved for PWM, switched to output, and initialized at a default frequency of 1,000 Hz with a duty cycle of 0%.

Arguments

Argument Type Description
io number The logical obniz IO pin number.

Return Value

Returns a numeric status code.

Value Meaning
0 Started successfully, or PWM was already running on this pin.
1 The specified IO number is invalid.
2 No free PWM channel is available.

pwm.freq(io, hz)

Sets the frequency of the PWM signal in hertz.

The current duty cycle is reapplied automatically after the frequency changes.

Arguments

Argument Type Description
io number The logical obniz IO pin number on which PWM has started.
hz number The frequency in hertz.

Return Value

Returns a numeric status code.

Value Meaning
0 Set successfully.
1 PWM has not started on the specified pin.
2 The specified frequency is out of range (0 or greater than 80 MHz).

pwm.duty(io, percent)

Sets the duty cycle of the PWM signal as a percentage. Values below 0 or above 100 are clamped to that range.

Arguments

Argument Type Description
io number The logical obniz IO pin number on which PWM has started.
percent number The duty cycle from 0 to 100.

Return Value

Returns a numeric status code.

Value Meaning
0 Set successfully.
1 PWM has not started on the specified pin.

pwm.stop(io)

Stops PWM output on the specified pin and releases both the PWM channel and the IO pin.

Arguments

Argument Type Description
io number The logical obniz IO pin number.

Example: Breathing LED

The following example fades an LED connected to IO1 up and down by updating the duty cycle every 50 milliseconds.

local io_num = 1
local duty = 0
local step = 5
local tick = 0

os.log(" - Lua PowerOn");

-- Start PWM at 1kHz and a duty cycle of 0%
pwm.stop(io_num);
pwm.start(io_num);
pwm.freq(io_num, 1000);
pwm.duty(io_num, duty);

function on_offline_loop()
  loop()
end

function on_online_loop()
  loop()
end

function loop()
  -- Update the duty cycle every 50ms to fade the LED in and out
  if tick + 50 < os.getTick() then
    tick = os.getTick()
    duty = duty + step
    if duty >= 100 then
      duty = 100
      step = -step
    elseif duty <= 0 then
      duty = 0
      step = -step
    end
    pwm.duty(io_num, duty)
  end
end