PWM fan controller for the Raspberry Pi Pico written in Rust. This fan controller just sets the fan speed to 40% speed to reduce noise from the Noctua NF-P12 redux-1700 PWM Fan.
All the hardware components in my particular build are enumerated here.
-
12V DC 1000mA (1A) regulated switching power adapter - UL listed
-
Female DC Power adapter - 2.1mm jack to screw terminal block
-
micro USB power supply for the microcontroller
Programming will require a micro USB cable and a computer. If you don’t already have one, you’ll probably want a fan, too. This circuit is meant for a 12V fan. I use this controller for the Noctua NF-P12 redux-1700 PWM Fan.
This is a dead-simple PWM fan controller that simply lowers the speed of the Noctua NF-P12 redux-1700 PWM Fan to a quiescent 40% speed. The microcontroller simply sets the fan speed and then does nothing. The fan setup might evolve in the future to take into account temperature sensing and dynamic speed adjustment.
The 3.3V Raspberry Pi Pico requires a logic level shifter to boost the PWM signal up to 5V for the fan.
I use the 74AHCT125 to perform the logic level conversion, using pin #40, VBUS
, to provide the 5V reference voltage.
The Raspberry Pi Pico draws 1.99 mA of current in this particular configuration.
The 74AHCT125 is wired as shown in the [74AHCT125 Wiring] table. All pins omitted from the table are connected to ground.
74AHCT125 Pin |
Signal |
Connection |
2 |
3.3V logic level input |
Pico pin #20 (GP15) |
3 |
5V logic level output |
1N4001 to fan header pin #4 (Control) |
8 |
5V |
Pico pin #40 (VBUS) |
The output signal from the logic level shifter is sent through the 1N4001 power blocking diode to the fan header. The pins on the 4-pin fan header are classified in the [4-pin Fan Header Pinout] table. The pins are numbered one through four from left to right with the pins reaching upwards and the overhang positioned between the viewer and the pins.
Fan Header Pin |
Signal |
1 |
GND |
2 |
+12VDC |
3 |
Sense |
4 |
Control |
-
Change to the board’s directory.
cd pwm-fan-controller/boards/pico
-
While holding the
BOOT
button, attach the Pico to your computer using the micro-USB port. -
Mount the drive provided by the Pico. This can be determined by perusing the block devices available from the
lsblk
command. To mount/dev/sda1
, as in my case, use theudisksctl
command like so.udisksctl mount --block-device /dev/sda1
-
Double check that .cargo/config.toml has the runner set to
elf2uf2-rs -d
. -
Flash the board using the
nix run
command with thepico.flash.elf2uf2-rs
target.nix run ../..#pico.flash.elf2uf2-rs
The UF2
method is handy for programming microcontrollers without requiring any additional hardware.
However, debug probes are quite convenient for flashing and debugging code running on the microcontroller.
Any CMSIS-DAP compatible debug probe should work with probe-rs.
The Raspberry Pi Debug Probe is the most straightforward probe to use for this, and quite affordable.
If you happen to have another Raspberry Pi Pico on-hand, this can be used as a debug probe.
Follow the instructions in Probe Firmware to install the necessary firmware to convert the Pico into a debug probe.
The PicoProbe PCB kit is a nifty add-on that makes it a bit more convenient to use the Pico as a probe.
Whichever probe you happen to choose, configure udev to give your user access to the probe by following these instructions.
-
Add a udev rule to be able to access the Raspberry Pi Debug Probe as a non-root user.
/etc/udev/rules.d/60-pico-debug-probe.rulesSUBSYSTEM=="usb", ATTRS{idVendor}=="2e8a", ATTRS{idProduct}=="000c", TAG+="uaccess"
-
Unplug the probe, and plug it back in for the udev rule to take effect.
If you want to use a probe with the cargo run
command, be sure that .cargo/config.toml has the runner set to probe-run --chip RP2040 --protocol swd
.
The Pico Probe and the Raspberry Pi Debug Probe use variations of the same firmware. The firmware is installed and upgraded in the same way. I recommend using the latest firmware. It’s very easy to install. Raspberry Pi releases official firmware in their Debug Probe repository. I prefer the firmware from the Yet Another Picoprobe project, which is used in these instructions. It’s a bit faster and provides more information about the connection through the LED.
-
While holding the
BOOTSEL
button on the Raspberry Pi Pico or Raspberry Pi Debug Probe, connect it to the computer. -
Mount the drive provided by the Pico. This can be determined by perusing the block devices available from the
lsblk
command. To mount/dev/sda1
, as in my case, use theudisksctl
command like so.udisksctl mount --block-device /dev/sda1
-
Download and install the appropriate firmware for the device.
- Raspberry Pi Debug Probe
-
curl --location --output-dir=/run/media/$USER/RPI-RP2 --remote-name \ https://github.com/rgrr/yapicoprobe/releases/download/v1.21/yapicoprobe-0121-picodebugprobe-11bf6c0.uf2
- Pico Probe
-
curl --location --output-dir=/run/media/$USER/RPI-RP2 --remote-name \ https://github.com/rgrr/yapicoprobe/releases/download/v1.21/yapicoprobe-0121-pico-11bf6c0.uf2
This Raspberry Pi Pico uses a 3-pin debug connector on end of the board opposite the microUSB connector, right below the Raspberry Pi logo. This is documented in detail in the Raspberry Pi 3-pin Debug Connector Specification. The pins are numbered one through three from left to right when the board is oriented such that the Raspberry Pi logo is upright. The Raspberry Pi Debug Probe utilizes a JST-SH connector. If your Pico uses a JST-SH connector, making the connection is straightforward. If it doesn’t, the following table describes each connection, including the color of each wire for the adapter that comes with the Raspberry Pi Debug Probe.
Pin |
SWD |
UART |
Wire Color |
1 |
SWCLK |
RX |
Orange |
2 |
GND |
GND |
Black |
3 |
SWDIO |
TX |
Yellow |
When using a standalone Pico as a probe, connect the pins to the target Pico according to the following table. Refer to the Picoprobe Wiring documentation for further details.
Probe | Pico |
---|---|
GND |
GND |
GP2 |
SWCLK |
GP3 |
SWDIO |
GP4/UART1 TX |
GP1/UART0 RX |
GP5/UART1 RX |
GP0/UART0 TX |
Follow these steps to run the code on the Raspberry Pi Pico.
-
Connect the probe to the Raspberry Pi Pico using the connections described in the Probe Wiring section.
-
Flash and run the firmware using the
nix run
command with thepico.run.probe-rs
target. Alternatively, use the just commandjust run dev probe-rs
.nix run .#pico.run.probe-rs
Contributions in the form of issues, feedback, and even pull requests are welcome. Make sure to adhere to the project’s Code of Conduct.
This project is built on the hard work of countless open source contributors. Several of these projects are enumerated below.
-
{probe-run}
Refer to the project’s Code of Conduct for details.
Licensed under either of
-
Apache License, Version 2.0 (LICENSE-APACHE or https://www.apache.org/licenses/LICENSE-2.0)
-
MIT license (LICENSE-MIT or https://opensource.org/licenses/MIT)
at your option.
© 2022-2024 Jordan Williams