Chrisroy
Published

Wood stove monitor and control

Monitor chimney temperature, alert if too high and control air intake damper

IntermediateWork in progress541
Wood stove monitor and control

Things used in this project

Hardware components

Arduino Nano R3
Arduino Nano R3
×1
SG90 Micro-servo motor
SG90 Micro-servo motor
×1
Nextion NX4024T032 - Generic 3.2" HMI TFT Intelligent LCD Touch Display Module
Itead Nextion NX4024T032 - Generic 3.2" HMI TFT Intelligent LCD Touch Display Module
×1
Temperature Sensor IC, Thermocouple
Temperature Sensor IC, Thermocouple
×1

Software apps and online services

Arduino IDE
Arduino IDE
Nextion

Hand tools and fabrication machines

3D Printer (generic)
3D Printer (generic)

Story

Read more

Schematics

Wood Stove Controller 3 d parts

Code

Wood Stove Controller

Arduino
#include <EEPROM.h>
#include <Servo.h>
#include <Wire.h>
#include <SimpleTimer.h>
#include <max6675.h>
#include <Servo.h>
#include <SoftwareSerial.h>
#include <Average.h>

#define rxPin 2
#define txPin 3
#define buzzerPin  7
#define motor_pin 9
#define ktcCLK  10
#define ktcCS  11
#define ktcSO  12

SimpleTimer timer;
int timerId1,  timerId2, timerId3, timerId4, timerId5 ;
// set up a new serial port
SoftwareSerial Serial1 =  SoftwareSerial(rxPin, txPin);
Servo Motor_inTake;

long lastTouchtDelta, lastTouch;
int min_possition = 20;
int max_possition = 104;
int from2;

byte dimSet = 100;
MAX6675 ktc(ktcCLK, ktcCS, ktcSO);

int Tmp;
float tDelta, Delta1, taux;
float derive = 0;
byte HMIButton;
int set_tmp ; // 'Celsius ////////////
int spd ; //msec//////////////////////////
int pos2go, posStep;
int pos_old = 60;
int bipN;
int lastPosition;
int tangential,tmp1,tmp2;
//char msg[6];

int counter = 0;
String msg;
boolean moreWood = true;
Average<float> tmpAve(10);

///////////////////////////////////////////////////////
void setup() {
  /////////////////////////////////////////////////////
  Serial.begin(9600);
  Serial1.begin(9600);
  pinMode(buzzerPin, OUTPUT);
  bipN = 7;

  digitalWrite(buzzerPin, 0);
  EEPROM.get(0, min_possition);
  if (min_possition < 1)min_possition = 10;
  EEPROM.get(5, max_possition);
  if (max_possition < 1)max_possition = 180;
  EEPROM.get(10, set_tmp );
  if (set_tmp < 100)set_tmp = 250;
  EEPROM.get(15, spd );
  if (spd < 10) {
    spd = 100;
    EEPROM.put(15, spd );
  }
  spd = 100;
  EEPROM.get(20, from2);

  HMIPrint("page 0");
  HMIPrint("t0.txt=\"FOYER MK3.0\"");

  timerId1 = timer.setInterval(5000, takeReading);
  timerId2 = timer.setInterval(5000, printTemp);
  timerId3 = timer.setTimer(500, bip, 6);
  timerId4 = timer.setInterval(20000, TmpRoll);
  timerId5 = timer.setInterval(500, takeTEMP);
  HMIPrint("dims=80");
  HMIPrint("t0.txt=\" \"");
  HMIPrint("page 1");
  HMIPrint("t0.txt=\"Calibration\"");
  HMIPrint("t1.txt=\"Min:" + String(min_possition) + "\"");
  HMIPrint("t2.txt=\"Max:" + String(max_possition) + "\"");
  delayx(2000);
  HMIPrint("page 0");
  HMIPrint("s0.pco2=25388");
  //motor(0);
  //motor(255);

}


//////////////////////////////////////////////////////////////////////
void loop() {                                                       //
  //////////////////////////////////////////////////////////////////////
  timer.run();
  HMIButton = 0;
  HMIButton = touchscreen();

  if (HMIButton == 0x01) {
    calibration();
  }
  if (HMIButton == 0x0A) {
    // HMIPrint("dim=80");
    HMIPrint("page 0");
  }
}



///////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////
void takeTEMP() {
  tmpAve.push(Tmp = ktc.readCelsius());
}


/////////////////////////////delay x///////////////////////////////////////////////////////////////
void delayx(int timer) {
  unsigned long t3 = 0;
  unsigned long t2 = millis();

  while (millis() - t2 < timer) {
    t3++;
    // timer.run();
  }
}
void TmpRoll() {

  tmp2 = tmp1;
  tmp1 = Tmp;
}

/////////////////////////////touchscreen///////////////////////////////////////////////////////////
int touchscreen() {
  static const byte numBytes = 32;
  static byte receivedBytes[numBytes];
  static byte numReceived = 0;
  static boolean recvInProgress = false;
  static byte ndx = 1;
  byte startMarker = 101;
  byte endMarker = 0xff;

  static byte rb;
  boolean newData;
  receivedBytes[0] = 0;
  HMIButton = 0;

  while (Serial1.available() > 0 ) { //&& newData == false) {
    rb = Serial1.read();
    if (rb != 0xff)    {
      Serial.print(rb, HEX); Serial.print(", ");
    }
    if (recvInProgress == true) {
      if (rb != endMarker) {
        receivedBytes[ndx] = rb;
        //Serial.print(ndx); Serial.print("= "); Serial.print(receivedBytes[ndx]); Serial.println("");
        ndx++;
        if (ndx >= numBytes) {
          ndx = numBytes - 1;
        }
      }
      else {
        receivedBytes[ndx] = '\0'; // terminate the string
        recvInProgress = false;
        numReceived = ndx;  // save the number for use when printing
        ndx = 1;
        newData = true;
        lastTouchtDelta = millis() - lastTouch;
      }
    }
    if (rb == 0x65) {
      receivedBytes[0] = rb;
      recvInProgress = true;
    }
  }
  delayx (100);
  //if (rb!=255)Serial.print(rb); Serial.println("< ");
  if (newData == true) {
    if (receivedBytes[0] == 0x65) {   //Puch Press Event  0x65
      //bipN = 1;

      Serial.println();
      Serial.print ("HMIButton= "); Serial.print (HMIButton);
      /*Serial.print ("Byte 1="); Serial.print(receivedBytes[1], DEC);
        Serial.print ("Byte 2="); Serial.print(receivedBytes[2], DEC);
        Serial.print ("Byte 3="); Serial.print(receivedBytes[3], DEC);
        Serial.print ("Byte 4="); Serial.print(receivedBytes[4], DEC);
        //Serial.print ("slider ="); Serial.println(slider);
      */
    }

    if (receivedBytes[0] == 0x65) {     //Puch Release Event

      HMIButton = receivedBytes[3];
      Serial.print("box="); Serial.print(HMIButton); Serial.println("");
      lastTouch = millis();
    }
    if (!dimSet) {
      HMIPrint("dims=60");
      dimSet = true;
    }
    newData = false;
  }
  return (HMIButton);
}

///////////////////////////print temp//////////////////////////////////////////////////////////////
void printTemp() {
  //Serial.print ("temp:"); Serial.println (Tmp);
  HMIPrint("");
  HMIPrint("t0.txt=\"" + String(Tmp) + "\"");
  //HMIPrint("add 3,2," + String(map(set_tmp, 0, 100, 0, 40)));

  HMIPrint("add 3,0," + String(map(Tmp, 0, 100, 0, 40)));

}
double scale(float input, float factor)
{
  double value = pow(input, factor);
  if (input < 0.0) value = -value;  // only adjust calculated factor when input is negative.
  return value;
}
/////////////////take reading and action///////////////////////////////////////////////////////////

void takeReading() {
  int  pourcent;
  int proportionnel;
  //Serial.println("Take Reading and Action");
  Tmp = tmpAve.mean();
  if ( Tmp > 500 || Tmp < 5) {                // max/min temperature
    pos2go = min_possition;
    timerId3 = timer.setTimer(1000, bip, 6);
    HMIPrint("t2.bco=YELLOW");
    HMIPrint("t2.pco=BLACK");
    HMIPrint("t2.txt=\"Temperature ANORMAL\"");
  }
  else if (Tmp < 25) {//COLD DOWN
    HMIPrint("t2.txt= \"Cold Down\"");
    pos2go = min_possition;
  }
  else if (Tmp > 75) {
    HMIPrint("t2.bco=BLACK");
    HMIPrint("t2.pco=WHITE");
    tDelta = set_tmp - Tmp;
    tDelta = constrain(tDelta, -30, 30);
    proportionnel = map(tDelta, -30, 30, min_possition, max_possition);
    tangential =  scale(tDelta/7.00,2) -scale((tmp1 - tmp2),2)     ;
    Serial.print (", tang= "); Serial.println (tangential);

    pos2go = proportionnel + tangential;
    pos2go = constrain(pos2go, min_possition, max_possition);

    Serial.print (", tmp= "); Serial.print (Tmp);
    Serial.print (", tDelta= "); Serial.print (tDelta);
    Serial.print (", tmp1/2= "); Serial.print (tmp1);Serial.print (" / ");Serial.print (tmp2);
    
    Serial.print (", min/max_possition= "); Serial.print (min_possition);
    Serial.print (" / "); Serial.print (max_possition);
    Serial.print (", pos2go= "); Serial.print (pos2go);
    Serial.println (", ");

    if ( Tmp < 180 && moreWood == true) {
      bipN = 1;
      moreWood = false;
      timerId3 = timer.setTimer(1000, bip, 2);
      HMIPrint("t2.txt= \"Add Wood\"");
      Serial.print("[108]");
    }
    if ( Tmp > 190 && moreWood == false) {
      moreWood = true;
    }
  }


  pourcent = map (pos2go, min_possition, max_possition, 0, 200);
  pourcent = constrain(pourcent, 0, 200);
  HMIPrint("h0.val=" + String(pourcent));
  HMIPrint("add 3,1," + String(pourcent));
  motor (constrain(pos2go, min_possition, max_possition))
  ;

}
///////////////////////////////HMI Print////////////////////////////////////////////////////////////

void HMIPrint(String msg2) {
  Serial1.print("dim=80");
  Serial1.print ("\xFF\xFF\xFF");
  Serial1.print ("\xFF\xFF\xFF");
  //delayx(50);
  Serial1.print(msg2);
  Serial1.print("\xFF\xFF\xFF");
  //Serial.println(msg2);
  delayx(50);
}
//////////////////////////////mOTOR/////////////////////////////////////////////////////////////////
void motor ( int go2) {
  constrain(go2, 0, 255);
  //Serial.println("motor");
  if (from2 != go2) {
    Motor_inTake.attach(motor_pin);
    if (from2 < go2)  {
      HMIPrint("t2.txt=\"" + String(from2) + " >> " + String(go2) + "\"");
      for ( posStep = from2; posStep <= go2; ++posStep) {
        Motor_inTake.write(posStep);
        delayx (spd);// speed
      }
    }
    else {
      HMIPrint("t2.txt=\"" + String(go2) + " << " + String(from2) + "\"");
      //Serial.println("motor 3");
      //Serial.println(spd);
      for ( posStep = from2; posStep >= go2; --posStep) {
        Motor_inTake.write(posStep);
        delayx (spd);//speed
        //Serial.println("motor 1");
      }
    }
    Motor_inTake.detach();
  }
  timerId4 = timer.setTimer(2000, clearHMIt2, 1);
  //HMIPrint("t2.txt=\" \"");
  //Serial.println("motor 2");
  from2 = go2;
  EEPROM.put(20, from2);

}
/////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////
void clearHMIt2() {
  HMIPrint("t2.txt=\" \"");
  //Serial.println("clr screen");
}

///////////////////////////////calibration//////////////////////////////////////////////////////////
void calibration() {
  Serial.println("calibration");
  spd = 30;
  HMIPrint("page 1");
  HMIPrint("t0.txt=\"Set Temp.\"");
  HMIPrint("t1.txt=\"Temp:" + String(set_tmp) + "\"");
  HMIPrint("t2.txt=\" \"");
  HMIButton = 0;


  while (HMIButton != 0x09 && HMIButton != 0x0A) {
    HMIButton = touchscreen();
    if (HMIButton == 0x06) {
      set_tmp += 5;
      // // HMIPrint("dim=80");
      HMIPrint("t1.txt=\"Temp:" + String(set_tmp) + "\"");
    }
    if (HMIButton == 0x08) {
      set_tmp -= 5;
      // // HMIPrint("dim=80");
      HMIPrint("t1.txt=\"Min:" + String(set_tmp) + "\"");
    }
  }
  if (HMIButton == 0x0A)return;
  HMIPrint("t0.txt=\"Set Close\"");
  HMIPrint("t1.txt=\"Min:" + String(min_possition) + "\"");
  HMIButton = 0;



  motor (min_possition);
  while (HMIButton != 0x09 && HMIButton != 0x0A) {
    HMIButton = touchscreen();
    if (HMIButton == 0x06) {
      min_possition += 5;
      HMIPrint("t1.txt=\"Min:" + String(min_possition) + "\"");
      motor (min_possition);
    }
    if (HMIButton == 0x08) {
      min_possition -= 5;
      HMIPrint("t1.txt=\"Min:" + String(min_possition) + "\"");
      motor (min_possition);
    }
  }
  if (HMIButton == 0x0A)return;


  EEPROM.get(5, max_possition);
  HMIPrint("t0.txt=\"Set Open\"");
  HMIPrint("t1.txt=\"Max:" + String(max_possition) + "\"");
  motor (max_possition);

  HMIButton = 0;

  while (HMIButton != 0x09) {
    HMIButton = touchscreen();
    if (HMIButton == 0x06) {
      max_possition += 5;
      HMIPrint("t1.txt=\"Max:" + String(max_possition) + "\"");
      motor (max_possition);
    }
    if (HMIButton == 0x08) {
      max_possition -= 5;
      HMIPrint("t1.txt=\"Max:" + String(max_possition) + "\"");
      motor (max_possition);
    }
  }
  EEPROM.get(15, spd);
  HMIPrint("t0.txt=\"Set Speed\"");
  HMIPrint("t1.txt=\"Speed:" + String(spd) + "\"");
  motor (max_possition);

  HMIButton = 0;

  while (HMIButton != 0x09) {
    HMIButton = touchscreen();
    if (HMIButton == 0x06) {
      spd += 5;
      HMIPrint("t1.txt=\"Speed:" + String(spd) + "\"");

    }
    if (HMIButton == 0x08) {
      spd -= 5;
      HMIPrint("t1.txt=\"Sped:" + String(spd) + "\"");
      motor (max_possition);
    }
  }
  EEPROM.put(0, min_possition);
  EEPROM.put(5, max_possition);
  EEPROM.put(10, set_tmp );
  EEPROM.get(15, spd );
  HMIPrint("t0.txt=\"Saved\"");
  HMIPrint("t1.txt=\" \"");
  HMIPrint("t2.txt=\" \"");
  HMIButton = 0;
  while (HMIButton != 0x0A) {
    HMIButton = touchscreen();
  }
  HMIButton = 0;
  HMIPrint("page 0");
  timer.restartTimer(timerId1);
  timer.restartTimer(timerId2);
  timer.restartTimer(timerId3);
  timer.restartTimer(timerId4);
  Serial.println("calibration completed");
}

/////////////////////////////////////////////////////////////////////////////////////////////////////
//                               BIP BIP
/////////////////////////////////////////////////////////////////////////////////////////////////////

void bip() {
  digitalWrite (buzzerPin, !digitalRead(buzzerPin));
}

Credits

Chrisroy
1 project • 2 followers
Contact

Comments

Please log in or sign up to comment.