Summary
This experiment investigates dc motor speed control. Fractional factorial screening of PWM frequency, duty cycle, voltage, load inertia, and PID gain for speed accuracy and efficiency.
The design varies 5 factors: pwm khz (kHz), ranging from 1 to 25, duty pct (%), ranging from 20 to 80, voltage v (V), ranging from 6 to 24, load kg cm2 (kg*cm2), ranging from 1 to 10, and pid kp (gain), ranging from 0.5 to 5.0. The goal is to optimize 2 responses: speed accuracy pct (%) (maximize) and efficiency pct (%) (maximize). Fixed conditions held constant across all runs include motor = brushed_DC, encoder = 100ppr.
A fractional factorial design reduces the number of runs from 32 to 8 by deliberately confounding higher-order interactions. This is ideal for screening — identifying which of the 5 factors matter most before investing in a full study.
Key Findings
For speed accuracy pct, the most influential factors were pwm khz (27.9%), pid kp (27.9%), voltage v (24.6%). The best observed value was 98.0 (at pwm khz = 1, duty pct = 80, voltage v = 6).
For efficiency pct, the most influential factors were pid kp (47.8%), duty pct (26.1%), pwm khz (13.0%). The best observed value was 78.0 (at pwm khz = 25, duty pct = 80, voltage v = 24).
Recommended Next Steps
- Follow up with a response surface design (CCD or Box-Behnken) on the top 3–4 factors to model curvature and find the true optimum.
- Consider whether any fixed factors should be varied in a future study.
- The screening results can guide factor reduction — drop factors contributing less than 5% and re-run with a smaller, more focused design.
Experimental Setup
Factors
| Factor | Low | High | Unit |
pwm_khz | 1 | 25 | kHz |
duty_pct | 20 | 80 | % |
voltage_v | 6 | 24 | V |
load_kg_cm2 | 1 | 10 | kg*cm2 |
pid_kp | 0.5 | 5.0 | gain |
Fixed: motor = brushed_DC, encoder = 100ppr
Responses
| Response | Direction | Unit |
speed_accuracy_pct | ↑ maximize | % |
efficiency_pct | ↑ maximize | % |
Configuration
{
"metadata": {
"name": "DC Motor Speed Control",
"description": "Fractional factorial screening of PWM frequency, duty cycle, voltage, load inertia, and PID gain for speed accuracy and efficiency"
},
"factors": [
{
"name": "pwm_khz",
"levels": [
"1",
"25"
],
"type": "continuous",
"unit": "kHz"
},
{
"name": "duty_pct",
"levels": [
"20",
"80"
],
"type": "continuous",
"unit": "%"
},
{
"name": "voltage_v",
"levels": [
"6",
"24"
],
"type": "continuous",
"unit": "V"
},
{
"name": "load_kg_cm2",
"levels": [
"1",
"10"
],
"type": "continuous",
"unit": "kg*cm2"
},
{
"name": "pid_kp",
"levels": [
"0.5",
"5.0"
],
"type": "continuous",
"unit": "gain"
}
],
"fixed_factors": {
"motor": "brushed_DC",
"encoder": "100ppr"
},
"responses": [
{
"name": "speed_accuracy_pct",
"optimize": "maximize",
"unit": "%"
},
{
"name": "efficiency_pct",
"optimize": "maximize",
"unit": "%"
}
],
"settings": {
"operation": "fractional_factorial",
"test_script": "use_cases/278_motor_speed_control/sim.sh"
}
}
Experimental Matrix
The Fractional Factorial Design produces 8 runs. Each row is one experiment with specific factor settings.
| Run | pwm_khz | duty_pct | voltage_v | load_kg_cm2 | pid_kp |
| 1 | 1 | 80 | 24 | 1 | 0.5 |
| 2 | 25 | 20 | 6 | 1 | 0.5 |
| 3 | 25 | 80 | 6 | 10 | 0.5 |
| 4 | 25 | 80 | 24 | 10 | 5.0 |
| 5 | 1 | 80 | 6 | 1 | 5.0 |
| 6 | 25 | 20 | 24 | 1 | 5.0 |
| 7 | 1 | 20 | 6 | 10 | 5.0 |
| 8 | 1 | 20 | 24 | 10 | 0.5 |
Step-by-Step Workflow
1
Preview the design
$ doe info --config use_cases/278_motor_speed_control/config.json
2
Generate the runner script
$ doe generate --config use_cases/278_motor_speed_control/config.json \
--output use_cases/278_motor_speed_control/results/run.sh --seed 42
3
Execute the experiments
$ bash use_cases/278_motor_speed_control/results/run.sh
4
Analyze results
$ doe analyze --config use_cases/278_motor_speed_control/config.json
5
Get optimization recommendations
$ doe optimize --config use_cases/278_motor_speed_control/config.json
6
Multi-objective optimization
With 2 competing responses, use --multi to find the best compromise via Derringer–Suich desirability.
$ doe optimize --config use_cases/278_motor_speed_control/config.json --multi
7
Generate the HTML report
$ doe report --config use_cases/278_motor_speed_control/config.json \
--output use_cases/278_motor_speed_control/results/report.html
Features Exercised
| Feature | Value |
| Design type | fractional_factorial |
| Factor types | continuous (all 5) |
| Arg style | double-dash |
| Responses | 2 (speed_accuracy_pct ↑, efficiency_pct ↑) |
| Total runs | 8 |
Analysis Results
Generated from actual experiment runs using the DOE Helper Tool.
Response: speed_accuracy_pct
Top factors: pwm_khz (27.9%), pid_kp (27.9%), voltage_v (24.6%).
ANOVA
| Source | DF | SS | MS | F | p-value |
| Source | DF | SS | MS | F | p-value |
| pwm_khz | 1 | 36.1250 | 36.1250 | 2.379 | 0.1836 |
| duty_pct | 1 | 3.1250 | 3.1250 | 0.206 | 0.6691 |
| voltage_v | 1 | 28.1250 | 28.1250 | 1.852 | 0.2317 |
| load_kg_cm2 | 1 | 6.1250 | 6.1250 | 0.403 | 0.5533 |
| pid_kp | 1 | 36.1250 | 36.1250 | 2.379 | 0.1836 |
| pwm_khz*duty_pct | 1 | 6.1250 | 6.1250 | 0.403 | 0.5533 |
| pwm_khz*voltage_v | 1 | 36.1250 | 36.1250 | 2.379 | 0.1836 |
| pwm_khz*load_kg_cm2 | 1 | 3.1250 | 3.1250 | 0.206 | 0.6691 |
| pwm_khz*pid_kp | 1 | 28.1250 | 28.1250 | 1.852 | 0.2317 |
| duty_pct*voltage_v | 1 | 6.1250 | 6.1250 | 0.403 | 0.5533 |
| duty_pct*load_kg_cm2 | 1 | 36.1250 | 36.1250 | 2.379 | 0.1836 |
| duty_pct*pid_kp | 1 | 10.1250 | 10.1250 | 0.667 | 0.4513 |
| voltage_v*load_kg_cm2 | 1 | 10.1250 | 10.1250 | 0.667 | 0.4513 |
| voltage_v*pid_kp | 1 | 36.1250 | 36.1250 | 2.379 | 0.1836 |
| load_kg_cm2*pid_kp | 1 | 6.1250 | 6.1250 | 0.403 | 0.5533 |
| Error | (Lenth | PSE) | 5 | 75.9375 | 15.1875 |
| Total | 7 | 125.8750 | 17.9821 | | |
Pareto Chart
Main Effects Plot
Normal Probability Plot of Effects
Half-Normal Plot of Effects
Model Diagnostics
Response: efficiency_pct
Top factors: pid_kp (47.8%), duty_pct (26.1%), pwm_khz (13.0%).
ANOVA
| Source | DF | SS | MS | F | p-value |
| Source | DF | SS | MS | F | p-value |
| pwm_khz | 1 | 4.5000 | 4.5000 | 0.667 | 0.4513 |
| duty_pct | 1 | 18.0000 | 18.0000 | 2.667 | 0.1634 |
| voltage_v | 1 | 4.5000 | 4.5000 | 0.667 | 0.4513 |
| load_kg_cm2 | 1 | 0.0000 | 0.0000 | 0.000 | 1.0000 |
| pid_kp | 1 | 60.5000 | 60.5000 | 8.963 | 0.0303 |
| pwm_khz*duty_pct | 1 | 0.0000 | 0.0000 | 0.000 | 1.0000 |
| pwm_khz*voltage_v | 1 | 60.5000 | 60.5000 | 8.963 | 0.0303 |
| pwm_khz*load_kg_cm2 | 1 | 18.0000 | 18.0000 | 2.667 | 0.1634 |
| pwm_khz*pid_kp | 1 | 4.5000 | 4.5000 | 0.667 | 0.4513 |
| duty_pct*voltage_v | 1 | 2.0000 | 2.0000 | 0.296 | 0.6096 |
| duty_pct*load_kg_cm2 | 1 | 4.5000 | 4.5000 | 0.667 | 0.4513 |
| duty_pct*pid_kp | 1 | 18.0000 | 18.0000 | 2.667 | 0.1634 |
| voltage_v*load_kg_cm2 | 1 | 18.0000 | 18.0000 | 2.667 | 0.1634 |
| voltage_v*pid_kp | 1 | 4.5000 | 4.5000 | 0.667 | 0.4513 |
| load_kg_cm2*pid_kp | 1 | 2.0000 | 2.0000 | 0.296 | 0.6096 |
| Error | (Lenth | PSE) | 5 | 33.7500 | 6.7500 |
| Total | 7 | 107.5000 | 15.3571 | | |
Pareto Chart
Main Effects Plot
Normal Probability Plot of Effects
Half-Normal Plot of Effects
Model Diagnostics
Response Surface Plots
3D surfaces fitted with quadratic RSM. Red dots are observed data points.
efficiency pct duty pct vs load kg cm2
efficiency pct duty pct vs pid kp
efficiency pct duty pct vs voltage v
efficiency pct load kg cm2 vs pid kp
efficiency pct pwm khz vs duty pct
efficiency pct pwm khz vs load kg cm2
efficiency pct pwm khz vs pid kp
efficiency pct pwm khz vs voltage v
efficiency pct voltage v vs load kg cm2
efficiency pct voltage v vs pid kp
speed accuracy pct duty pct vs load kg cm2
speed accuracy pct duty pct vs pid kp
speed accuracy pct duty pct vs voltage v
speed accuracy pct load kg cm2 vs pid kp
speed accuracy pct pwm khz vs duty pct
speed accuracy pct pwm khz vs load kg cm2
speed accuracy pct pwm khz vs pid kp
speed accuracy pct pwm khz vs voltage v
speed accuracy pct voltage v vs load kg cm2
speed accuracy pct voltage v vs pid kp
Multi-Objective Optimization
When responses compete, Derringer–Suich desirability finds the best compromise.
Each response is scaled to a 0–1 desirability, then combined via a weighted geometric mean.
Overall Desirability
D = 0.9206
Per-Response Desirability
| Response | Weight | Desirability | Predicted | Dir |
speed_accuracy_pct |
1.5 |
|
98.00 0.9545 98.00 % |
↑ |
efficiency_pct |
1.0 |
|
77.00 0.8719 77.00 % |
↑ |
Recommended Settings
| Factor | Value |
pwm_khz | 25 kHz |
duty_pct | 20 % |
voltage_v | 24 V |
load_kg_cm2 | 1 kg*cm2 |
pid_kp | 5.0 gain |
Source: from observed run #6
Trade-off Summary
Sacrifice = how much worse than single-objective best.
| Response | Predicted | Best Observed | Sacrifice |
efficiency_pct | 77.00 | 78.00 | +1.00 |
Top 3 Runs by Desirability
| Run | D | Factor Settings |
| #4 | 0.9083 | pwm_khz=25, duty_pct=20, voltage_v=6, load_kg_cm2=1, pid_kp=0.5 |
| #5 | 0.5617 | pwm_khz=1, duty_pct=80, voltage_v=6, load_kg_cm2=1, pid_kp=5.0 |
Model Quality
| Response | R² | Type |
efficiency_pct | 0.9767 | linear |
Full Multi-Objective Output
============================================================
MULTI-OBJECTIVE OPTIMIZATION
Method: Derringer-Suich Desirability Function
============================================================
Overall desirability: D = 0.9206
Response Weight Desirability Predicted Direction
---------------------------------------------------------------------
speed_accuracy_pct 1.5 0.9545 98.00 % ↑
efficiency_pct 1.0 0.8719 77.00 % ↑
Recommended settings:
pwm_khz = 25 kHz
duty_pct = 20 %
voltage_v = 24 V
load_kg_cm2 = 1 kg*cm2
pid_kp = 5.0 gain
(from observed run #6)
Trade-off summary:
speed_accuracy_pct: 98.00 (best observed: 98.00, sacrifice: +0.00)
efficiency_pct: 77.00 (best observed: 78.00, sacrifice: +1.00)
Model quality:
speed_accuracy_pct: R² = 0.9265 (linear)
efficiency_pct: R² = 0.9767 (linear)
Top 3 observed runs by overall desirability:
1. Run #6 (D=0.9206): pwm_khz=25, duty_pct=20, voltage_v=24, load_kg_cm2=1, pid_kp=5.0
2. Run #4 (D=0.9083): pwm_khz=25, duty_pct=20, voltage_v=6, load_kg_cm2=1, pid_kp=0.5
3. Run #5 (D=0.5617): pwm_khz=1, duty_pct=80, voltage_v=6, load_kg_cm2=1, pid_kp=5.0
Full Analysis Output
=== Main Effects: speed_accuracy_pct ===
Factor Effect Std Error % Contribution
--------------------------------------------------------------
pwm_khz -4.2500 1.4993 27.9%
pid_kp -4.2500 1.4993 27.9%
voltage_v -3.7500 1.4993 24.6%
load_kg_cm2 -1.7500 1.4993 11.5%
duty_pct 1.2500 1.4993 8.2%
=== ANOVA Table: speed_accuracy_pct ===
Source DF SS MS F p-value
-----------------------------------------------------------------------------
pwm_khz 1 36.1250 36.1250 2.379 0.1836
duty_pct 1 3.1250 3.1250 0.206 0.6691
voltage_v 1 28.1250 28.1250 1.852 0.2317
load_kg_cm2 1 6.1250 6.1250 0.403 0.5533
pid_kp 1 36.1250 36.1250 2.379 0.1836
pwm_khz*duty_pct 1 6.1250 6.1250 0.403 0.5533
pwm_khz*voltage_v 1 36.1250 36.1250 2.379 0.1836
pwm_khz*load_kg_cm2 1 3.1250 3.1250 0.206 0.6691
pwm_khz*pid_kp 1 28.1250 28.1250 1.852 0.2317
duty_pct*voltage_v 1 6.1250 6.1250 0.403 0.5533
duty_pct*load_kg_cm2 1 36.1250 36.1250 2.379 0.1836
duty_pct*pid_kp 1 10.1250 10.1250 0.667 0.4513
voltage_v*load_kg_cm2 1 10.1250 10.1250 0.667 0.4513
voltage_v*pid_kp 1 36.1250 36.1250 2.379 0.1836
load_kg_cm2*pid_kp 1 6.1250 6.1250 0.403 0.5533
Error (Lenth PSE) 5 75.9375 15.1875
Total 7 125.8750 17.9821
Note: Error estimated using Lenth's pseudo-standard-error (unreplicated design)
=== Interaction Effects: speed_accuracy_pct ===
Factor A Factor B Interaction % Contribution
------------------------------------------------------------------------
pwm_khz voltage_v 4.2500 15.5%
duty_pct load_kg_cm2 -4.2500 15.5%
voltage_v pid_kp 4.2500 15.5%
pwm_khz pid_kp 3.7500 13.6%
duty_pct pid_kp 2.2500 8.2%
voltage_v load_kg_cm2 -2.2500 8.2%
pwm_khz duty_pct -1.7500 6.4%
duty_pct voltage_v 1.7500 6.4%
load_kg_cm2 pid_kp -1.7500 6.4%
pwm_khz load_kg_cm2 1.2500 4.5%
=== Summary Statistics: speed_accuracy_pct ===
pwm_khz:
Level N Mean Std Min Max
------------------------------------------------------------
1 4 93.5000 5.4467 86.0000 98.0000
25 4 89.2500 0.5000 89.0000 90.0000
duty_pct:
Level N Mean Std Min Max
------------------------------------------------------------
20 4 90.7500 5.1235 86.0000 98.0000
80 4 92.0000 3.8297 89.0000 97.0000
voltage_v:
Level N Mean Std Min Max
------------------------------------------------------------
24 4 93.2500 4.9244 89.0000 98.0000
6 4 89.5000 2.8868 86.0000 93.0000
load_kg_cm2:
Level N Mean Std Min Max
------------------------------------------------------------
1 4 92.2500 3.5940 89.0000 97.0000
10 4 90.5000 5.1962 86.0000 98.0000
pid_kp:
Level N Mean Std Min Max
------------------------------------------------------------
0.5 4 93.5000 4.6547 89.0000 98.0000
5.0 4 89.2500 2.8723 86.0000 93.0000
=== Main Effects: efficiency_pct ===
Factor Effect Std Error % Contribution
--------------------------------------------------------------
pid_kp -5.5000 1.3855 47.8%
duty_pct 3.0000 1.3855 26.1%
pwm_khz -1.5000 1.3855 13.0%
voltage_v -1.5000 1.3855 13.0%
load_kg_cm2 0.0000 1.3855 0.0%
=== ANOVA Table: efficiency_pct ===
Source DF SS MS F p-value
-----------------------------------------------------------------------------
pwm_khz 1 4.5000 4.5000 0.667 0.4513
duty_pct 1 18.0000 18.0000 2.667 0.1634
voltage_v 1 4.5000 4.5000 0.667 0.4513
load_kg_cm2 1 0.0000 0.0000 0.000 1.0000
pid_kp 1 60.5000 60.5000 8.963 0.0303
pwm_khz*duty_pct 1 0.0000 0.0000 0.000 1.0000
pwm_khz*voltage_v 1 60.5000 60.5000 8.963 0.0303
pwm_khz*load_kg_cm2 1 18.0000 18.0000 2.667 0.1634
pwm_khz*pid_kp 1 4.5000 4.5000 0.667 0.4513
duty_pct*voltage_v 1 2.0000 2.0000 0.296 0.6096
duty_pct*load_kg_cm2 1 4.5000 4.5000 0.667 0.4513
duty_pct*pid_kp 1 18.0000 18.0000 2.667 0.1634
voltage_v*load_kg_cm2 1 18.0000 18.0000 2.667 0.1634
voltage_v*pid_kp 1 4.5000 4.5000 0.667 0.4513
load_kg_cm2*pid_kp 1 2.0000 2.0000 0.296 0.6096
Error (Lenth PSE) 5 33.7500 6.7500
Total 7 107.5000 15.3571
Note: Error estimated using Lenth's pseudo-standard-error (unreplicated design)
=== Interaction Effects: efficiency_pct ===
Factor A Factor B Interaction % Contribution
------------------------------------------------------------------------
pwm_khz voltage_v 5.5000 26.2%
pwm_khz load_kg_cm2 3.0000 14.3%
duty_pct pid_kp 3.0000 14.3%
voltage_v load_kg_cm2 -3.0000 14.3%
pwm_khz pid_kp 1.5000 7.1%
duty_pct load_kg_cm2 -1.5000 7.1%
voltage_v pid_kp 1.5000 7.1%
duty_pct voltage_v -1.0000 4.8%
load_kg_cm2 pid_kp 1.0000 4.8%
pwm_khz duty_pct 0.0000 0.0%
=== Summary Statistics: efficiency_pct ===
pwm_khz:
Level N Mean Std Min Max
------------------------------------------------------------
1 4 74.0000 4.5461 68.0000 78.0000
25 4 72.5000 3.6968 67.0000 75.0000
duty_pct:
Level N Mean Std Min Max
------------------------------------------------------------
20 4 71.7500 4.9917 67.0000 77.0000
80 4 74.7500 2.2174 73.0000 78.0000
voltage_v:
Level N Mean Std Min Max
------------------------------------------------------------
24 4 74.0000 4.9666 67.0000 78.0000
6 4 72.5000 3.1091 68.0000 75.0000
load_kg_cm2:
Level N Mean Std Min Max
------------------------------------------------------------
1 4 73.2500 4.6458 67.0000 78.0000
10 4 73.2500 3.7749 68.0000 77.0000
pid_kp:
Level N Mean Std Min Max
------------------------------------------------------------
0.5 4 76.0000 1.8257 74.0000 78.0000
5.0 4 70.5000 3.5119 67.0000 74.0000
Optimization Recommendations
=== Optimization: speed_accuracy_pct ===
Direction: maximize
Best observed run: #6
pwm_khz = 1
duty_pct = 80
voltage_v = 6
load_kg_cm2 = 1
pid_kp = 5.0
Value: 98.0
RSM Model (linear, R² = 0.7756, Adj R² = 0.2145):
Coefficients:
intercept +91.3750
pwm_khz -0.1250
duty_pct +3.1250
voltage_v -0.8750
load_kg_cm2 +0.6250
pid_kp +1.1250
Predicted optimum (from linear model, at observed points):
pwm_khz = 1
duty_pct = 80
voltage_v = 6
load_kg_cm2 = 1
pid_kp = 5.0
Predicted value: 96.0000
Surface optimum (via L-BFGS-B, linear model):
pwm_khz = 1
duty_pct = 80
voltage_v = 6
load_kg_cm2 = 10
pid_kp = 5
Predicted value: 97.2500
Model quality: Good fit — general trends are captured, some noise remains.
Factor importance:
1. duty_pct (effect: 6.2, contribution: 53.2%)
2. pid_kp (effect: 2.2, contribution: 19.1%)
3. voltage_v (effect: 1.8, contribution: 14.9%)
4. load_kg_cm2 (effect: 1.2, contribution: 10.6%)
5. pwm_khz (effect: -0.2, contribution: 2.1%)
=== Optimization: efficiency_pct ===
Direction: maximize
Best observed run: #4
pwm_khz = 25
duty_pct = 80
voltage_v = 24
load_kg_cm2 = 10
pid_kp = 5.0
Value: 78.0
RSM Model (linear, R² = 0.5302, Adj R² = -0.6442):
Coefficients:
intercept +73.2500
pwm_khz +0.0000
duty_pct +2.5000
voltage_v +0.5000
load_kg_cm2 -0.2500
pid_kp -0.7500
Predicted optimum (from linear model, at observed points):
pwm_khz = 1
duty_pct = 80
voltage_v = 24
load_kg_cm2 = 1
pid_kp = 0.5
Predicted value: 77.2500
Surface optimum (via L-BFGS-B, linear model):
pwm_khz = 19.5749
duty_pct = 80
voltage_v = 24
load_kg_cm2 = 1
pid_kp = 0.5
Predicted value: 77.2500
Model quality: Moderate fit — use predictions directionally, not precisely.
Factor importance:
1. duty_pct (effect: 5.0, contribution: 62.5%)
2. pid_kp (effect: -1.5, contribution: 18.8%)
3. voltage_v (effect: -1.0, contribution: 12.5%)
4. load_kg_cm2 (effect: -0.5, contribution: 6.2%)
5. pwm_khz (effect: 0.0, contribution: 0.0%)