Author Topic: Arduino Kiln Control  (Read 6764 times)

Offline pardydon

  • Jr. Member
  • **
  • Posts: 7
Arduino Kiln Control
« on: March 17, 2014, 03:39:45 PM »
I would like to offer my input for controlling a kiln with an Arduino. I am using an Arduino Uno and a LCD panel 16 by 2 that uses the I2C interface. I also use the max 31855. These are all from Adafruit. I used  a type K thermocouple from a pottery supply company. The thermocouple has to be of heavy gauge wire at least number 14.
On the input side I added a 10k pot and a push button switch. On the output side I directly wired the Arduino  to 2 SSR relays.
There are postings on the Internet to do this with PID control. I found this to be very complex and not necessary for my application. I use it to fire pottery to cone 6. (2170 f)
My kiln is approx 13" dia and 12" deep inside . It is approx 3000 watts. The SSR relays are rated at 40 amp. I put them on large heat sink and run a computer fan to cool them.
The posting on this forum titled oven control is very similar to what I did. I will post my code when I figure out how to do that.

Offline pardydon

  • Jr. Member
  • **
  • Posts: 7
Re: Arduino Kiln Control
« Reply #1 on: March 17, 2014, 09:00:26 PM »
the code

/*
   Kiln Controller
 Mod Jan 7 2014  added hold time and slow cool Jan 13
   
 */
// include the library code:
#include "Adafruit_MAX31855.h"
#include <Wire.h>
#include <Adafruit_MCP23017.h>
#include <Adafruit_RGBLCDShield.h>

Adafruit_RGBLCDShield lcd = Adafruit_RGBLCDShield();

// constants won't change. They're used here to
// set pin numbers:
const int buttonPin = 2;     // the number of the pushbutton pin
const int ledPin =  12;      // the number of the LED pin
const int ledPinTwo =  11;   //for 2nd element
const int sensorMin = 0;     // sensor minimum
const int sensorMax = 1023;   // sensor maximum

int thermoCLK = 5;     //pins for MAX32855 chip
int thermoCS = 4;
int thermoDO = 3;
// Initialize the Thermocouple
Adafruit_MAX31855 thermocouple(thermoCLK, thermoCS, thermoDO);

// variables will change:
int buttonState = 0;// variable for reading pushbutton status
#define WHITE 0x7   //  backlight color


void setup() {

  Serial.begin(9600); // initialize serial communication:
  lcd.begin(16, 2);
  lcd.setBacklight(WHITE);
  // initialize the LED pin as an output:
  pinMode(ledPin, OUTPUT);     // from button sketch 
  pinMode(ledPinTwo, OUTPUT);  // 2nd element
  // initialize the pushbutton pin as an input:
  pinMode(buttonPin, INPUT);
  pinMode(8,OUTPUT);      //pin for speaker
  // wait for MAX chip to stabilize
  delay(5000);
}

void loop() {

  // check if the pushbutton is pressed.
  // if it is, the buttonState is HIGH:
  while(buttonState = digitalRead(buttonPin),buttonState == LOW) {
    delay(44);   // stabilize button press
   
//This section of code is to display the choice as you adjust the pot

    switch (knobRead()) {

    case 0:    // pot reading 0 to 255
      displayMode();
      lcd.setCursor(0, 1);
      lcd.print("Full on 1 hr");
      delay(1000);
      break;

    case 1:    // higher reading
      displayMode();
      lcd.setCursor(0, 1);
      lcd.print("Bisque");
      delay(1000);
      break;

    case 2:    // even higher
      displayMode();
      lcd.setCursor(0, 1);
      lcd.print("Glaze");
      delay(1000);
      break;

    case 3:    // higher still
      displayMode();
      lcd.setCursor(0, 1);
      lcd.print("Glaze Program 2");
      delay(1000);
      break;
     
       case 4:    // pot reading higher
      displayMode();
      lcd.setCursor(0, 1);
      lcd.print("Show Temp only");
      delay(1000);
      break;
     
       case 5:    // pot reading higher
     displayMode();
      break;
     
       case 6:    // pot reading max
      displayMode();
      break;
    };
 
  };//end of while loop

//When button is pressed we jump to the selected mode***************

  switch (knobRead()) {
 
  case 0:  // full on 1 hr
    lcd.clear();         
    lcd.setCursor(0, 0);
    lcd.print("FULL ON 60 mins");
 
    for (int i =0; i<= 3600; i++){
     heatHigh();
      showTemperatureAndTime();
      delay (1000);
    }
   break; 
     

  case 1:    // bisque

    lcd.clear();         //print bisque
    lcd.setCursor(0, 0);
    lcd.print("BISQUE Warm Up");

    //warm for 2 hours at 200F

    while (elapsedTime() < 120){
      showTemperatureAndTime();
      while (tempVal() < 200){

        showTemperatureAndTime();
        heatLow();           //power to element
        delay (200);

      }//end of while loop for temp
    }//end of while loop for time

    // second stage of fire
    do{
     
      lcd.clear();         //print bisque 2nd stage
      lcd.setCursor(0, 0);
      lcd.print("2nd stage BISQUE");
       
      showTemperatureAndTime();
      heatMedium();

    }
    while (tempVal() < 600);

    // Third stage of fire

    do{
     
      lcd.clear();         //print bisque 3rd stage
      lcd.setCursor(0, 0);
      lcd.print("3rd stage BISQUE");
     
      showTemperatureAndTime();
      heatHigh();
      delay (2000);
    }
    while (tempVal() < 1888);  //cone 05 iss 1888 F
   
    heatOff();   
    slowCool();         
    //clear display and print DONE mssg. 
    lcd.clear();
    lcd.setCursor(2, 0);
    lcd.print("BISQUE DONE ");
    endSignal();
   
    break;
//*******************************************************************
  case 2:    // glaze
    lcd.clear();         //print glaze
    lcd.setCursor(0, 0);
    lcd.print(" GLAZE Warming");

    // warm for 2 hours at 200F

    while (elapsedTime() < 120){
      showTemperatureAndTime();
      while (tempVal() < 200){

        showTemperatureAndTime();
        heatLow();           //power to element
        delay (200);

      }//end of while loop for temp
    }//end of while loop for time

    // second stage of fire
     lcd.clear();         //print 2nd stage mssg
      lcd.setCursor(0, 0);
      lcd.print("Glaze 2nd stage");
   
    do{
      heatMedium();
      showTemperatureAndTime();

    }
    while (tempVal() < 600);

    // Third stage of fire
    lcd.clear();         //print 3rd stage mssg
      lcd.setCursor(0, 0);
      lcd.print("Glaze 3rd stage");

    do{
      heatHigh();
      showTemperatureAndTime();
    }
    while (tempVal() < 2170);  //cone 6 is 2170 F
   
    // Fourth Stage  Hold 15 mins
   
     holdFifteen();
 
         // Fifth stage   slow cool with element on medium
                   
    slowCool();
 
    heatOff(); // end of firing cycle

    glazeDoneMessage(); //clear display and print DONE 
   
  break;
//*********************************************************************   
  case 3:  //Glaze program 2 Jan 24
 
    lcd.clear();         
    lcd.setCursor(0, 0);
    lcd.print("Glaze program 2");
    delay (3000);
                                   //Step 1 heat 2 hr @ 200f
    while ( elapsedTime() < 120){
      showTemperatureAndTime();
      heatKiln(25,200);
    }
   
                                 // Step 2
     lcd.clear();         
     lcd.setCursor(0, 0);
     lcd.print("GLAZE 2nd stage");
   
    while (tempVal() < 600){
     showTemperatureAndTime();
      heatKiln(50,600);
   }
   
                                 // Step 3
       lcd.clear();         
     lcd.setCursor(0, 0);
     lcd.print("GLAZE 3rd stage");                           
                                 
    while (tempVal() < 1100){
     showTemperatureAndTime();
      heatKiln(75,1100);
   }
   
                                // Step 4 cone 6 is 2170F
       lcd.clear();         
     lcd.setCursor(0, 0);
     lcd.print("GLAZE 4th stage");                           
                                 
    while (tempVal() < 2170){
     showTemperatureAndTime();
      heatHigh();
   }
    heatOff();
   
          // Stage 5 Hold 15 mins
   
     holdFifteen();
 
         //  stage 6   slow cool with element on medium
                   
    slowCool();
 
    heatOff(); // end of firing cycle

    glazeDoneMessage(); //clear display and print DONE   
   
break;


case 4:
      lcd.clear();
      showTemperatureAndTime();
      delay(10000);
break;

case 5:
break;

case 6:
break;

  }//end of switch case


} //end of main program loop

//**************FUNCTIONS*****************************************

// func to pass range value.
int knobRead (){
  // read the sensor:a 10k potentiometer
  int sensorReading = analogRead(A0);//input from potentiometer(0-1023)
  // map the sensor reading to a range of four options:
  int range = map(sensorReading, sensorMin, sensorMax, 0, 6);

  return range;


//function to display temp
int tempVal(){
  int f = thermocouple.readFarenheit();
  if (isnan(f))
  {
    lcd.print("T/C Problem");
  }
  else
  {
    return f;
    delay(200);
  }
}//end of func

//function to put text on LCD
void printKilnMode(){
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print("Kiln Mode ");
  lcd.setCursor(11, 0);

}//end of func

void displayMode(){
   printKilnMode();
      lcd.print(knobRead());
      delay(1000);
}//end of function

//function to get ET
//returns no of mins.since reset
int elapsedTime(){
  unsigned long time = millis();//gives a minute counter
  int elapsedTimeCalc = (time/60000);// since reset
  return elapsedTimeCalc;
}//end of func.

//output to element 25%
void heatLow(){
  digitalWrite(ledPin,HIGH);
  delay(2000);//on time 2 sec
  digitalWrite(ledPin,LOW);
  delay(6000);//off time 6 sec
}//end of function

//output to element 50%
void heatMedium(){
  digitalWrite(ledPin,HIGH);
  delay(4000);//on time 4 sec
  digitalWrite(ledPin,LOW);
  delay(4000);//off time 4 sec
}//end of function

//output to element 100%
void heatHigh(){
  digitalWrite(ledPin,HIGH);
  digitalWrite(ledPinTwo,HIGH);
}//end of function

//output to element 0%
void heatOff(){
  digitalWrite(ledPin,LOW);
  digitalWrite(ledPinTwo,LOW);
}//end of function

void showTemperatureAndTime(){
  lcd.setCursor(0, 1);//show temp
  lcd.print("F=");
  lcd.print(tempVal());
  lcd.setCursor(8, 1); //print elapsed time
  lcd.print("ET ");    //since reset
  lcd.setCursor(11, 1);
  lcd.print(elapsedTime());
}//end of function


void slowCool(){
   int slowCoolTime = elapsedTime(); 
   int y = slowCoolTime +60;//add 1 hour
   
         while (elapsedTime() < y){
          lcd.clear();         //print mssg
          lcd.setCursor(0, 0);
          lcd.print("slow cool");
           
         showTemperatureAndTime();
          heatMedium();               
       }// end of while loop for slow cool
 
}


void holdFifteen(){
 
      int holdTime = elapsedTime();
      int x = holdTime +15;  //add 15 to present time
   
        while (elapsedTime() < x){
           lcd.clear();         //print hold mssg
           lcd.setCursor(0, 0);
           lcd.print("Glaze Hold 15m");
           
         showTemperatureAndTime();
       
             while (tempVal() < 2170){
             heatHigh();
             showTemperatureAndTime();
             delay(500);
       }// end of while loop for temp hold
     
       heatOff();
       
  }// end of loop for hold time
   
}


void glazeDoneMessage(){
      lcd.clear();
      lcd.setCursor(6, 0);
      lcd.print("GLAZE DONE ");
     
      for(int x = 0; x < 6000; x++){
        tone(8,500);// uses pin 8 to a speaker and resistor?
        delay(500);// sounds tone for 100 minutes
        noTone(8);
        lcd.setCursor(0, 1);
        lcd.print(tempVal());
        lcd.print("F  time ");//print time since stop
        lcd.print(x/60);

    }//end of for loop 
 
}

void heatKiln (float percentHeat, int targetTemp){
  //int f = thermocouple.readFarenheit();
  if ( tempVal() < targetTemp){

    digitalWrite(ledPin,HIGH);
    delay((percentHeat/100) * 8000);//on time
    digitalWrite(ledPin,LOW);
    delay(((100-percentHeat)/100)*8000);//off time
  }
}

void endSignal(){
  for(int x = 0; x < 6000; x++){
      tone(8,500);// uses pin 8 to a 120 ohm resistor and speaker
      delay(500);// sounds tone for 100 minutes
      noTone(8);
      lcd.setCursor(0, 1);
      lcd.print(tempVal());
      lcd.print("F  time ");//print time since stop
      lcd.print(x/60);
      lcd.print("  ");

    }//end of for loop 100 mins
}