Pages: [1]   Go Down
Author Topic: Temperature controlled fan with One wire DS18B20 sensor with threshold  (Read 2284 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Newbie
*
Karma: 0
Posts: 14
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Thought I'd share my code, I've messed with this over the past couple of days.  I wanted to have a threshold which would prevent the program from turning on the fan immediately.

Basic program: 
Check temp;
-----> if higher than setpoint + threshold, then turn fan on
-----> if between setpoint and setpoint + threshold, check previous fan state,
----------> if was on, stay on
----------> if was off, stay off
-----> if lower than setpoint, then turn fan off

Right now its setup to print a lot of info, but you can remove it as you see fit.

Code:
#include <OneWire.h>


OneWire  ds(10);                    // on pin 10

int PinLED = 13;                     //LED Pin
float temp_setpoint = 75.00;    //Temperature Set Point
float temp_thresh = 2.50;        //Temperature threshold
 
void setup(void) {
  Serial.begin(9600);
  pinMode(PinLED,OUTPUT);
}

void loop(void) {
  byte i;
  byte present = 0;
  byte type_s;
  byte data[12];
  byte addr[8];
  float celsius, fahrenheit;
 
  if ( !ds.search(addr)) {
    ds.reset_search();
    delay(250);
    return;
  }
 
  Serial.print("ROM =");
  for( i = 0; i < 8; i++) {
    Serial.write(' ');
    Serial.print(addr[i], HEX);
  }

  if (OneWire::crc8(addr, 7) != addr[7]) {
      Serial.println("CRC is not valid!");
      return;
  }

  ds.reset();
  ds.select(addr);
  ds.write(0x44,1);                          // start conversion, with parasite power on at the end
 
  delay(750);                               // maybe 750ms is enough, maybe not
                                             // we might do a ds.depower() here, but the reset will take care of it.
 
  present = ds.reset();
  ds.select(addr);   
  ds.write(0xBE);                            // Read Scratchpad

  for ( i = 0; i < 9; i++) {                 // we need 9 bytes
    data[i] = ds.read();
  }

                                             // convert the data to actual temperature
  unsigned int raw = (data[1] << 8) | data[0];
  if (type_s) {
    raw = raw << 3;                          // 9 bit resolution default
    if (data[7] == 0x10) {
                                             // count remain gives full 12 bit resolution
      raw = (raw & 0xFFF0) + 12 - data[6];
    }
  } else {
    byte cfg = (data[4] & 0x60);
    if (cfg == 0x00) raw = raw << 3;         // 9 bit resolution, 93.75 ms
    else if (cfg == 0x20) raw = raw << 2;    // 10 bit res, 187.5 ms
    else if (cfg == 0x40) raw = raw << 1;    // 11 bit res, 375 ms
  }

  fahrenheit = (float)raw / 16.0 * 1.8 + 32.0;
  float temp_current = fahrenheit;
  Serial.print(", Fan Relay: ");

  if (temp_current >= temp_setpoint + temp_thresh) {
   Serial.print("ON ");
   digitalWrite(PinLED, 1);
  }
else if (temp_current >= temp_setpoint && temp_current <= temp_setpoint + temp_thresh) {
    int fan1state = digitalRead(PinLED);
       if (fan1state == 1){
           Serial.print("ON ");
           digitalWrite(PinLED, 1);
       }
       else {
           Serial.print("OFF");
           digitalWrite(PinLED, 0);
       } 
  }
  else if (temp_current <= temp_setpoint) {
   Serial.print("OFF");
   digitalWrite(PinLED, LOW);
  }
 
  Serial.print(",  Current Temp / Threshold: ");
  Serial.print(fahrenheit);
  Serial.print(" / "); 
  Serial.print(temp_setpoint + temp_thresh); 
  Serial.print(" (");
  Serial.print(temp_current >= temp_setpoint + temp_thresh); 
  Serial.println(")"); 

}
                 
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 14
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

So I have messed around with this and have found out that if I put a load on pin 13, reading its state no longer returns the expected result.  I want it to tell me that it was previously on but it defaults to 0 state.  Connecting an NPN transistor to drive a relay as load.

Any advice appreciated.
Logged

Global Moderator
Netherlands
Offline Offline
Shannon Member
*****
Karma: 220
Posts: 13846
In theory there is no difference between theory and practice, however in practice there are many...
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset


Split your program up in several functions that do one task to simplify the loop() to something like this

Code:
void loop()
{
  float t = readTemperature();

  if (t > setpoint+threshold)
  {
    state = ON;
  }
  if (t < setpoint)
  {
    state = OFF;
  }

  setFan(state);
}


the part below makes no difference in state...
Quote
-----> if between setpoint and setpoint + threshold, check previous fan state,
----------> if was on, stay on
----------> if was off, stay off
Logged

Rob Tillaart

Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -
(Please do not PM for private consultancy)

Offline Offline
Newbie
*
Karma: 0
Posts: 14
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset


Split your program up in several functions that do one task to simplify the loop() to something like this

Code:
void loop()
{
  float t = readTemperature();

  if (t > setpoint+threshold)
  {
    state = ON;
  }
  if (t < setpoint)
  {
    state = OFF;
  }

  setFan(state);
}


the part below makes no difference in state...
Quote
-----> if between setpoint and setpoint + threshold, check previous fan state,
----------> if was on, stay on
----------> if was off, stay off


Thanks for your help. 

But I have to disagree with you, that part does make a difference.  Or at least I want it to make a difference, I may just not be programming it correctly.  The threshold is designed to prevent excessive cycling of the fan.  I want the fan to only turn on when the temp > setpoint + threshold AND it needs to stay on until temp < setpoint. 

I could rewrite the program to be an if then based on output pin state, but based on the trouble with the pin beg read low when it should be high that I've been seeing, I'll hold off on this.
Logged

New Jersey
Offline Offline
Faraday Member
**
Karma: 70
Posts: 3726
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Code:
I want the fan to only turn on when the temp > setpoint + threshold AND it needs to stay on until temp < setpoint. 

That's exactly what Robtillart's code does.
Logged

Global Moderator
Netherlands
Offline Offline
Shannon Member
*****
Karma: 220
Posts: 13846
In theory there is no difference between theory and practice, however in practice there are many...
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Here is a more complete code, take a pen and paper and iterate over loop and let the temperature go from 15 - 30 and back to 15 and write dowwn state for every temp. This will help to understand how the code works. I learned a lot of programming with paper and pencil and being "the interpreter" myself smiley

Code:
#define FANPIN 5

int state = LOW;     // note this is a global variable IMPORTANT
int setpoint = 20;
int threshold = 5;

void setup()
{
  Serial.begin(115200);
  Serial.println("Start...");
  pinMode(FANPIN, OUTPUT);
}
 

void loop()
{
  float t = readTemperature();

  if (t > setpoint+threshold)
  {
    state = ON;
  }
  if (t < setpoint)
  {
    state = OFF;
  }

  Serial.print("temp: ");
  Serial.print(t, 2);              // 2 decimals
  Serial.print("\t\tstate: ");
  Serial.print(state);

  setFan(state);
}

void setFan(int state)
{
  digitalWrite(FANPIN, state);
}

float readTemperature()
{
  float t = analogRead(A0);   // assuming an analog LM35 sensor , other code
  t = t * 5000 / 1023;           // make millivolts of it
  t = -25 + t/10;                  // 1C per 10 mv  (dont know exact formula)
}

Succes!
Logged

Rob Tillaart

Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -
(Please do not PM for private consultancy)

0
Offline Offline
Shannon Member
****
Karma: 214
Posts: 12412
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

So I have messed around with this and have found out that if I put a load on pin 13, reading its state no longer returns the expected result.  I want it to tell me that it was previously on but it defaults to 0 state.  Connecting an NPN transistor to drive a relay as load.

Any advice appreciated.

Erm, you connected the NPN how exactly?  If the pin is set to HIGH and you are reading LOW that means you're grossly overloading it (which can fry the chip) - or that its configured as an INPUT...
Logged

[ I won't respond to messages, use the forum please ]

Offline Offline
Newbie
*
Karma: 0
Posts: 1
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I'm going to to the same thing with my code which uses DS18B20.h to show the temperature and control the heat-sink fan.

Since the temperature rises very slowly, it reaches many times to the "set point" and comes down and

this makes the microcontroller to turn on and off the fan when temperature gets close to "setpoint" and plays around 49-50.
In result fan starts and stops tens of times until temperature stays on 50 or goes above; then it stays on.

Setpoint is set to 50 degrees in this line in DS18B20.h file.

if(((temp_whole/10)%10) >= 5) PORTD.F1=1; // Aici setez temp de pornire cooler [5=50 grade] (maximum setpoint temperature to turn on fan 5=50 degrees)

So i'm asking the same question like "Poldim".
I want the fan to only turn on when the temp > setpoint + threshold AND it needs to stay on until temp < setpoint.

Do you guys can help me change this code?

* VAM code.zip (3.61 KB - downloaded 11 times.)
Logged

Global Moderator
Netherlands
Offline Offline
Shannon Member
*****
Karma: 220
Posts: 13846
In theory there is no difference between theory and practice, however in practice there are many...
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset


Had a quick look at your code, you really need to restructure it.

The problem comes down to what is called hysteresis. This is the way to handle it:

Code:
void loop()
{
  float temperature = readTemperature();
  if (temperature > 50)  fanOn();
  if (temperature < 48)  fanOff();
  displayTemperature(temperature);
}

Note that there is a different temperature to switch on and a different to switch off the fan.





Logged

Rob Tillaart

Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -
(Please do not PM for private consultancy)

Pages: [1]   Go Up
Jump to: