Cool ProjectsGeneral

Arduino Mod for Open Hardware Monitor ( to control a System Fan)

userHead LNC-SPN 2017-11-02 20:40:16 34425 Views15 Replies
Hi LattePanders!, if you have installed a system fan for your LattePanda (like me) this mod for Open Hardware Monitor its useful to control the fan (Power On when system start - Power Off when system shutdown - Activate by CPU temp)

You can use a Relay or a NPN Transistor (PWM not implemented yet).

Installation
Download the RAR OpenHardwareMonitor(Arduino Mod).rar (461.08 KiB) Downloaded 1170 times Uncompress the OpenHardwareMonitor folder to Program Files(x86)

Image

Arduino Setup
Options - Arduino - COM Port (Select your Arduino COM, AUTO by default)
Options - Arduino - Fan Controller - GPIO Pin (Select the Relay or Transistor Pin)
Options - Arduino - Fan Controller - Enable (You can also select "Activate by CPU temp")
(To change the Pin you need to Disable first)

Important= Options - Run On Windows Startup
Optional = Options - Start Minimized
Recomended= View - Show Gadget (select the items from the list (Right click-Show in Gadget)

Image

How it works?
Using the Standard Firmata library from the Arduino Leonardo side and a custom LattePanda Firmata library (only digitalWrite, low CPU usage)

ArduinoCustomFirmata.cs

Code: Select all

using System; using System.IO.Ports; using System.Threading; using System.Linq; namespace LattePanda.CustomFirmata { class Arduino { public const byte LOW = 0; public const byte HIGH = 1; public const byte OUTPUT = 1; public Arduino(string serialPortName) { _arduinoSerialPort = new SerialPort(); if (serialPortName == String.Empty) { _arduinoSerialPort.PortName = List().ElementAt(List().Length - 1); } else { _arduinoSerialPort.PortName = serialPortName; } _arduinoSerialPort.BaudRate = 57600; _arduinoSerialPort.DataBits = 8; _arduinoSerialPort.Parity = Parity.None; _arduinoSerialPort.StopBits = StopBits.One; Open(); } public static string[] List() { return SerialPort.GetPortNames(); } public void Open() { _arduinoSerialPort.DtrEnable = true; _arduinoSerialPort.Open(); Thread.Sleep(1000); } public void Close() { if (_arduinoSerialPort.IsOpen == true) { _arduinoSerialPort.Close(); } } public void pinMode(int pin, byte mode) { byte[] message = new byte[3]; message[0] = (byte)(SET_PIN_MODE); message[1] = (byte)(pin); message[2] = (byte)(mode); _arduinoSerialPort.Write(message, 0, 3); message = null; } public void digitalWrite(int pin, byte value) { int portNumber = (pin >> 3) & 0x0F; byte[] message = new byte[3]; if ((int)value == 0) _digitalOutputData[portNumber] &= ~(1 << (pin & 0x07)); else _digitalOutputData[portNumber] |= (1 << (pin & 0x07)); message[0] = (byte)(DIGITAL_MESSAGE | portNumber); message[1] = (byte)(_digitalOutputData[portNumber] & 0x7F); message[2] = (byte)(_digitalOutputData[portNumber] >> 7); _arduinoSerialPort.Write(message, 0, 3); } private const int MAX_DATA_BYTES = 64; private const int TOTAL_PORTS = 2; private const int DIGITAL_MESSAGE = 0x90; // send data for a digital port private const int SET_PIN_MODE = 0xF4; // set a pin to INPUT/OUTPUT/PWM/etc private volatile int[] _digitalOutputData = new int[MAX_DATA_BYTES]; private SerialPort _arduinoSerialPort; } } Using ArduinoUtilities class that have a loop to know every second the CPU temp, compare to the max temp setted by user and power on or power off the fan.

Code: Select all

using System; using System.Threading; using OpenHardwareMonitor.Hardware; using LattePanda.CustomFirmata; namespace OpenHardwareMonitor.Utilities { public class ArduinoUtilities { private Arduino arduino; private PersistentSettings settings; public string ArduinoPortName = String.Empty; public int RelayFanPin; public int RelayFanByTemp; private bool ArduinoIsOpen; public bool RelayFanIsEnabled; public bool RelayFanByTempIsEnabled; private bool RelayFanIsOn; private Thread readCPUtemp = null; private volatile bool keepGetCPUtempRunning = true; public ArduinoUtilities(PersistentSettings settings) { this.settings = settings; ArduinoPortName = settings.GetValue("ArduinoPortName", (ArduinoPortName)); RelayFanIsEnabled = settings.GetValue("RelayFanIsEnabled", (RelayFanIsEnabled)); RelayFanPin = settings.GetValue("RelayFanPin", (RelayFanPin)); RelayFanByTempIsEnabled = settings.GetValue("RelayFanByTempIsEnabled", (RelayFanByTempIsEnabled)); RelayFanByTemp = settings.GetValue("RelayFanByTemp", (RelayFanByTemp)); if (RelayFanIsEnabled == true && RelayFanByTempIsEnabled == true) { ActivateRelayFanByTemp(); } else { if (RelayFanIsEnabled == true) { RelayFanON(); } } } private void OpenArduino() { arduino = new Arduino(ArduinoPortName); ArduinoIsOpen = true; } public void CloseArduino() { arduino.Close(); ArduinoIsOpen = false; } private void GetCPUTemp() { while (keepGetCPUtempRunning) { int CPUtemp; var myComputer = new Computer { CPUEnabled = true }; myComputer.Open(); foreach (var hardwareItem in myComputer.Hardware) { hardwareItem.Update(); hardwareItem.GetReport(); foreach (var sensor in hardwareItem.Sensors) { if (sensor.SensorType == SensorType.Temperature) { CPUtemp = (int)sensor.Value; if (CPUtemp >= RelayFanByTemp) { RelayFanON(); } else { RelayFanOFF(); } } } } Thread.Sleep(1000); } } public void ActivateRelayFanByTemp() { keepGetCPUtempRunning = true; if (readCPUtemp == null) { readCPUtemp = new Thread(GetCPUTemp); readCPUtemp.IsBackground = true; readCPUtemp.Start(); } } public void DeactivateRelayFanByTemp() { keepGetCPUtempRunning = false; readCPUtemp = null; } public void RelayFanON() { if (ArduinoIsOpen == false) { OpenArduino(); } if (RelayFanIsOn == false) { arduino.pinMode(RelayFanPin, Arduino.OUTPUT); arduino.digitalWrite(RelayFanPin, Arduino.HIGH); RelayFanIsOn = true; } } public void RelayFanOFF() { if (ArduinoIsOpen == false) { OpenArduino(); } if (RelayFanIsOn == true) { arduino.pinMode(RelayFanPin, Arduino.OUTPUT); arduino.digitalWrite(RelayFanPin, Arduino.LOW); RelayFanIsOn = false; } } public void Close() { if (RelayFanByTempIsEnabled == true) { RelayFanOFF(); keepGetCPUtempRunning = false; readCPUtemp = null; } if (RelayFanIsEnabled == true) { RelayFanOFF(); CloseArduino(); } } } } Video Demostration: https://vid.me/7lOj5

Testing
Stable on LattePanda 4GB/64GB Z8300 CPU - Windows 10 64 bits Creators Update
Not tested on LattePanda 2GB/32GB Z8300 CPU - Windows 10 32 bits
Not tested on LattePanda 4GB/64GB Z8350 CPU

Feedback is much appreciated.

Credits/Copyright
Michael Möller (http://openhardwaremonitor.org/)
Kevlin Sun (LattePanda.Firmata)
Luis Navarro (LattePanda.CustomFirmata, OHM Arduino Mod) Attachments OpenHardwareMonitor_gadget.jpg OpenHardwareMonitor_gadget.jpg (58.26 KiB) Viewed 22195 times OpenHardwareMonitor-Arduino.png OpenHardwareMonitor-Arduino.png (30.02 KiB) Viewed 22195 times
2020-05-06 04:12:11 Is there a possibility to be able to set the temperature so that it would start the fan at one temperature, and then stop the fan at different temperature?
The way my setup is:
5V relay powered by LP
COM port goes to the 12V fan
NO port goes to 5V on LP
NC port goes to 12V power supply.
Fans ground goes to LP

If/When temperature is below 70 degrees Celsius, NO and COM ports are connected, thus powering 12V fan with 5V (silent but active cooling).
If/When temperature is greater than 70 degrees Celsius, NC and COM ports gets connected, thus powering 12V fan with 12V (loud but very active cooling).

But the problem is that a lot of the time, temperature constantly hovering around 70 degrees Celsius, and the relay is constantly switching between 5V and 12V.

So the perfect solution would be to be able to set that the relay would switch on when CPU reaches 70 degrees Celsius, and that it would turn off when CPU gets below 60 degrees Celsius. (or and selected temperature value).
userHeadPic Skrimo
2019-02-02 00:41:18 excuses my possibly stupid question but do i need additional hardware to use this mod? if so, would it be possible to include a link to an example? Unfortunately I don't know anything about the subject so your explanation was a bit ambiguous for me.

greetings
userHeadPic Apop85
2019-01-11 18:02:06
MarkF wrote: ↑Thu Jan 10, 2019 1:12 pm
LattePanda wrote: ↑Wed Jan 09, 2019 5:02 am @MarkF, checkout this - https://create.arduino.cc/projecthub/10 ... fan-499f90
Thank you, just received the transistor so can start to hook up the fan, still not sure about the software side of things.
It's explained here.
"
How it works?
Using the Standard Firmata library from the Arduino Leonardo side and a custom LattePanda Firmata library (only digitalWrite, low CPU usage)
"

It means:
1. Download and install Arduino IDE following the Arduino official guide.
2. Open the sample named "standard firmata" in Arduino IDE sample list
3. Upload this sample code to LattePanda onboard Arduino according to the Arduino basic tutorials.
4. Open the software developed by the creator to run the GUI.

That's it.
userHeadPic LattePanda
2019-01-10 21:12:41
LattePanda wrote: ↑Wed Jan 09, 2019 5:02 am @MarkF, checkout this - https://create.arduino.cc/projecthub/10 ... fan-499f90
Thank you, just received the transistor so can start to hook up the fan, still not sure about the software side of things.
userHeadPic MarkF
2019-01-09 13:02:50 @MarkF, checkout this - https://create.arduino.cc/projecthub/10 ... fan-499f90 userHeadPic LattePanda
2019-01-09 13:02:50 @MarkF, checkout this - https://create.arduino.cc/projecthub/10 ... fan-499f90 userHeadPic LattePanda
2019-01-08 04:50:12 Great Project. Is there an idiots guide on how to connect the fan via a npn transistor? Do you only run the monitor and select the selected options or is there something that needs to be run in the arduino program as well? userHeadPic MarkF
2018-11-15 04:04:32
Pip wrote: ↑Fri Jan 12, 2018 11:07 pm Not being and electronics expert (read I know very basic stuff) I'm interested to know more information about the relay it's self. I'm looking for either an off the self or DIY relay that would easily fit in a metal case. This is the case I bought http://a.co/gipPL3i. nice looking nothing special, Very functional. would anyone care to share some links that would meet my needs, I'm sure others are also interested.
To fit in the case I recommend you to use a NPN transistor, like the 2N2222A.
2N2222A_Transistor.PNG 2N2222A Transistor 2N2222A_Transistor.PNG (22.23 KiB) Viewed 17721 times

attachments:

2N2222A_Transistor.PNG

userHeadPic LNC-SPN
2018-01-22 16:37:22 Amazing! Thanks for sharing!! I've already downloaded the software and used on my lattepanda.It's really a useful function!!!
I want use the Open Hardware Monitor to make my own software too. But I can't get the Temperature of the CPU in console. Do you know why?
Here's my code:

Code: Select all

using System; using OpenHardwareMonitor.Hardware; using System.Text; using System.Threading; namespace VS_ReadCPUTemperature { class Program { public class UpdateVisitor : IVisitor { public void VisitComputer(IComputer computer) { computer.Traverse(this); } public void VisitHardware(IHardware hardware) { hardware.Update(); foreach (IHardware subHardware in hardware.SubHardware) subHardware.Accept(this); } public void VisitSensor(ISensor sensor) { } public void VisitParameter(IParameter parameter) { } } static void Main(string[] args) { while (true) { UpdateVisitor updateVisitor = new UpdateVisitor(); Computer computer = new Computer(); computer.Open(); computer.CPUEnabled = true; computer.Accept(updateVisitor); for (int i = 0; i < computer.Hardware.Length; i++) { if (computer.Hardware[i].HardwareType == HardwareType.CPU) { for (int j = 0; j < computer.Hardware[i].Sensors.Length; j++) { if (computer.Hardware[i].Sensors[j].SensorType == SensorType.Temperature) { if (computer.Hardware[i].Sensors[j].Name == "CPU Package") Console.WriteLine("Tem=" + computer.Hardware[i].Sensors[j].Value.ToString()); } } } } computer.Close(); } } } }
userHeadPic Kellman616
2018-01-15 18:46:34 Hey, you can check here to find if there is the relay suitable to you.
https://www.dfrobot.com/search-relay.html
userHeadPic LattePanda
2018-01-13 07:07:26 Not being and electronics expert (read I know very basic stuff) I'm interested to know more information about the relay it's self. I'm looking for either an off the self or DIY relay that would easily fit in a metal case. This is the case I bought http://a.co/gipPL3i. nice looking nothing special, Very functional. would anyone care to share some links that would meet my needs, I'm sure others are also interested. userHeadPic Pip
2017-11-29 01:49:26 What!? This's the coolest project, which matches a very common need for LattePanda!
Very coool.
userHeadPic ED209
2017-11-17 13:52:23 Look's so nice, my fan is running all the time now, i will try it later userHeadPic Coco Xia
2017-11-03 15:01:33
LattePanda wrote: ↑Fri Nov 03, 2017 4:04 am Wow, thanks for your sharing, Nice!
You're allways wellcome

Hope it helps.
userHeadPic LNC-SPN
2017-11-03 12:04:43 Wow, thanks for your sharing, Nice! :) userHeadPic LattePanda