In most DIY grow boxes the fan runs either at 100% or not at all. Sometimes in between, via a cheap dimmer controller that causes the motor to oscillate and produces a high-frequency whine that goes through walls.
PWM — Pulse Width Modulation — does it right: stepless speed control, silent, energy-efficient, with feedback on actual RPM. The Growix system controls three independent fan circuits with it.
What PWM is — the basics
PWM switches a motor's control signal very rapidly between 0 and 100%. The motor integrates these pulses due to its inertia into an average speed. The duty cycle — the percentage of time the signal is HIGH — determines the effective speed.
The frequency — why 25 kHz is non-negotiable
PWM at low frequency — 50 Hz, 200 Hz, even 1 kHz — is within human hearing range. The motor responds to each pulse as a mechanical event: coil engages, releases, engages. This creates a buzzing or whining noise.
| PWM Frequency | Noise | Suitability for grow |
|---|---|---|
| 50–200 Hz | Loud buzzing, clearly audible | Not suitable |
| 1–5 kHz | High-pitched whine, annoying | Poor |
| 10 kHz | Borderline audibility | Acceptable |
| 25 kHz | Above hearing range (> 20 kHz) | Recommended — silent |
| 40+ kHz | Ultrasound, switching losses increase | Not necessary |
25 kHz is the standard PWM frequency target value for PC fans (4-pin standard). The Growix uses this frequency on all three channels. The result: 48–50 dB sound level at 1 metre — barely perceptible in operation through the closed box.
3-pin vs. 4-pin fans
| Type | Speed control | RPM feedback |
|---|---|---|
| 2-pin | Voltage (inefficient) | No |
| 3-pin | Voltage or PWM (limited) | Yes (tach signal) |
| 4-pin | True PWM (25 kHz) | Yes (tach signal) |
The Growix uses exclusively 4-pin fans. The tachometer signal typically outputs 2 pulses per revolution — the Pi reads these pulses and calculates the actual RPM. This means: the controller always knows if a fan is blocked or has failed.
Minimum duty cycle — the stall threshold
PWM is non-linear. Below a certain duty cycle, a fan no longer starts reliably. This stall threshold lies at 10–30% duty cycle depending on the fan. Growix OS calibrates this threshold automatically at first start for each channel:
# fan_calibration.py
def find_stall_threshold(pwm_channel, tach_pin):
"""Find the minimum duty cycle at which the fan runs stably."""
for duty in range(5, 50, 5):
set_pwm(pwm_channel, duty, freq_hz=25000)
time.sleep(2)
rpm = read_tach(tach_pin)
if rpm > 100:
return duty # Stall threshold found
return 30 # Fallback
The three fan circuits of the Growix
| Channel | Function | PWM Range | VPD response |
|---|---|---|---|
| Intake | Bring in fresh air | 30–80% | Increase when VPD too high |
| Exhaust (+ filter) | Remove air + odour | 50–100% | Increase at high VPD / high RH |
| Circulation | Air movement at canopy | 20–70% | Slight increase at stress signals |
Growix OS keeps exhaust permanently slightly stronger than intake — this creates the desired negative pressure that prevents odour seepage. When VPD deviates by more than 0.15 kPa, the system responds with stepped ventilation increases — first exhaust, then intake — to dampen VPD fluctuations rather than amplify them.