

Ball heater controller
This repo contains the schematics and associated code for a controller to control the temperature of a ball holder or other device using closed loop PID drive of a resistive heater.
- Size
- 127 × 76.2 mm
- Copper layers
- 2
- Thickness
- 1.6 mm
- Parts
- 43
- Nets
- 36
- Pads
- 140
- Tracks, vias
- 212, 35
- Pours
- 4
- Routed
- Yes
- KiCad
- KiCad 7 (file 20221018)
- Created
- 3 Aug 2025
- Updated
- 24 Jun 2025
Overview
Ball heater controller is an open-source printed circuit board by jazzlw, from the jazzlw/ball_heater_controller repository on GitHub. It is a 2-layer board of 127 × 76.2 mm with 43 parts on 36 nets, routed with 212 tracks and 35 vias.
It is built around the ARDUINO UNO R3, F0512S-1WR3 and B3B-PH-SM4-TB(LF)(SN), with the BSS138DW-7-F-ES, CL-SB-12A-01T and M8S-04PFFR-SF8001 among its other parts. Its parts include 12 capacitors, 6 resistors, 6 connectors, 2 transistors and 2 switches. It belongs with the AVR (ATmega, ATtiny) boards of this library.
Main components
8ARDUINO UNO R3
Arduino UNO R3 Printed Circuit Board ModuleArduinoUncategorisedF0512S-1WR3
SIP-4-40℃~+105℃ 1 10.16mm 1000uF 12V 19.65mm 1W 270kHz 30mVp-p 3kV 4.5V~5.5V 84mA 88% 8mA 8mm Short Circuit Protection SIP-4 Isolated Power Modules ROHSYLPTECIsolated Power ModulesB3B-PH-SM4-TB(LF)(SN)
SMD,P=2mm-25℃~+85℃ 1 100V 1x3P 2A 2mm 3 3P 6.6mm 7mm 9.95mm Auxiliary Solder Pin Beige Copper alloy PA PH Surface Mount,Vertical Tin UL94V-0 SMD,P=2mm Wire To Board Connector ROHSJSTWire To Board ConnectorBSS138DW-7-F-ES
SOT-363-55℃~+150℃ 1.5Ω@10V、1.6Ω@4.5V 1V 2 N-Channel 2.2pF 25pF 410mA 417mW 60V 650pC@4.5V 9.7pF N-Channel SOT-363 MOSFETs ROHSElecSuperMOSFETsCL-SB-12A-01T
SMD,8.5x3.5mm-40℃~+85℃ 200mA 3.5mm 5.5mm 50V 8.5mm J-Lead Rectangular Columnar SPDT Surface Mount,Vertical White SMD,8.5x3.5mm Slide Switches ROHSNidecSlide SwitchesM8S-04PFFR-SF8001
弯插-40℃~+105℃ 30V 4A 4P Bent tip Copper alloy Female Gold IP68 M8 弯插 Circular Connectors & Cable Connectors ROHSAmphenolCircular Connectors & Cable ConnectorsS1G
SMA(DO-214AC)-55℃~+150℃ 1.1V@1A 1A 30A 400V 5uA Independent SMA(DO-214AC) Diodes - General Purpose ROHSTWGMCDiodes - General PurposeTSM170N06CP
TO-252(DPAK)MOSFETsTaiwan Semiconductor
README
README.mdBall Heater Controller
This repo contains the schematics and associated code for a controller to control the temperature of a ball holder or other device using closed loop PID drive of a resistive heater. There is a Python class to interact with the controller over USB-Serial, as well as a ROS2 Node to send and receive commands with the controller using ROS2.
For instructions on building a Ball Heater Controller, see Assembly.
Basic Usage
The Ball Heater Controller can be used independently of a computer by simply supplying it with AC power and attaching a ball heater and thermistor assembly to the main 4 pin output port on the front.
You can then change the mode by pressing and holding the control knob (see Modes), and set the temperature setpoint (shown lower left as SP: on the LCD) by turning the knob. Current temperature is shown bottom right on the LCD.
Python
The device can also be used with a computer for greater control and temperature logging. Interaction is done over USB-Serial, and the computer side is managed through the BallHeaterDriver Python class found in ball_heater_driver.py. An example of how this class can be used can be found in the Jupyter Notebook ball_heater_controller_testing.ipynb
In short, after creating a BallHeaterDriver object, providing the correct serial port, commands can be sent using the send_command method. The main commands you will use are status, set_target_temp, and set_control_mode. Valid syntax for creating an object and sending these commands is shown below, with the first valid serial port chosen by default.
import ball_heater_driver
from list_ports import list_ports
import time
ports = [
port
for port in list_ports()
if port["manufacturer"] is not None and "Silicon Labs" in port["manufacturer"]
]
port = ports[0]["port"]
print(f"Using Port: {port}")
ball_heater = ball_heater_driver.BallHeaterDriver(port=port)
# wait for the device to reset
time.sleep(5)
# Get and print status
success, status = ball_heater.send_command('status', [])
print('current status is:')
print('\n'.join((f"{key} : {value}") for key, value in status.items()))
# Set the target temperature to 35 (will also set control mode to remote)
ball_heater.send_command("set_target_temp", [35])ROS2
There is also a ROS2 Node provided for interacting with the Ball Heater Controller, ball_heater_node.py. The launch file example_ball_heater.launch.py, along with the config file example_config.yaml will launch the node, as well as an example client node that can interact with the ball_heater_node. It will also launch the ball_heater_gui that will subscribe to and print the heater status, and let the user set the temperature setpoint. Once installed, set the serial_port or device_serial_number in example_config.yaml and launch the launch file using
ros2 launch ball_heater_controller example_ball_heater.launch.py Generally, the BallHeaterNode must be given a serial_port or a device_serial_number to specify the controller. Then, the status information will be published to the ball_heater_status_topic (default ball_heater_controller/status_topic), and the temperature can be set by another node by publishing to the ball_heater_set_temp_topic (default ball_heater_controller/set_temp_topic)
Sub-directories
ball_heater_controller-- ROS2 Package with a Node to interact with and control the heater, as well asball_heater_driver.pywhich contains a Python classBallHeaterDriverto interact with the controller.ball_heater_controller_interfaces-- ROS2 Package with custom message types associated with the above package.ball_heater_controller_firmware-- Firmware for the microcontroller at the center of the PCB.ball_heater_controller_pcb-- Design files and gerbers for the printed circuit board for the Ball Heater Controller.ball_heater_controller_case-- Vector files for laser cuttting the case for the Ball Heater Controller.docs-- Additional documentation.
Controller Modes
The controller has several different modes, shown upper left on the LCD display, and its behavior will be different depending on what mode it is in. The mode can be changed using the set_control_mode command through the interface, or by pressing and holding the control knob on the front of the device for >= 1 second.
- Standby On startup, the controller will be in standby mode, and the heater will not be driven, but the temperature will be shown on screen.
- Local Control Pressing the control from standby mode will switch into
local controlmode, and the temperature setpoint can then be adjusted by turning the control knob. This mode is useful for running the ball heater without a computer attached, or without needing to set the temp from the computer. - Remote Control In this mode, the setpoint temperature is set from the computer using the
set_target_tempcommand. Anyset_target_tempcommands received by the controller will automatically switch the controller into this mode. - Error Mode There are also several error modes discussed below in Safety Cutoffs
Install
Run the installation script
./install_dependencies.shSafety Cutoffs / Troubleshooting
The ball heater firmware has several different safety cutoffs built in that will trigger different errors and shut down the heater to prevent overheating. Once one of these error modes has been activated, the heater output will shut down, and the type of error will be displayed on the LCD. Pressing and holding the control knob down will reset the device into standby mode if the error state has been resolved.
- High temp error: If the heater temperature sensor reads over 60 °C, the device will go into High temp error and shutdown.
- No Temp Sensor: If the temperature sensor for the ball heater is not detected because it has been unpluged or a wire has broken, the device will go into No Temp Sensor Error and shutdown. When the sensor is replaced, the device will return to standby mode. Note that this is only for the integrated temp sensor in the ball heater, not the optional aux temp sensor.
- Heater Non Responsive: If the control loop drives the heater at a high power for too long, eg if the temperature is not responding properly, the device will go into Heater Non Responsive error and shutdown.
Parts
43| Qty | Value | Footprint | References |
|---|---|---|---|
| 4 | MountingHole | MountingHole:MountingHole_3.7mm | H1, H2, H3, H4 |
| 4 | TestPoint | TestPoint:TestPoint_Loop_D2.60mm_Drill1.6mm_Beaded | TP1, TP2, TP3, TP4 |
| 3 | 100nF | Capacitor_SMD:C_0805_2012Metric_Pad1.18x1.45mm_HandSolder | C9, C10, C11 |
| 3 | 10k | Resistor_SMD:R_0805_2012Metric_Pad1.20x1.40mm_HandSolder | R1, R5, R6 |
| 2 | 0.1uF | Capacitor_SMD:C_0805_2012Metric_Pad1.18x1.45mm_HandSolder | C6, C8 |
| 2 | 10k | Resistor_SMD:R_Array_Convex_4x1206 | RN1, RN2 |
| 2 | 10k 1% | Resistor_SMD:R_0805_2012Metric_Pad1.20x1.40mm_HandSolder | R3, R4 |
| 2 | 10uF | Capacitor_SMD:C_0805_2012Metric_Pad1.18x1.45mm_HandSolder | C2, C12 |
| 2 | 4.7uF | Capacitor_SMD:C_0805_2012Metric_Pad1.18x1.45mm_HandSolder | C3, C4 |
| 2 | B3B-PH-SM4-TB(LF)(SN) | Connector_JST:JST_PH_B3B-PH-SM4-TB_1x03-1MP_P2.00mm_Vertical | J3, J4 |
| 1 | .1uF | Capacitor_SMD:C_0805_2012Metric_Pad1.18x1.45mm_HandSolder | C7 |
| 1 | 10R | Resistor_SMD:R_0805_2012Metric_Pad1.20x1.40mm_HandSolder | R2 |
| 1 | 2.2uF | Capacitor_SMD:C_0805_2012Metric_Pad1.18x1.45mm_HandSolder | C5 |
| 1 | 470uF | Capacitor_THT:CP_Radial_D12.5mm_P5.00mm | C1 |
| 1 | Arduino_UNO_R3 | Misc_custom:Metro_mini | A1 |
| 1 | BSS138DW-7-F | digikey-footprints:SOT-363 | Q1 |
| 1 | Barrel_Jack_Switch | Connector_BarrelJack:BarrelJack_Horizontal | J6 |
| 1 | CL-SB-12A-01T | Misc_custom:CL-SB-12A-01T | SW2 |
| 1 | F0512S-1WR3 | Misc_custom:CONV_F0512S-1WR3 | PS1 |
| 1 | LOGO | test:ball_heater_black | G*** |
| 1 | LOGO | test:ball_heater_gold | G*** |
| 1 | M8S-04PFFR-SF8001 | Misc_custom:AMPHENOL_M8S-04PFFR-SF8001 | J5 |
| 1 | RotaryEncoder_Switch | Rotary_Encoder:RotaryEncoder_Bourns_Horizontal_PEC09-2xxxF-Sxxxx | SW1 |
| 1 | S1G | digikey-footprints:DO-214AC | D1 |
| 1 | Screw_Terminal_01x02 | digikey-footprints:Term_Block_1x2_P5.08MM | J1 |
| 1 | TSM170N06CP | digikey-footprints:TO-252-3 | Q2 |
| 1 | qwiic | Misc_custom:BM04B-SRSS-TB(LF)(SN) | J2 |
Similar boards
- 6 layers160 × 100 mm

- 4 layers70 × 100 mm

- 4 layers80 × 60 mm

Bytebeam ble can
Atif6894/automotive-ble-can-pcb
A small 4-layer board that sits on a vehicle's 12/24 V harness, talks CAN FD through a TCAN4550-Q1, and exposes it over Bluetooth LE through a CC2340R5-Q1.
153 parts - 4 layers191.5 × 121.8 mm

Foxhunt1
gx1400/kicad_foxhunt_batterytest
Custom amateur radio fox hunt (hidden transmitter) controller, aimed at being a flexible, dynamic platform for a wide range of fox-hunt formats — not just a fixed single-mode beacon.
260 parts - 4 layers110 × 80 mm

Spin rig controller
Tinkerbug-Robotics/TinkerRocket
Model rocket flight computer, ground station, iOS app, and simulation
170 parts1GPL-3.0 - 2 layers90 × 37 mm

- 4 layers33 × 90 mm

Active drag system
RocketryVT/active-drag-system
Eigen Library, cmake, and arm-none-eabi-gcc tooling required for successful build.
100 parts6MIT - 2 layers50 × 47.3 mm

Questions
How big is the Ball heater controller PCB?
It measures 127 × 76.2 mm and has 2 copper layers, 1.6 mm thick.
What parts does the Ball heater controller use?
43 parts, built around the ARDUINO UNO R3, F0512S-1WR3, B3B-PH-SM4-TB(LF)(SN) and BSS138DW-7-F-ES. The full list of its parts is on this page, with links to each part's symbol and footprint where PCBKit's library has them.
Where can I download the Ball heater controller KiCad files?
From the jazzlw/ball_heater_controller repository on GitHub, at the commit this page was made from: the board is ball_heater_controller_pcb/ball_heater_controller.kicad_pcb and its schematic ball_heater_controller_pcb/ball_heater_controller.kicad_sch. PCBKit opens the board in the browser, with nothing to install.
Can I use the Ball heater controller design in my own project?
Its repository states no licence, so its author keeps all rights: ask jazzlw before reusing the design.