Skip to content

PWM Output ​

Overview ​

PWM (Pulse Width Modulation) output is used to control LED brightness, servo angle, motor speed, etc. Analog control effects are achieved by varying the duty cycle.

Supported Peripheral Types ​

Typetype ValueDescription
GPIO_PWM_OUTPUT17General PWM output (LED dimming/motor speed control)
PWM_SERVO41Servo control (50Hz fixed frequency)

Parameter Description ​

PWM Output Parameters ​

ParameterDescriptionDefault
pwmChannelPWM channel (0-15)0
pwmFrequencyPWM frequency (Hz)1000
pwmResolutionResolution (bits, 1-16)8
defaultDutyDefault duty cycle0

Servo Parameters ​

ParameterDescriptionDefault
frequencyPWM frequency50
minPulseMinimum pulse width (μs)544
maxPulseMaximum pulse width (μs)2400

PWM debugging starts from low duty cycle or mid-position angle; confirm power supply and load response before connecting to automatic rules; servos and motors are recommended to use independent power supplies with common ground.

Duty Cycle Range ​

Duty cycle range is determined by pwmResolution:

  • 8-bit resolution: 0 ~ 255
  • 10-bit resolution: 0 ~ 1023
  • 12-bit resolution: 0 ~ 4095

Analog Output (AO) Mode ​

A true DAC (type=27) is only available on GPIO25/26 of the classic ESP32; other chips (S3/C3/C6, etc.) use PWM-as-AO (type=17 PWM output / type=16 analog output). With AO mode enabled, the PWM peripheral linearly maps a 0–100% input to duty cycle, and together with an RC filter or the actuator's own analog input it can be used as an AO channel:

ParameterDefaultDescription
aoModefalseEnable AO percentage mapping mode (default keeps the original PWM behavior)
aoMinPct0Output percentage lower limit corresponding to 0% input
aoMaxPct100Output percentage upper limit corresponding to 100% input

Mapping formula:

text
mappedPct = aoMinPct + (aoMaxPct − aoMinPct) × input / 100
duty      = maxDuty × mappedPct / 100
  • Out-of-range input is automatically clamped to 0–100.
  • When aoMinPct > aoMaxPct, the two are swapped automatically and the configuration remains usable.
  • Industrial actuators commonly use a 20%–80% effective window: with aoMinPct=20 and aoMaxPct=80, writing 0% yields 20% duty (signal lower limit), and writing 100% yields 80% duty (signal upper limit).
  • The mapping is implemented in the unified write path and automatically takes effect for all PWM write paths, including Web control, the rule engine, and MQTT downlink.
json
{
  "id": "ao_valve",
  "name": "Control Valve",
  "type": 17,
  "enabled": false,
  "pins": [2],
  "params": {
    "pwmFrequency": 1000,
    "pwmResolution": 12,
    "aoMode": true,
    "aoMinPct": 20,
    "aoMaxPct": 80
  }
}

Configuration ​

Before saving PWM output configuration, verify pin, frequency, resolution, and initial duty cycle.

Step 1: Navigate to Peripheral Management Page ​

  1. Open a browser and navigate to the ESP32 IP address
  2. After logging in, click Peripheral Configuration in the left menu

Step 2: Add PWM Output Peripheral ​

  1. Click the Add Peripheral button

  2. Fill in the configuration:

    FieldValueDescription
    Peripheral IDled_pwm or motor_pwmUnique identifier
    NameLED Dimmer or DC Motor Speed ControlDisplay name
    Peripheral TypeGPIO PWM Output (type: 17)General PWM
    Pin Configuration5 or 18Fill according to actual wiring
    PWM Frequency10001000Hz for LEDs, 5000Hz for motors
    PWM Resolution88-bit=0-255, 12-bit=0-4095
    Default Duty Cycle0Initial brightness/speed
  3. Click Save

Step 3: Verify Configuration ​

  1. Find the newly added peripheral in the peripheral list
  2. Click the Enable toggle
  3. Use the control panel to adjust PWM values

💡 Tip: For servos, select PWM Servo (type: 41) with fixed 50Hz frequency


Method 2: JSON Configuration File Import ​

Add the following configuration to the peripherals array in data/config/peripherals.json:

LED Dimming (8-bit PWM) ​

json
{
  "id": "led_pwm",
  "name": "LED Dimmer",
  "type": 17,
  "enabled": false,
  "pins": [5],
  "params": {
    "initialState": 0,
    "pwmChannel": 0,
    "pwmFrequency": 1000,
    "pwmResolution": 8,
    "defaultDuty": 0
  }
}

Motor Speed Control (12-bit PWM) ​

json
{
  "id": "motor_pwm",
  "name": "DC Motor Speed Control",
  "type": 17,
  "enabled": false,
  "pins": [18],
  "params": {
    "initialState": 0,
    "pwmChannel": 1,
    "pwmFrequency": 5000,
    "pwmResolution": 12,
    "defaultDuty": 0
  }
}

SG90 Servo ​

json
{
  "id": "servo1",
  "name": "SG90 Servo",
  "type": 41,
  "enabled": false,
  "pins": [16],
  "params": {
    "frequency": 50,
    "minPulse": 544,
    "maxPulse": 2400
  }
}

Peripheral Execution Integration ​

Set PWM Duty Cycle ​

json
{
  "targetPeriphId": "led_pwm",
  "actionType": 4,
  "actionValue": "128",
  "useReceivedValue": false,
  "syncDelayMs": 0,
  "execMode": 0
}

Web Interface Configuration Steps ​

Create PWM Control Rule

  1. Click Peripheral Execution in the left menu
  2. Create a rule and configure trigger (e.g., timer trigger, platform trigger)
  3. Add PWM action:
    • Action Type: Set PWM
    • Target Peripheral: led_pwm
    • Action Value: 128 (50% duty cycle, 8-bit resolution)
  4. Click Save

💡 Tip: For breathing light effect, select "Breathe" action type; actionValue is the period in milliseconds


JSON Configuration Example ​

Breathing Light Effect ​

json
{
  "targetPeriphId": "led_pwm",
  "actionType": 3,
  "actionValue": "2000",
  "useReceivedValue": false,
  "syncDelayMs": 0,
  "execMode": 0
}

actionValue is the breathing period (milliseconds)

Servo Angle Control ​

Servo is controlled via ACTION_SET_PWM(4); actionValue is the pulse width corresponding to the angle.

Script Linkage Example ​

Use command scripts to implement PWM gradient:

PERIPH led_pwm PWM 0
DELAY 500
PERIPH led_pwm PWM 1000
DELAY 500
PERIPH led_pwm PWM 2000
DELAY 500
PERIPH led_pwm PWM 4095

Notes ​

  1. Channel Conflict: Same PWM channel cannot be shared by multiple peripherals; ensure pwmChannel is unique during configuration
  2. Frequency Selection: Recommend 1000Hz for LED dimming, 5000-25000Hz for motor drive, fixed 50Hz for servos
  3. Resolution vs Frequency: Available resolution decreases at higher frequencies (ESP32 limitation: freq × 2^resolution ≤ 80MHz)
  4. Servo Power: Servos require independent power supply; do not power directly from ESP32 3.3V pin
  5. Platform Downlink: Platform can set duty cycle via [{"id":"led_pwm","value":"128"}]

FastBee | fastbee.cn