Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

37 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

AutoFan

Code license: MIT Hardware license: CC BY-SA 4.0 Firmware: CircuitPython

A custom CircuitPython controller for an AC Infinity Cloudline S6 axial fan that can automatically turn on based on a current sensor. Useful for external exhaust fans on laser systems — the fan engages automatically whenever the laser starts lasing.

The controller supports two modes:

  • Auto — the fan runs at full speed whenever the current sensor detects the monitored load is on, and shuts off when it turns off.
  • Manual — up/down buttons step through the 8 fan speeds by hand.

An 8×8 LED matrix shows the current speed.

The completed AutoFan

Hardware

The AutoFan is deliberately built from off-the-shelf breakout boards rather than a from-scratch custom design. Leaning on existing, well-documented modules (microcontroller, current sensor, LED display, buck converter, and IO expander) kept the proof-of-concept cheap and fast to bring up — no custom silicon or low-level board bring-up, just wiring together known-good parts and focusing the effort on the firmware. The Eagle PCB in design/eagle/ simply carries and connects these same modules for a tidier, more permanent build.

The controller runs on an Adafruit Trinket M0 (SAMD21). Full bill of materials (reference designators match the schematic):

Bill of materials

Ref Part Qty Purpose
U2 Adafruit Trinket M0 1 Microcontroller (SAMD21)
Modern Device current sensor 1 Non-contact load detection
U3 Adafruit 8x8 LED matrix (HT16K33) 1 Speed display
U1 Adafruit MPM3610 3.3V buck converter 1 10 V → 3.3 V power
IC1 Microchip MCP23008 1 IO expander for buttons / switch
T1 2N2222 (P2N2222) NPN transistor 1 Drives the fan's 10 V PWM line
VR1 10 kΩ trim potentiometer 1 Sensor threshold adjust (A3)
R2, R3 2.2 kΩ resistor 2 I2C SDA/SCL pull-ups
R4, R5, R6 1 kΩ resistor 3 Button/switch current limiting
R1 470 Ω resistor 1 Transistor base resistor
C2 0.1 µF capacitor 1 MCP23008 decoupling
S1, S2 Momentary push button 2 Up / down speed
S3 SPDT switch 1 Manual / Auto mode select
4-pin "molex" ATX HDD connector 1 Fan connection (10 V / GND / PWM)

The fan's PWM control wire is pulled up to 10 V by the fan itself; T1 pulls it low under control of the Trinket's D4 output to generate the speed signal.

See design/eagle/ for the PCB and design/enclosure/ for the 3D-printable case.

The AutoFan controller PCB

The assembled AutoFan controller

Schematic

AutoFan schematic

The editable schematic is in design/eagle/Autofan.sch (Autodesk EAGLE).

Current sensing

Load detection uses the Modern Device current sensor, which senses the magnetic field around a conductor rather than making any electrical connection to it. In practice you simply zip-tie the sensor alongside the load's AC power cable — no cutting, splicing, or breaking into the mains wiring. As the AC current through the cable rises and falls, the sensor picks up the changing field and outputs a proportional analog voltage that the Trinket reads on A0. Because it never touches the conductor, the sensor stays galvanically isolated from mains, which keeps the low-voltage controller safe.

The firmware compares this reading against a threshold (set by the trim pot on A3); when the monitored load draws current, AutoFan switches the fan on. See Calibration for how to dial in the threshold.

Pinout

Derived from src/code.py:

Signal Connection
Fan PWM output D4
Current sensor input A0 (analog)
Threshold trim pot A3 (analog)
LED matrix + IO expander I2C (SCL / SDA, 400 kHz)
Down button MCP23008 pin 0 (active low)
Up button MCP23008 pin 1 (active low)
Mode switch (Manual/Auto) MCP23008 pin 2

Close-up of the controller front panel

Firmware

The controller runs CircuitPython.

Dependencies

The Adafruit libraries under src/lib/ are bundled for convenience and come from the Adafruit CircuitPython Bundle (MIT licensed):

  • adafruit_bus_device
  • adafruit_debouncer
  • adafruit_ht16k33
  • adafruit_mcp230xx

Their copyright notices and the MIT license text are retained in src/lib/THIRD_PARTY_LICENSES.txt.

Install

  1. Install CircuitPython on the Trinket M0 (see the Adafruit guide).
  2. Copy the contents of src/ to the board's CIRCUITPY drive:
    • code.py → the drive root
    • the lib/ folder → the drive root
  3. The controller starts automatically. Open the serial console to see status messages.

Calibration

Use the scripts in src/test/ to read the sensor voltage and to regenerate the PWM speed table. See that folder's readme for details.

Testing

TODO: Provide details for test rig to verify the AutoFan is working.

The AutoFan controller running

Bench test rig used for calibration

Repository layout

src/
  code.py            main controller firmware
  lib/               bundled Adafruit CircuitPython libraries
  test/              sensor / PWM calibration scripts
design/
  eagle/             PCB schematic and board (Autodesk EAGLE)
  enclosure/         3D-printable case and button/switch caps

Reverse-engineered OEM controller data

Details captured from the original AC Infinity controller, used to match the fan's expected PWM signal.

The stock controller has one button that cycles through 8 fan speeds and 8 LEDs that indicate the current speed. It connects to the fan via a 4-pin "molex" ATX HDD power connector.

The fan connection provides three lines:

  1. 10V DC power
  2. GND
  3. PWM fan-speed control wire (pulled up to 10V by the fan)

Fan speed is controlled by grounding and opening the 10V control wire to create a PWM signal.

Current draw

  • Controller logic: ~9.2 mA at rest, ~18.2 mA at full speed (all LEDs on).
  • PWM signal line: 1 mA when grounded (left grounded to turn the fan off).

PWM timing

Based on a 245 µs cycle time — almost 4 kHz, likely the intended target frequency but slightly off due to drift.

PWM "high" times:

Speed High time Notes
0 0 µs 0% PWM (off)
1 ~82 µs
2 ~100 µs
3 ~120 µs
4 ~140 µs
5 ~162 µs
6 ~185 µs
7 ~210 µs
8 ~245 µs 100% PWM (full)

The stock controller transitions instantly between speeds 0 and 1, and smoothly transitions between the other speeds over ~2 seconds.

TODO

  • Add digital trim for current sensor. (the manual trim pot is a bit of a pain)
  • Add some hysteresis to handle flickering at the sensor threshold. Favor staying "on".

License

This project is dual-licensed to fit the two kinds of content it contains:

The bundled Adafruit libraries under src/lib/ remain under their own upstream MIT licenses; see src/lib/THIRD_PARTY_LICENSES.txt for their copyright notices and license text.

About

Current-sensing auto controller for an AC Infinity Cloudline inline exhaust fan (CircuitPython / Trinket M0).

Resources

Contributing

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages