Tinkers Projects

Imagine | Develop | Create

Programable Reflow Oven

Categories: PLEX
Programable Reflow OvenMain
Programable Reflow Oven0
Programable Reflow Oven1
Programable Reflow Oven2

Programable Reflow Oven

Categories: PLEX

After making the reflow oven, I wanted to make the oven more universal. An oven can e a help tool for heating, curing and drying.

The first setup just had one program that could be adjusted within limits. The controller had a temperature profile programmed into it and the user could change the temperature and the duration time at that temperature. Each setting had limits. Once the settings are saved, the user would need to change the settings again for a different function.

The new Controller can almost be programmed to do any type of heating between the room temperature and 250 degrees Celsius. It can be easily programmed/changed using G-code on an SD card, each file is a different programmed oven function. this allows the oven to almost do any temperature profile.

Using the oven

Using the oven is very simple, ensure the SD is inserted and has the correct program file required for the temperature profile. Power the oven controller and using the up/down buttons, navigate to the correct file and press enter(middle button). the oven will now start running that programmed temperature profile.

Code for Project

GNU General Public License v3.0
#include <Plex.h>
#include "max6675.h"
#include <gcode.h>
#include <SPI.h>
#include <SD.h>

#define UpPin 14
#define DownPin 15
#define SelectPin 16

#define replayPin A3
#define buzzerPin A4

#define NumberOfMenuItems 7

#define ktcCLK 13 /// change
#define ktcCS 13 /// change
#define ktcSO 13 /// change

#define MAX_FILE_SIZE 1024
#define JSON_BUFFER_SIZE 512



void rampOven();
void stepOven();
void ToTemp();
void Finished();

commandscallback commands[6] = {{"G1",ToTemp},
                                {"G2",stepOven},
                                {"G3",rampOven},
                                {"G4",Finished}};

gcode Commands(6,commands);
Plex PLEX;
MAX6675 ktc(ktcCLK, ktcCS, ktcSO);

File dir;
File Files;

unsigned long currentPosInFile = 0;
bool Running = false;
int fileID = -1;
long inPos = 0;

int menuLocation = 0;

int  type = 0;
long temp = 0;
long time = 0;
                                

void setup() 
{
  Serial.begin(115200);
  Serial.println("Start");
  
  pinMode(UpPin, INPUT);
  pinMode(DownPin, INPUT);
  pinMode(SelectPin, INPUT);
  pinMode(replayPin,OUTPUT);
  digitalWrite(replayPin,LOW);
  pinMode(buzzerPin,OUTPUT);
  digitalWrite(buzzerPin,LOW);


  PLEX.lcd.clear();
  PLEX.lcd.print("  Oven Control  ");
  PLEX.lcd.setCursor(0, 1);
  PLEX.lcd.print("Tinkers Projects");

  delay(3000);
  

  while (!SD.begin(10))
  {
    PLEX.lcd.clear();
    PLEX.lcd.print("Card failed");
  }

  loadMenuLocation();
}

void loop() 
{
  onOven(-10000);

  if(fileID != menuLocation)
  {
    PrintFileName();
  }
  
  if(digitalRead(UpPin)==HIGH)
  {
      menuLocation--;// menu will go up but the count will go down
      delay(200);
      PrintFileName();
      while(digitalRead(UpPin)==HIGH){}
  }

  if(digitalRead(DownPin)==HIGH)
  {
      menuLocation++;// menu will go dpwn but the count will go up
      delay(200);
      PrintFileName();
      while(digitalRead(DownPin)==HIGH){}
  }

  if(digitalRead(SelectPin)==HIGH)
  {
      delay(200);
      while(digitalRead(SelectPin)==HIGH);
      saveMenuLocation();
      Run();
      PrintFileName();
  } 

}
/*
void PrintFileName(File entry,File NextFiles)
{
    PLEX.lcd.setCursor(0, 0);
    PLEX.lcd.print(">");
    PLEX.lcd.print(entry.name());
    PLEX.lcd.print("                ");
    PLEX.lcd.setCursor(0, 1);
    if(NextFiles)
    {
      PLEX.lcd.print(entry.name());
    }
    PLEX.lcd.print("                ");
}*/



// OLD
void PrintFileName() 
{
  fileID = menuLocation;
      if(menuLocation<0)
        menuLocation = 0;
      Files = getFile(menuLocation);  
      if(Files) 
      {
        PLEX.lcd.clear();
        PLEX.lcd.setCursor(0,0);
        PLEX.lcd.print(Files.name());
        
        File NextFiles = getFile(menuLocation+1);
        if(NextFiles) 
        {
          PLEX.lcd.setCursor(0,1);
          PLEX.lcd.print(NextFiles.name());
        }
      }
      else if(menuLocation>0) 
        menuLocation = menuLocation-1;
}


File getFile(int number) 
{
  int count = 0;
  dir = SD.open("/");
  while (true) 
  {
    File entry =  dir.openNextFile();
    
    if (!entry.available())
    {
      return entry;
    }
    
    if (!entry.isDirectory()) 
    {
      
      if(number == count)return entry;
      count++;
    }
    entry.close();
  }
}


void Run()
{
  temp = 0;
  time = 0;
  
  File dataFile = getFile(fileID);
  if(dataFile) 
  {
    while (dataFile.available()) 
    {
      char SDinput = dataFile.read();
      Serial.print(SDinput);
      if(Commands.available(SDinput))
      {
        if(Commands.availableValue('F'))
          temp = (Commands.GetValue('F')− 32) × 5/9;
        if(Commands.availableValue('C'))
          temp = Commands.GetValue('C');
        if(Commands.availableValue('S'))
          time = Commands.GetValue('S');
          
      Serial.println(temp);
      Serial.println(time);
        Commands.clearBuffer();
      }
    }
  }
  dataFile.close();

  onOven(-10000);
}



void rampOven()
{
  Serial.println("rampOven");
  if(Commands.availableValue('F'))
    temp = (Commands.GetValue('F')− 32) × 5/9;
  if(Commands.availableValue('C'))
    temp = Commands.GetValue('C');
  if(Commands.availableValue('S'))
    time = Commands.GetValue('S');
  rampOven(time, temp);
}

void stepOven()
{
  Serial.println("stepOven");
  if(Commands.availableValue('F'))
    temp = (Commands.GetValue('F')− 32) × 5/9;
  if(Commands.availableValue('C'))
    temp = Commands.GetValue('C');
  if(Commands.availableValue('S'))
    time = Commands.GetValue('S');
  stepOven(time, temp);
}

void ToTemp()
{
  Serial.println("ToTemp");
  if(Commands.availableValue('F'))
    temp = (Commands.GetValue('F')− 32) × 5/9;
  if(Commands.availableValue('C'))
    temp = Commands.GetValue('C');
  ToTemp(temp);
}


void rampOven(long time, long temp)
{
  unsigned long FinishTime = millis()+time*1000;
  unsigned long startTime = millis();
  long startTemp = ktc.readCelsius();
  
  while(FinishTime>millis())
  {
    long G = (temp - startTemp)/(time*1000);
    long currentRampTemp = G*millis()+startTemp;
    unsigned long timeLeft = (FinishTime - millis())/1000;
    onOven(currentRampTemp);
    
    PLEX.lcd.setCursor(0, 1);
    PLEX.lcd.print((int)currentRampTemp);
    PLEX.lcd.print("C   ");
    
    PLEX.lcd.setCursor(5, 1);
    PLEX.lcd.print((int)ktc.readCelsius());
    PLEX.lcd.print("C   ");
    
    PLEX.lcd.setCursor(10, 1);
    PLEX.lcd.print(timeLeft);
    PLEX.lcd.print("Sec    ");
  }
}

void stepOven(long time, long temp)
{
  unsigned long FinishTime = millis()+time*1000;

  while(FinishTime>millis())
  {
    unsigned long timeLeft = (FinishTime - millis())/1000;
    onOven(temp);
    
    PLEX.lcd.setCursor(0, 1);
    PLEX.lcd.print((int)temp);
    PLEX.lcd.print("C   ");
    
    PLEX.lcd.setCursor(5, 1);
    PLEX.lcd.print((int)ktc.readCelsius());
    PLEX.lcd.print("C   ");
    
    PLEX.lcd.setCursor(10, 1);
    PLEX.lcd.print(timeLeft);
    PLEX.lcd.print("Sec    ");
  }
}

unsigned long starttotemp;

void ToTemp(long temp)
{
  starttotemp = millis()+300000;
  while(ktc.readCelsius()<temp-10 && starttotemp>millis)
  {
    onOven(temp);
    PLEX.lcd.setCursor(0, 1);
    PLEX.lcd.print((int)temp);
    PLEX.lcd.print("C   ");
    
    PLEX.lcd.setCursor(5, 1);
    PLEX.lcd.print((int)ktc.readCelsius());
    PLEX.lcd.print("C   ");
  }
}

void onOven(long temp)
{
  long currentTemp = ktc.readCelsius();
  if(currentTemp<temp-10)
  {
    digitalWrite(replayPin,HIGH);
  }
  if(currentTemp>temp)
  {
    digitalWrite(replayPin,LOW);
  }
}

void Finished()
{
  onOven(-10000);
  digitalWrite(replayPin,LOW);
  digitalWrite(buzzerPin,HIGH);
  delay(2000);
  digitalWrite(buzzerPin,LOW);
}

void Error()
{
  onOven(-10000);
  digitalWrite(replayPin,LOW);
  digitalWrite(buzzerPin,HIGH);
  delay(2000);
  digitalWrite(buzzerPin,LOW);
}





















void loadMenuLocation()
{
          Serial.println("load:");
  File ovenControllerFile = SD.open("ovenController.data",FILE_READ);
  if (ovenControllerFile) {
    
          Serial.println("ovenController");
    String currentFileName = "";
    while (ovenControllerFile.available()) {
      currentFileName += String(ovenControllerFile.read());
    }
    ovenControllerFile.close();
    
    int count = 0;
    dir = SD.open("/");
    while (true) 
    {
      File entry =  dir.openNextFile();
      if (!entry.isDirectory()) 
      {
        if(currentFileName.equals(entry.name()))
        {
          Serial.print("got:");
          Serial.print(currentFileName);
          Serial.print(",");
          Serial.print(currentFileName);
          Serial.println(entry.name());
          break;
        }
        count++;
      }
      entry.close();
    }
    menuLocation = count;
    ovenControllerFile.close();
  }
}

void saveMenuLocation()
{
  File ovenControllerFile = SD.open("ovenController.data", FILE_WRITE);
  File file = getFile(menuLocation);
  if (file && ovenControllerFile) 
  {
          Serial.println(file.name());
    ovenControllerFile.print(file.name());
    ovenControllerFile.close();
  }

}

After making the reflow oven, I wanted to make the oven more universal. An oven can e a help tool for heating, curing and drying.

The first setup just had one program that could be adjusted within limits. The controller had a temperature profile programmed into it and the user could change the temperature and the duration time at that temperature. Each setting had limits. Once the settings are saved, the user would need to change the settings again for a different function.

The new Controller can almost be programmed to do any type of heating between the room temperature and 250 degrees Celsius. It can be easily programmed/changed using G-code on an SD card, each file is a different programmed oven function. this allows the oven to almost do any temperature profile.

Using the oven

Using the oven is very simple, ensure the SD is inserted and has the correct program file required for the temperature profile. Power the oven controller and using the up/down buttons, navigate to the correct file and press enter(middle button). the oven will now start running that programmed temperature profile.

Related Projects