// ***** INCLUDES *****
#include <SPI.h>
#include <Wire.h>
#include <EEPROM.h>
#include <LiquidCrystal.h>
#include <Adafruit_GFX.h> // Comment for VERSION 1
#include <Adafruit_SSD1306.h> // Comment for VERSION 1
#include <Adafruit_MAX31856.h>
#include <PID_v1.h>
#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels
#define X_AXIS_START 18 // X-axis starting position
// ***** DEGREE SYMBOL FOR LCD *****
unsigned char degree[8] = {
140, 146, 146, 140, 128, 128, 128, 128
};
unsigned char ssrPin = A0;
unsigned char fanPin = A1;
unsigned char thermocoupleCSPin = 10;
unsigned char ledPin = 4;
unsigned char buzzerPin = 5;
unsigned char switchStartStopPin = 3;
unsigned char switchLfPbPin = 2;
int windowSize;
unsigned long windowStartTime;
unsigned long nextCheck;
unsigned long nextRead;
unsigned long updateLcd;
unsigned int timerSeconds;
// Thermocouple fault status
unsigned char fault;
unsigned int timerUpdate;
unsigned char temperature[SCREEN_WIDTH - X_AXIS_START];
unsigned char x;
#define UPDATE_RATE 100
double input;
double output;
double setpoint;
double kp=2,ki=5,kd=1;
PID myPID(&input, &output, &setpoint,kp,ki,kd,DIRECT);
int targetTemp = 50;
int tolerance = 1;
int timer = -1;
int overrideOff = false;
int timeToCookInMilli = 3 * 60 * 1000;
Adafruit_SSD1306 oled(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire);
Adafruit_MAX31856 thermocouple = Adafruit_MAX31856(thermocoupleCSPin);
void setup()
{
// SSR pin initialization to ensure reflow oven is off
digitalWrite(ssrPin, LOW);
pinMode(ssrPin, OUTPUT);
setpoint = 50;
//turn the PID on
myPID.SetMode(AUTOMATIC);
// Initialize thermocouple interface
thermocouple.begin();
thermocouple.setThermocoupleType(MAX31856_TCTYPE_K);
oled.begin(SSD1306_SWITCHCAPVCC, 0x3C);
oled.display();
delay(2000);
///
oled.clearDisplay();
oled.setTextSize(1);
oled.setTextColor(WHITE);
oled.setCursor(0, 0);
oled.println(F(" Temp"));
oled.println(F(" Test"));
oled.println();
oled.println(F(" v1.00"));
oled.println();
oled.println(F(" 29-03-21"));
oled.display();
delay(3000);
oled.clearDisplay();
// Serial communication at 115200 bps
Serial.begin(115200);
// Set window size
windowSize = 2000;
// Initialize time keeping variable
nextCheck = millis();
// Initialize thermocouple reading variable
nextRead = millis();
// Initialize LCD update timer
updateLcd = millis();
}
void loop()
{
// Current time
unsigned long now;
// Time to read thermocouple?
if (millis() > nextRead)
{
// Read current temperature
input = thermocouple.readThermocoupleTemperature();
}
////////////////
if (millis() > updateLcd)
{
// Update LCD in the next 100 ms
updateLcd += UPDATE_RATE;
oled.clearDisplay();
oled.setTextSize(2);
oled.setCursor(0, 0);
oled.setTextSize(1);
oled.setCursor(115, 0);
// Temperature markers
oled.setCursor(0, 18);
oled.print(F("250"));
oled.setCursor(0, 36);
oled.print(F("150"));
oled.setCursor(0, 54);
oled.print(F("50"));
// Draw temperature and time axis
oled.drawLine(18, 18, 18, 63, WHITE);
oled.drawLine(18, 63, 127, 63, WHITE);
oled.setCursor(115, 0);
if (input < 10) oled.setCursor(91, 9);
else if (input < 100) oled.setCursor(85,9);
else oled.setCursor(80, 9);
// Display current temperature
oled.print(input);
oled.print((char)247);
oled.print(F("C"));
Serial.print(input);
Serial.print((char)247);
Serial.print(F("C"));
delay(500);
if (timerSeconds > timerUpdate)
{
// Store temperature reading every 3 s
if ((timerSeconds % 3) == 0)
{
timerUpdate = timerSeconds;
unsigned char averageReading = map(input, 0, 250, 63, 19);
if (x < (SCREEN_WIDTH - X_AXIS_START))
{
temperature[x++] = averageReading;
}
}
}
unsigned char timeAxis;
for (timeAxis = 0; timeAxis < x; timeAxis++)
{
oled.drawPixel(timeAxis + X_AXIS_START, temperature[timeAxis], WHITE);
}
// Update screen
oled.display();
}
if (input > targetTemp + tolerance) {
// close relay
digitalWrite(ssrPin, LOW);
} else if (input < targetTemp - tolerance) {
myPID.Compute();
digitalWrite(ssrPin, HIGH);
}
if (timer == -1 && input > targetTemp - tolerance && input < targetTemp + tolerance) {
timer = millis();
}
if (timer != -1 && millis() >= timer + timeToCookInMilli) {
// jobs done.
}
}