Wiring for temperature controlled fan system with UPS

I've just bought my first arduino (Nano V3.0 ATmega328) to build an automated fan system for my log burner.
It's pretty simple in what it needs - when the temperature of the log burner goes up the arduino turns the fans on, blowing air into the room, and keeps them going until the fire is out and the burner has cooled.

The problem is if there is a power cut the fans will cut off, and a chimney fire will ensue. For this I'm adding an uninterruptible power supply using a car battery and a trickle charger.

I've done my circuit diagram but I want to check that it's all OK as it's been years since doing any electronics in school!

I'm running a K type thermcouple with a MAX6675 to check the temperature (I have the thermocouple and arduino so far, I need to order the relays), and the relay and relay board to control the power.

As far as code goes I've got a pin turning on and off at the correct temperatures, and giving me readouts in the serial port so I think no problems.

#include "max6675.h"

const int threshold = 50; //Fan start temperature
int fanPin = 13; //Pin to fan relay
int thermoDO = 4;
int thermoCS = 5;
int thermoCLK = 6;

MAX6675 thermocouple(thermoCLK, thermoCS, thermoDO);
int vccPin = 3;
int gndPin = 2;

const int numReadings = 10;
int readings[numReadings];      // the readings from the digital input
int index = 0;                  // the index of the current reading
int total = 0;                  // the running total
int average = 0;                // the average
  
void setup() {
  Serial.begin(9600);
  // use Arduino pins 
  pinMode(vccPin, OUTPUT); digitalWrite(vccPin, HIGH);
  pinMode(gndPin, OUTPUT); digitalWrite(gndPin, LOW);
  
  Serial.println("MAX6675 test");
  // wait for MAX chip to stabilize
  delay(1000);                  
  // initialize all the readings to 0: 
  for (int thisReading = 0; thisReading < numReadings; thisReading++)
    readings[thisReading] = 0;   
}

void loop() {
  // subtract the last reading:
  total= total - readings[index];         
  // read from the sensor:  
  readings[index] = (thermocouple.readCelsius()); 
  // add the reading to the total:
  total= total + readings[index];       
  // advance to the next position in the array:  
  index = index + 1;                    

  // if we're at the end of the array...
  if (index >= numReadings)              
    // ...wrap around to the beginning: 
    index = 0;                           

  // calculate the average:
  average = total / numReadings;         
  // send it to the computer as ASCII digits
  // basic readout test, just print the current temp
  
   Serial.print("C = "); 
   Serial.println(thermocouple.readCelsius());
   Serial.print("Av = ");
   Serial.println(average);
   
   if (average > threshold) {
     digitalWrite(fanPin, LOW);
   }
   else {
     digitalWrite(fanPin, HIGH);
   }
   delay(1000);
}

The code is probably a bit dodgy as I copied and pasted the first chunk, but it seems to work fine,
I plan on adding an LCD readout and some warning LEDs later on, but for now I just want to check I'm not going to destroy anything or cause an electrical fire when I out the initial circuit together.

Many thanks! I'm looking forward to getting stuck in, with several other projects lined up for the near future.

It looks like you have the basics all sorted out, but it may suite you well to add some hysteresis to your fan relay and possibly some smoothing to your temperature reading to prevent the fan relay from chattering.

hysteresis: Turn the fan on at 50C but it wont turn off till 48C. That way if your temp is bouncing around 50 you don't get chattering.

Smoothing: taking a running average of the thermo-couple reading. http://arduino.cc/en/Tutorial/Smoothing

Cheers!

Cheers for those pointers - both very handy. I've added the smoothing so far (and put that new code into my top message), and I'll work on the hysteresis next.

I also just notice that you have not set you "fanPin" to output in void setup(), as well as your fan control "if / else" statements seem to have their logic reversed. Also once you add hysteresis you can get rid of that delay you have at the end of void loop().

Ok, I've added hysterisis into the mix (although I used simpler coding as the example was a bit beyond me).
Thanks for pointing out the logic reversal! I added that when I was thinking about using it as a failsafe, so in the event the arduino failed the fans would remain on rather than remain off (and connecting the fan to the "nc" terminal of the relay).
I'd since reversed it but not updated the attached code. I don't know how hard wearing the boards are but I figure it's better to not have it triggering a relay 24/7 in case it wears faster.

This

   if (average >= threshold) {
     digitalWrite(fanPin, HIGH);
   }
   if (average < threshold-1) {
     digitalWrite(fanPin, LOW);
   }

Simple as possible, and combined with the smoothing it gives really consistent results when I test it with a voltmeter and soldering iron.

Also thanks for theOUTPUT bit - I didn't notice a problem as I was only testing with a voltmeter, not drawing any current.

The whole code is as follows now, and I think works fine (until the LCD arrives)

#include "max6675.h"

const int threshold = 50; //Fan start temperature
int fanPin = 12; //Pin the fan relay connects to

//copied code to control the thermocouple
int thermoDO = 4; 
int thermoCS = 5;
int thermoCLK = 6;

MAX6675 thermocouple(thermoCLK, thermoCS, thermoDO);
int vccPin = 3;
int gndPin = 2;

//copied code to perform smoothing
const int numReadings = 10;
int readings[numReadings];      // the readings from the digital input
int index = 0;                  // the index of the current reading
int total = 0;                  // the running total
int average = 0;                // the average
  
void setup() {
  Serial.begin(9600);
  // use Arduino pins 
  pinMode(vccPin, OUTPUT); digitalWrite(vccPin, HIGH);
  pinMode(gndPin, OUTPUT); digitalWrite(gndPin, LOW);
  pinMode(fanPin, OUTPUT);
  
  Serial.println("MAX6675 test");
  // wait for MAX chip to stabilize
  delay(1000);                  
  // initialize all the readings to 0: 
  for (int thisReading = 0; thisReading < numReadings; thisReading++)
    readings[thisReading] = 0;   
}

void loop() {
  // subtract the last reading:
  total= total - readings[index];         
  // read from the sensor:  
  readings[index] = (thermocouple.readCelsius()); 
  // add the reading to the total:
  total= total + readings[index];       
  // advance to the next position in the array:  
  index = index + 1;                    

  // if we're at the end of the array...
  if (index >= numReadings)              
    // ...wrap around to the beginning: 
    index = 0;                           

  // calculate the average:
  average = total / numReadings;         
  // send it to the computer as ASCII digits
  // basic readout test
  
   Serial.print("C = "); 
   Serial.println(thermocouple.readCelsius());
   Serial.print("Av = ");
   Serial.println(average);
   Serial.println(" ");
   
   //Fan control logic, using two "if's" for hysterisis
   if (average >= threshold) {
     digitalWrite(fanPin, HIGH);
   }
   if (average < threshold-1) {
     digitalWrite(fanPin, LOW);
   }

Cheers for your help, it's much appreciated!

That should do ya. :slight_smile: And don't worry about running the relay too much. They wear based on cycles not on time.