Found this code on website but for two PWM fans to be controlled by two DS18B20 and can't change it to work with only one fan so I can control 1 PWM fan with several DS18B20.
// Fan_Temp_Control.ino ##############################################
/* This code was written to control the temperature inside a server cabinet
by measuring the temperature with a DS18b20 Temperature probe and
outputting a PWM signal with the Arduino Nano to control a 4-Pin fan.
Unlike the cheap control boards from Amazon or Ebay this code switches
the fan off when the temperature is low enough. */
/*
The following constants should be changed according to the use case:
constant (default value) - description
tempLow (35) - Below this temperature (minus half hysteresis) the fan shuts off.
It shuts on again at this temperature plus half hysteresis
tempHigh (50) - At and above this temperature the fan is at maximum speed
hyteresis (5) - Hysteresis to prevent frequent on/off switching at the threshold
minDuty (10) - Minimum fan speed to prevent stalling
maxDuty (100) - Maximum fan speed to limit noise
*/
#include <OneWire.h>
#include <DallasTemperature.h>
// Digital pin of temperature sensor
#define ONE_WIRE_BUS 12
// Setup a oneWire instance
OneWire oneWire(ONE_WIRE_BUS);
// Setup temperature sensor library
DallasTemperature sensors(&oneWire);
// PWM output pin
const byte OC1B_PIN = 10;
const byte OC1A_PIN = 9;
// Digital pin for controlliing optional high side switch
// const byte HS_SWITCH = 9;
// how frequently the main loop runs
const int tempSetInterval = 5000;
// temperatur settings
const float tempLow = 35;
const float tempHigh = 55;
const float hyteresis = 5;
const int minDuty = 10;
const int maxDuty = 100;
// state on/off of Fan 1
bool fanState1 = HIGH;
// state on/off of Fan 2
bool fanState2 = HIGH;
// current duty cycle of Fan 1
byte duty1 = 100;
// current duty cycle of Fan 2
byte duty2 = 100;
// new duty cycle of Fan 1
byte newDuty1 = 100;
// new duty cycle of Fan 2
byte newDuty2 = 100;
//tempertature 1 (1m) sensor address
uint8_t sensor1[8] = { 0x28, 0x50, 0x3A, 0x81, 0xE3, 0xC8, 0x3C, 0xA3 };
//tempertature 2 (3m) sensor address
uint8_t sensor2[8] = { 0x28, 0x66, 0xD5, 0x76, 0xE0, 0x01, 0x3C, 0x5C };
void setup() {
//enable output for Timer 1
pinMode(OC1B_PIN, OUTPUT);
pinMode(OC1A_PIN, OUTPUT);
setupTimer1();
// configure High-Side Switch
//pinMode(HS_SWITCH, OUTPUT);
//digitalWrite(HS_SWITCH, HIGH); // default: Fan on
// start serial port
Serial.begin(9600);
// Start up the temperature library
sensors.begin();
sensors.requestTemperatures();
// welcome message
Serial.println("## Start of Program ##");
Serial.println();
Serial.println("# Connections #");
Serial.println(" Temperature Sensor (VCC, Data, GND)");
Serial.print(" Arduino: 3V3, D");
Serial.print(ONE_WIRE_BUS);
Serial.println(" , GND");
Serial.println(" *additionally 4k7 pullup between VCC and Data");
Serial.println();
Serial.println(" 4-Pin Fan (GND, VCC, Sense, Control)");
Serial.print(" Arduino: GND, 12V, n/C , D");
Serial.println(OC1B_PIN);
Serial.println();
Serial.println(" 4-Pin Fan (GND, VCC, Sense, Control)");
Serial.print(" Arduino: GND, 12V, n/C , D");
Serial.println(OC1A_PIN);
Serial.println();
// Serial.println(" Optional High-Side Switch");
// Serial.print(" Arduino: D");
// Serial.println(HS_SWITCH);
// Serial.println();
Serial.println("# Settings #");
Serial.println(" Below this temperature (minus half hysteresis) the fan");
Serial.println(" shuts off. It enables again at this temperature plus half hysteresis:");
Serial.print(" tempLow: ");
Serial.print(tempLow);
Serial.println("°C");
Serial.println(" At and above this temperature the fan is at maximum speed: ");
Serial.print(" tempHigh: ");
Serial.print(tempHigh);
Serial.println("°C");
Serial.println();
Serial.println(" Between these two temperatures the fan is regulated from");
Serial.println(" the minimum fan speed to maximum fan speed");
Serial.println();
Serial.println(" Hysteresis to prevent frequent on/off switching at the threshold");
Serial.print(" hyteresis: ");
Serial.print(hyteresis);
Serial.println("°C");
Serial.println();
Serial.println(" Minimum fan speed to prevent stalling");
Serial.print(" minDuty: ");
Serial.print(minDuty);
Serial.println(" %");
Serial.println();
Serial.println(" Maximum fan speed to limit noise");
Serial.print(" maxDuty: ");
Serial.print(maxDuty);
Serial.println(" %");
Serial.println();
Serial.println(" The fan speed is adjusted at the following interval:");
Serial.print(" tempSetInterval: ");
Serial.print(tempSetInterval);
Serial.println(" ms");
Serial.println();
delay(100);
Serial.println();
delay(100);
Serial.println();
delay(100);
Serial.println();
delay(100);
Serial.println();
delay(100);
Serial.println();
delay(100);
Serial.println();
delay(100);
Serial.println("# Main Loop");
Serial.println("(sr.no, temperature, state, Duty Cycle, Fan On/Off)");
Serial.println();
}
// main loop ##############################################
void loop() {
// measure temperature, calculate Duty cycle, set PWM
tempToPwmDuty();
// wait for a bit
delay(tempSetInterval);
}
// setting PWM ############################################
void setPwmDuty() {
if (duty1 == 0) {
fanState1 = LOW;
// Disable high side switch
//digitalWrite(HS_SWITCH, LOW);
} else if (duty1 > 0) {
fanState1 = HIGH;
// Enable high side switch
//digitalWrite(HS_SWITCH, HIGH);
}
if (duty2 == 0) {
fanState2 = LOW;
// Disable high side switch
//digitalWrite(HS_SWITCH, LOW);
} else if (duty2 > 0) {
fanState2 = HIGH;
// Enable high side switch
//digitalWrite(HS_SWITCH, HIGH);
}
setFan(duty1, duty2);
}
// calculate new PWM ######################################
void tempToPwmDuty() {
sensors.requestTemperatures();
float temp1 = sensors.getTempC(sensor1);
float temp2 = sensors.getTempC(sensor2);
Serial.print("#1, ");
Serial.print(temp1);
Serial.print("°C, ");
if (temp1 < tempLow) {
// distinguish two cases to consider hyteresis
if (fanState1 == HIGH) {
if (temp1 < tempLow - (hyteresis / 2)) {
// fan is on, temp below threshold minus hysteresis -> switch off
Serial.print("a, ");
newDuty1 = 0;
} else {
// fan is on, temp not below threshold minus hysteresis -> keep minimum speed
Serial.print("b, ");
newDuty1 = minDuty;
}
} else if (fanState1 == LOW) {
// fan is off, temp below threshold -> keep off
Serial.print("c, ");
newDuty1 = 0;
}
} else if (temp1 < tempHigh) {
// distinguish two cases to consider hyteresis
if (fanState1 == HIGH) {
// fan is on, temp above threshold > control fan speed
Serial.print("d, ");
newDuty1 = map(temp1, tempLow, tempHigh, minDuty, maxDuty);
} else if (fanState1 == LOW) {
if (temp1 > tempLow + (hyteresis / 2)) {
// fan is off, temp above threshold plus hysteresis -> switch on
Serial.print("e, ");
newDuty1 = minDuty;
} else {
// fan is on, temp not above threshold plus hysteresis -> keep off
Serial.print("f, ");
newDuty1 = 0;
}
}
} else if (temp1 >= tempHigh) {
// fan is on, temp above maximum temperature -> maximum speed
Serial.print("g, ");
newDuty1 = maxDuty;
} else {
// any other temperature -> maximum speed (this case should never occur)
Serial.print("h, ");
newDuty1 = maxDuty;
}
//set new duty
duty1 = newDuty1;
Serial.print(duty1);
Serial.print("%, ");
if (fanState1 == 0) {
Serial.println("OFF");
} else {
Serial.println("ON");
}
Serial.print("#2, ");
Serial.print(temp2);
Serial.print("°C, ");
if (temp2 < tempLow) {
// distinguish two cases to consider hyteresis
if (fanState2 == HIGH) {
if (temp2 < tempLow - (hyteresis / 2)) {
// fan is on, temp below threshold minus hysteresis -> switch off
Serial.print("a, ");
newDuty2 = 0;
} else {
// fan is on, temp not below threshold minus hysteresis -> keep minimum speed
Serial.print("b, ");
newDuty2 = minDuty;
}
} else if (fanState2 == LOW) {
// fan is off, temp below threshold -> keep off
Serial.print("c, ");
newDuty2 = 0;
}
} else if (temp2 < tempHigh) {
// distinguish two cases to consider hyteresis
if (fanState2 == HIGH) {
// fan is on, temp above threshold > control fan speed
Serial.print("d, ");
newDuty2 = map(temp2, tempLow, tempHigh, minDuty, maxDuty);
} else if (fanState2 == LOW) {
if (temp2 > tempLow + (hyteresis / 2)) {
// fan is off, temp above threshold plus hysteresis -> switch on
Serial.print("e, ");
newDuty2 = minDuty;
} else {
// fan is on, temp not above threshold plus hysteresis -> keep off
Serial.print("f, ");
newDuty2 = 0;
}
}
} else if (temp2 >= tempHigh) {
// fan is on, temp above maximum temperature -> maximum speed
Serial.print("g, ");
newDuty2 = maxDuty;
} else {
// any other temperature -> maximum speed (this case should never occur)
Serial.print("h, ");
newDuty2 = maxDuty;
}
//set new duty
duty2 = newDuty2;
Serial.print(duty2);
Serial.print("%, ");
if (fanState2 == 0) {
Serial.println("OFF");
} else {
Serial.println("ON");
}
setPwmDuty();
}
// Setup Timer control
void setupTimer1() {
//Set PWM frequency to about 25khz on pins 9,10 (timer 1 mode 10, no prescale, count to 320)
TCCR1A = (1 << COM1A1) | (1 << COM1B1) | (1 << WGM11);
TCCR1B = (1 << CS10) | (1 << WGM13);
ICR1 = 320;
OCR1A = 0;
OCR1B = 0;
}
//equivalent of analogWrite on pin 10
void setFan(int fan1, int fan2) {
float f1 = fan1;
float f2 = fan2;
f1 = f1 / 100;
f1 = f1 < 0 ? 0 : f1 > 1 ? 1: f1;
f2 = f2 / 100;
f2 = f2 < 0 ? 0 : f2 > 1 ? 1: f2;
OCR1B = (uint16_t)(320 * f1);
OCR1A = (uint16_t)(320 * f2);
}