// libs for the display
#include <Elegoo_GFX.h>
#include <Elegoo_TFTLCD.h>
#include <TouchScreen.h>
#include <SPI.h>
#include <Wire.h>
// libs for the sensor
#include "Adafruit_MAX31855.h"
// display stuff, these settings are taken from Elegoo code
#define LCD_CS A3
#define LCD_CD A2
#define LCD_WR A1
#define LCD_RD A0
#define LCD_RESET A4
#define YP A3
#define XM A2
#define YM 9
#define XP 8
#define TS_MINX 120
#define TS_MAXX 900
#define TS_MINY 70
#define TS_MAXY 920
#define STATUS_X 10
#define STATUS_Y 65
// pin definition for the MAX31855 sensor board, I removed them from the display, where they are used for the SD card
#define MAXDO 12
#define MAXCS 13
#define MAXCLK 11
// define the relais at pin 10 (also removed from the display)
const int relaisIN1 = 10;
// a couple of used variables
unsigned long myTime, newTime, startTime, startTwomin, stopTwomin, newTwomin;
// maxtemp,interval temp, interval time, max time
int parameters[4] = {1050, 100, 60, 30};
int runs = 0;
float rohtemp = 650;
int timepos = 10;
float steptemp = 0;
int looptime = 0;
int oldpos = 0;
int tempcounter = 0;
int simfactor = 1;
int finished = 0;
unsigned long graphcolor = 0xF800;
// #define BLUE 0x001F
float temp = 0;
float tempinc = 10;
float oldtemp = 0;
float deltemp = 0;
float loops = 0;
float numloops = 1;
// initialize the thermocouple sensor
Adafruit_MAX31855 thermocouple(MAXCLK, MAXCS, MAXDO);
// initialize the LCD display and touchscreen
Elegoo_TFTLCD tft(LCD_CS, LCD_CD, LCD_WR, LCD_RD, LCD_RESET);
TouchScreen ts = TouchScreen(XP, YP, XM, YM, 300);
// define array of 14 buttons .. yeah I know only 13 are on the screen, too lazy to fix that ;-)
Elegoo_GFX_Button buttons[14];
void setup(void) {
Serial.begin(9600);
pinMode(relaisIN1, OUTPUT);
delay(1000);
while (!Serial) delay(1); // wait for Serial on Leonardo/Zero, etc
delay(500);
Serial.print("Initializing sensor...");
if (!thermocouple.begin()) {
Serial.println("ERROR.");
while (1) delay(10);
}
Serial.println("DONE.");
Serial.println(F("TFT LCD test"));
Serial.println(graphcolor);
tft.reset();
temp = thermocouple.readCelsius();
uint16_t identifier = 0x9341;
tft.begin(identifier);
tft.setRotation(2);
tft.fillScreen(0x0000);
tft.setTextSize(2);
tft.setCursor(10, 2); tft.print("mx Temp:");
tft.setCursor(10, 20); tft.print("iv Temp:");
tft.setCursor(10, 38); tft.print("iv Zeit:");
tft.setCursor(10, 56); tft.print("mx Zeit:");
tft.setCursor(10, 153); tft.print("mx Temp:");
tft.setCursor(10, 187); tft.print("iv Temp:");
tft.setCursor(10, 222); tft.print("iv Zeit:");
tft.setCursor(10, 257); tft.print("mx Zeit:");
tft.setTextColor(0xB596);
tft.setCursor(110, 2); tft.print(parameters[0]); tft.print(" 'C");
tft.setCursor(110, 20); tft.print(parameters[1]); tft.print(" 'C");
tft.setCursor(110, 38); tft.print(parameters[2]); tft.print(" Min");
tft.setCursor(110, 56); tft.print(parameters[3]); tft.print(" Min");
tft.setCursor(0, 0);
buttons[1].initButton(&tft, 60, 90, 112, 30, 0xFFFF, 0xDDF2, 0xFFFF, "Keramik", 2);
buttons[2].initButton(&tft, 180, 90, 112, 30, 0xFFFF, 0x94B2, 0xFFFF, "Schmelze", 2);
buttons[3].initButton(&tft, 60, 125, 112, 30, 0xFFFF, 0xD340, 0xFFFF, "Glasur", 2);
buttons[4].initButton(&tft, 180, 125, 112, 30, 0xFFFF, 0x8AC8, 0xFFFF, " ", 2);
buttons[5].initButton(&tft, 150, 160, 53, 30, 0xFFFF, 0x2C5C, 0xFFFF, "-", 2);
buttons[6].initButton(&tft, 210, 160, 53, 30, 0xFFFF, 0x2C5C, 0xFFFF, "+", 2);
buttons[7].initButton(&tft, 150, 195, 53, 30, 0xFFFF, 0x2C5C, 0xFFFF, "-", 2);
buttons[8].initButton(&tft, 210, 195, 53, 30, 0xFFFF, 0x2C5C, 0xFFFF, "+", 2);
buttons[9].initButton(&tft, 150, 230, 53, 30, 0xFFFF, 0x2C5C, 0xFFFF, "-", 2);
buttons[10].initButton(&tft, 210, 230, 53, 30, 0xFFFF, 0x2C5C, 0xFFFF, "+", 2);
buttons[11].initButton(&tft, 150, 265, 53, 30, 0xFFFF, 0x2C5C, 0xFFFF, "-", 2);
buttons[12].initButton(&tft, 210, 265, 53, 30, 0xFFFF, 0x2C5C, 0xFFFF, "+", 2);
buttons[13].initButton(&tft, 60, 300, 112, 30, 0xFFFF, 0x0400, 0xFFFF, "START", 2);
for (uint8_t b = 1; b < 14; b++) {
buttons[b].drawButton();
}
steptemp = parameters[0];
}
#define MINPRESSURE 10
#define MAXPRESSURE 1000
// read temperature from sensor or do uncomment temp=temp+0.001*simfactor; for simulation
void gettemp() {
temp = thermocouple.readCelsius();
// temp = temp + 0.001 * simfactor;
}
void relais(int onoff) {
switch (onoff) {
case 0: if (digitalRead(relaisIN1) == HIGH) {
digitalWrite(relaisIN1, LOW); // relais1 off
// lower the temperature for simulation
Serial.println("off");
simfactor = -1;
} break;
case 1: if (digitalRead(relaisIN1) == LOW) {
digitalWrite(relaisIN1, HIGH); // relais1 on
// increase the temperature for simulation
simfactor = +1;
Serial.println("on");
} break;
}
}
void dostop() {
relais(0);
graphcolor = 0x001F;
tempcounter++;
if (tempcounter == 1000) {
tft.setCursor(150, 22); tft.setTextSize(2); tft.setTextColor(0x0000); tft.print(round(deltemp));
tft.setCursor(150, 22); tft.setTextSize(2); tft.setTextColor(0x07FF); tft.print(round(temp));
deltemp = temp;
tempcounter = 0;
}
if (newTwomin > (startTwomin + 120000)) {
drawtemp();
startTwomin = newTwomin;
}
if (temp < 30) {
while (1) {}
}
}
void drawtemp() {
Serial.println("draw");
tft.drawLine(timepos, 308 - (round(oldtemp / 5)), timepos + 1, 308 - (round(temp / 5)), graphcolor);
timepos = timepos + 1;
oldtemp = temp;
}
void intervall(long laufzeit) {
newTime = millis();
// set a start time
startTime = millis();
// start the two minute timer for the graph
// repeat as long as the running time is lower than the interval time laufzeit*60*1000 (minutes to seconds to milliseconds)
while ((millis() - startTime) < (laufzeit * 60 * 1000)) {
// Serial.print("L");
newTwomin = millis();
gettemp();
// draw the curve when the timer hits two minutes, then reset the timer
if (newTwomin > (startTwomin + 120000)) {
drawtemp();
startTwomin = newTwomin;
}
// if the temperature gets higher than the set temperature shut down the heating
if (temp > steptemp + 3) {
relais(0);
}
// if the temperature gets too low enable the heating again
if (temp < steptemp - 3) {
relais(1);
}
printtemp();
} // while end
loops = loops + 1;
// if there is only one heating intervall stop once it is done
if (parameters[1] == 0) {
finished = 1;
timepos = 10;
relais(0);
}
// once reached the biscuit firing go to the final temperature and hold it
if (steptemp == rohtemp) {
// heat up to the final temperature
steptemp = parameters[0];
// set the heating time for the final heating
parameters[2] = parameters[3];
} else {
// increase the temperature to the next step
steptemp = (steptemp + parameters[1]);
relais(1);
}
// if temperature is higher than biscuit them set the current target to biscuit temperature
if (steptemp > rohtemp && steptemp < parameters[0]) {
steptemp = rohtemp;
}
if (temp > parameters[0] - 5) {
relais(0);
timepos = 10;
dostop();
}
}
// this function sets the presets
void setparameters(int x, int y, int color, int mt, int it, int iz, int mz) {
tft.setTextColor(0x0000);
tft.setCursor(x, y); tft.print(parameters[0]); tft.print(" 'C");
tft.setCursor(x, y + 18); tft.print(parameters[1]); tft.print(" 'C");
tft.setCursor(x, y + 36); tft.print(parameters[2]); tft.print(" Min");
tft.setCursor(x, y + 54); tft.print(parameters[3]); tft.print(" Min");
parameters[0] = mt;
parameters[1] = it;
parameters[2] = iz;
parameters[3] = mz;
tft.setTextColor(color);
tft.setCursor(x, y); tft.print(mt); tft.print(" 'C");
tft.setCursor(x, y + 18); tft.print(it); tft.print(" 'C");
tft.setCursor(x, y + 36); tft.print(iz); tft.print(" Min");
tft.setCursor(x, y + 54); tft.print(mz); tft.print(" Min");
}
// this function updates the values time and temperature when pressing +/-
void incdec(int x, int y, int color, int orig, int factor) {
tft.setCursor(x, y); tft.setTextColor(0x0000); tft.print(parameters[orig]); tft.print(" 'C");
tft.setCursor(x, y); tft.setTextColor(0x0000); tft.print(parameters[orig]); tft.print(" Min");
newTime = millis();
// wenn touchscreen länger gedrückt beschleunige auf 10er Schritte, ansonsten +/- 1
if (newTime - myTime < 160) {
parameters[orig] = parameters[orig] + 10 * factor;
} else {
parameters[orig] = parameters[orig] + 1 * factor;
}
if (parameters[orig] < 0) parameters[orig] = 0;
tft.setCursor(x, y); tft.setTextColor(color); tft.print(parameters[orig]);
if (orig > 1) {
tft.print(" Min");
} else {
tft.print(" 'C");
}
myTime = millis();
}
void printtemp() {
tempcounter++;
if (tempcounter == 1000) {
// print the old temp with black
tft.setCursor(150, 22); tft.setTextSize(2); tft.setTextColor(0x0000); tft.print(round(deltemp));
// print the current temp
tft.setCursor(150, 22); tft.setTextSize(2); tft.setTextColor(0xB596); tft.print(round(temp));
deltemp = temp;
tempcounter = 0;
}
}
void loop(void) {
// some copied routines from elegoo for the touch control and buttons
digitalWrite(13, HIGH);
TSPoint p = ts.getPoint();
digitalWrite(13, LOW);
pinMode(XM, OUTPUT);
pinMode(YP, OUTPUT);
if (p.z > MINPRESSURE && p.z < MAXPRESSURE) {
p.x = map(p.x, TS_MINX, TS_MAXX, tft.width(), 0);
p.y = (tft.height() - map(p.y, TS_MINY, TS_MAXY, tft.height(), 0));
}
// go thru all the buttons, checking if they were pressed
for (uint8_t b = 0; b < 14; b++) {
if (buttons[b].contains(p.x, p.y)) {
buttons[b].press(true); // tell the button it is pressed
} else {
buttons[b].press(false); // tell the button it is NOT pressed
}
}
if (runs == 1) {
// clear screen
tft.fillScreen(0x0000);
// draw grid
tft.setTextColor(0xEEEE);
tft.setCursor(2, 22); tft.print("Temperatur:");
for (uint8_t i = 1; i < 27; i++) {
tft.drawLine(10, 38 + i * 10, 230, 38 + i * 10, 0x5AEB);
if ((i - 1) % 3 == 0) {
tft.drawLine(0 + i * 10, 48, 0 + i * 10, 309, 0x00EB);
} else {
tft.drawLine(0 + i * 10, 48, 0 + i * 10, 300, 0x00EB);
}
tft.setTextSize(1); tft.setTextColor(0xB596);
tft.setCursor(0, 30 + i * 10);
tft.print(1350 - i * 50);
}
// draw coords X axis, sadly no linear spacing so one by one
tft.setCursor(8, 310); tft.print("0");
tft.setCursor(35, 310); tft.print("60");
tft.setCursor(62, 310); tft.print("120");
tft.setCursor(92, 310); tft.print("180");
tft.setCursor(121, 310); tft.print("240");
tft.setCursor(152, 310); tft.print("300");
tft.setCursor(182, 310); tft.print("360");
tft.setCursor(212, 310); tft.print("420");
if (parameters[1] > 0) {
numloops = ceil(rohtemp / parameters[1]);
}
// if there are no more heating intervals go to the main temperature, otherwise go to next loop
if (parameters[1] == 0 && loops < 1) {
steptemp = parameters[0];
parameters[2] = parameters[3];
} else if (parameters[1] > 0 && loops < numloops) {
steptemp = parameters[1];
}
// relais on, start heating
relais(1);
// go to the heating loops
runs = 2;
}
if (runs == 2) {
// since there is no rtc, create a timer
if (startTime == 0) {
startTime = millis();
}
// zwei Minuten Timer starten
if (startTwomin == 0) {
startTwomin = millis();
}
// read temperature from sensor (or simulate)
gettemp();
// for how long is the program running already?
newTime = millis();
newTwomin = millis();
// draw graph all two minutes
if (newTwomin > (startTwomin + 120000)) {
drawtemp();
startTwomin = newTwomin;
}
// if destination temperature reached start the heating loop
if (temp > steptemp - 1 && parameters[1] > 0 && loops < numloops + 1) {
intervall(parameters[2]); // loop time
} else if (temp > parameters[0] - 1 && loops < 1) {
intervall(parameters[3]); // final time
}
// draw cooling graph in blue
if (numloops == loops) {
graphcolor = 0x001F;
}
printtemp();
} else {
for (uint8_t b = 1; b < 14; b++) {
if (buttons[b].justReleased()) {
buttons[b].drawButton(); // unpressed
}
if (buttons[b].justPressed()) {
buttons[b].drawButton(true); // pressed
switch (b) {
// presets
case 1: setparameters(110, 2, 0xB596, 1050, 100, 60, 30); break; // Keramik
case 2: setparameters(110, 2, 0xB596, 250, 0, 0, 30); break; // Schmelze
case 3: setparameters(110, 2, 0xB596, 1050, 0, 0, 30); break; // Glasur
case 5: incdec(110, 2, 0xB596, 0, -1); break; // if (parameters[0]<30) parameters[0]=30; - maxtemp
case 6: incdec(110, 2, 0xB596, 0, 1); break; // if (parameters[0]>1050) parameters[0]=1050; + maxtemp
case 7: incdec(110, 20, 0xB596, 1, -1); break; // if (parameters[1]<30) parameters[1]=30; - ivtemp
case 8: incdec(110, 20, 0xB596, 1, 1); break; // if (parameters[1]>1050) parameters[1]=1050; + ivtemp
case 9: incdec(110, 38, 0xB596, 2, -1); break; // - iv Time
case 10: incdec(110, 38, 0xB596, 2, 1); break; // + iv Time
case 11: incdec(110, 56, 0xB596, 3, -1); break; // - max Time
case 12: incdec(110, 56, 0xB596, 3, 1); break; // + max Time
case 13: runs = 1; break; // start pressed
}
// little delay to prevent uncontrolled ui reactions
delay(100);
}
}
}
}