To temperature control and monitor a small (12U) network rack system using PWM fans and thermometers managed using an Arduino Mega with a custom designed shield:
Above rack has:
- 4 fans mounted (2 top and 2 base) in the rack
- 2 temperature sensors one at the top and base
- Modular 3d printed model 2U rack housing Arduino temperature controller and OLED shown far left
- Uses Freetronics EtherMega Arduino board although likely any Mega board can reuse the shield
- Shield outline derived from Jonathan Oxer's ProtoShieldMega
- Power over Ethernet 802.3af support using Freetronics PoE module to power the board (and reset it), thermometers, fans and display to simplify power and wire management
- Measures temperatures using DS18B20 housed in metal cable assembly with an accuracy of +/- 0.5°C
- Uses Freetronics OLED via SPI to display the temperature and fan states of the rack
- Works with PWM fans of either 5 or 12V and supports configurable frequency (default 25kHz)
- Uses an passive infrared sensor to prevent burn in for OLED display, only enabling the display on a PIR trigger
- Monitors and displays fan tachometer output to verify RPM is within expected range and fan has not stalled
- Publishes all fan, temperature, error states and logs to an MQTT endpoint and topics for analysis and visualisation
- Software must support any number of temperature devices and fans to enable testing and reuse
Initial design was based on a separate (non-shield) board using a MAX31790 for fan PWM control and tach measurement integrated with an Arduino Uno using I2C. However due to Uno memory limitations of <32k, I upgraded to the Mega with 256k. Code is however included under MAX31790FanControl.cpp.
Using a Mega also enabled the PWM control and tach measurement to be done by the Mega pinout and all in software simplifying the overall hardware solution.
The shield design outline is based on ProtoShieldMega. The top side of the PCB layout is illustrated. The schematic and PCB design files are under Eagle. EAGLE PCB design software is available from https://www.autodesk.com/products/eagle/free-download and is free for non-commercial use.
Pin | Mapping |
---|---|
2, 4, 7 | OLED DC, Reset, CS |
8 | Onewire DS for thermos |
11, 12, 5, 3 | Fan PWM 1-4 |
18, 19, 20, 21 | Fan Tach 1-4 for RPM interrupts |
6 | IR sensor |
I used DirtyPCBs to manufacture the boards. They also support design rules checking and CAM Gerber export for EAGLE, which ensures the PCB layout conforms to their manufacture processes and the Gerber files produced will pass.
I then soldered (or used solder paste for surface mount) the parts in place. For the surface mount work, I used a heat gun and roughly followed the heat profile by modifying the gun temperature manually. YouTube videos explain how to do this.
The shield mounted with the EtherMega.
Minor error on the power circuit which required a track cut and wire from VIN to Fan power. This has been corrected on the Eagle files.
OLED display to render fan and temperature states showing the fan temperatures in the top row, and the fan RPMs as a percentage of maximum RPM in the lower rows. The fan RPM % does not always accurately map to the input PWM duty cycle - the fans I am using have a +/- 10% variance on RPM. The display also supports 90 degree rotation to support rack mounting.
Generated new fonts using GLDCFontCreator.
I used the mobile app IoT MQTT Panel to render the MQTT topics which supports configurable panels per topic and different rendering options:
Development done using PlatformIO which supports multiple boards and library management.
The main routine loop executes the RackTempController process method below which reads the temperature sensors, adjusts the fan speed based on the temperatures, reads and verifies the fan speed RPM is as requested by the PWM dutycycle within a tolerance and analyses temperature trends using a moving average.
void RackTempController::process(RackState_t& rs) {
// read temperatures
readTempStates(rs.thermos);
// adjust fan speeds based on temps
adjustFanSpeeds(rs);
// read fan tach/rpms - delay of 750ms per fan
readFanSpeeds(rs.fans);
// verify fan PWMs matches RPMs
verifyFanStates(rs.fans);
// analyse trends
analyseTrends(rs);
};
Thermos and fan configuration is created via RackTempController::build() which enables any number of thermos or fans to be used. The OLED display class however, is fixed to the specification above.
All libraries were loaded and managed used PlatformIO's library management.
Library | Purpose |
---|---|
DallasTemperature | Measures temperature of DS18* devices using OneWire |
FTOLED | Graphics library to drive OLED |
SD | Dependency for FTOLED - not used |
Ethernet | Ethernet, DHCP support |
ArduinoMqttClient | MQTT client |
TimerOne | PWM control for Timer1 |
TimerThree | PWM control for Timer3 |
ArduinoLog | Logging framework |
ArduinoSTL | STL library used for map, vector etc |
Further details on the rack mount design: 3D printed model.
- Update this README!
- Create a config endpoint - possibly via MQTT subscribe to enable changes to MQTT params, temp threshold etc.
- Improve MQTT events
- Watchdog via AWS lambda which reboots via PoE
- Look at FreeRTOS or Helios and work out if its worth it
- Make it cheaper
First and foremost to Jonathan Oxer.
Secondly all the excellent library contributors used in the project.
Hardware design licensed under the TAPR Open Hardware License (www.tapr.org/OHL) and GNU. The license folder within this repository also contains a copy of this license in plain text format.
Software licensed under GPLv3 - see license.md file for details.