diff --git a/Hotplate_Oled_420CW_31856_20221122_eeprom/Functions.ino b/Hotplate_Oled_420CW_31856_20221122_eeprom/Functions.ino new file mode 100644 index 0000000..8a71eea --- /dev/null +++ b/Hotplate_Oled_420CW_31856_20221122_eeprom/Functions.ino @@ -0,0 +1,553 @@ + +/***************************************************** +* Keyboard action * +*****************************************************/ + +void readKeys(){ + + enterKey = digitalRead(enter); + rightKey = digitalRead(right); + leftKey = digitalRead(left); + upKey = digitalRead(up); + downKey = digitalRead(down); + + if (enterKey == pressed){ + keyIn = true; + if (scrNr == 0 && enterKeyblk == false){ + enterKeyblk = true; + enter0Script(); + } + if (scrNr == 1 && enterKeyblk == false){ + enterKeyblk = true; + enter1Script(); + } + if (scrNr == 2 && enterKeyblk == false){ + enterKeyblk = true; + enter2Script(); + } + if (scrNr == 3 && enterKeyblk == false){ + enterKeyblk = true; + enter3Script(); + } + } + if (enterKey == released){ + if (enterKeyblk == true){ + enterKeyblk = false; + } + } + + if (rightKey == pressed){ + keyIn = true; + if (rightKeyblk == false){ + if(repeatRightLeftKeyblk == false) rightKeyblk = true; + if (scrNr == 1){ + if (recipeNr0 == 0){ + right1Script(); + } + } + if (scrNr == 2){ + right2Script(); + } + } + } + if (rightKey == released){ + if (rightKeyblk == true){ + rightKeyblk = false; + } + } + + if (leftKey == pressed){ + keyIn = true; + if (leftKeyblk == false){ + if(repeatRightLeftKeyblk == false) leftKeyblk = true; + if (scrNr == 1){ + if (recipeNr0 == 0){ + left1Script(); + } + } + if (scrNr == 2){ + left2Script(); + } + if (scrNr == 3){ + left3Script(); + } + } + } + if (leftKey == released){ + if (leftKeyblk == true){ + leftKeyblk = false; + } + } + + if (upKey == pressed ){ + keyIn = true; + if (upKeyblk == false){ + if(repeatUpdownKeyblk == false) upKeyblk = true; + if (scrNr == 0){ + up0Script(); + } + if (scrNr == 1){ + up1Script(); + } + if (scrNr == 2){ + up2Script(); + } + if (scrNr == 3){ + up3Script(); + } + } + } + if (upKey == released){ + if (upKeyblk == true){ + upKeyblk = false; + } + } + + if (downKey == pressed){ + keyIn = true; + if (downKeyblk == false){ + if(repeatUpdownKeyblk == false) downKeyblk = true; + if (scrNr == 0){ + down0Script(); + } + if (scrNr == 1){ + down1Script(); + } + if (scrNr == 2){ + down2Script(); + } + if (scrNr == 3){ + down3Script(); + } + } + } + if (downKey == released){ + if(downKeyblk == true){ + downKeyblk = false; + } + } + + if ((enterKey & rightKey & leftKey & upKey & downKey) == released){keyIn = false; start_scr_timer = true;} else {start_scr_timer = false;} + if ((upKey == pressed || downKey == pressed) && enter1Pos==0){blocktemp=true;} else {blocktemp=false;} + if (upKey == pressed & downKey == pressed){/*Enter reset code here*/} +} + +/***************************************************** +* Place a value on x,y position * +*****************************************************/ + +void placeValue(int row, int col, int len, int dec, float oldvalue, float value) +{ + + String svalue = String(oldvalue,dec); + int lvalue = svalue.length(); // length of value to send to the display + for( int i=0;i"); + oled.display(); +} + +/***************************************************** +* Thermcouple errors * +*****************************************************/ + +void thermocoupleErrors(uint8_t fault) { + if (fault & MAX31856_FAULT_CJRANGE) statusMessage(10); + if (fault & MAX31856_FAULT_TCRANGE) statusMessage(11); + if (fault & MAX31856_FAULT_CJHIGH) statusMessage(12); + if (fault & MAX31856_FAULT_CJLOW) statusMessage(13); + if (fault & MAX31856_FAULT_TCHIGH) statusMessage(14); + if (fault & MAX31856_FAULT_TCLOW) statusMessage(15); + if (fault & MAX31856_FAULT_OVUV) statusMessage(16); + if (fault & MAX31856_FAULT_OPEN) statusMessage(17); + setAlert = true; +} + +/***************************************************** +* Place elements on main screen * +*****************************************************/ + +void mainScreen(){ + scrNr = 0; + layoutput(0); + + // Draw border + oled.drawLine(9*font_with+2, 0, 9*font_with+2, 19, bordercolor); + oled.drawLine(20*font_with+4, 0, 20*font_with+4, 19, bordercolor); + oled.drawLine(0, 0, 0, 48, bordercolor); + oled.drawLine(255, 0, 255, 48, bordercolor); + oled.drawLine(0, 0, 255, 0, bordercolor); + oled.drawLine(0, 49, 255, 49, bordercolor); + oled.drawLine(0, 19, 255, 19, bordercolor); + outbar(30, 83, 102); + + oled.drawCircle(15*font_with+5, 7, 2, SSD1322_WHITE); // degrees Celsius 'o' + + tempControl(POSX[1][2]+1); + placeValue(0, POSX[1][3]+1, 3, 0, timeCounter0, timeCounter0); // place actual procestime on screen + + changeMode(oldenter1Pos, enter1Pos); + curpos = 0; + changePos(curpos, true); // Place the cursor + //oled.display(); +} + +/***************************************************** +* Place elements on single screen * +*****************************************************/ + +void singleScreen(){ + scrNr = 1; + layoutput(1); + + // Draw border + oled.drawLine(9*font_with+2, 0, 9*font_with+2, 48, bordercolor); + oled.drawLine(20*font_with+4, 0, 20*font_with+4, 48, bordercolor); + oled.drawLine(0, 0, 0, 48, bordercolor); + oled.drawLine(255, 0, 255, 48, bordercolor); + oled.drawLine(0, 0, 255, 0, bordercolor); + oled.drawLine(0, 49, 255, 49, bordercolor); + oled.drawLine(0, 19, 255, 19, bordercolor); + + oled.drawCircle(15*font_with+5, 7, 2, SSD1322_WHITE); // degrees Celsius 'o' + oled.drawCircle(15*font_with+5, 39, 2, SSD1322_WHITE); // degrees Celsius 'o' + + tempControl(POSX[1][2]+1); + + tempValue0 = RECIPES[recipeNr0][0]; + oldtempValue0 = tempValue0; + timeValue0 = RECIPES[recipeNr0][1]; + oldtimeValue0 = timeValue0; + + placeValue(0, POSX[1][3]+1, 3, 0, timeCounter0, timeCounter0); // place actual procestime on screen + placeValue(2, POSX[1][1]+1, 2, 0, recipeNr0, recipeNr0); // place set recipe number on screen + placeValue(2, POSX[1][2]+1, 3, 0, tempValue0, tempValue0); // place set temperature on screen + placeValue(2, POSX[1][3]+1, 3, 0, timeValue0, timeValue0); // place set procestime on screen + + changeMode(enter1Pos, enter1Pos); // Change to STOP mode + statusMessage(enter1Pos); // Show the STOP message + digitalWrite(vacuum, false); // Vacuum off + //pins_up_with_delay = 1; // Pins up after a delay + curpos = 0; + changePos(curpos, true); // Place the cursor + + //oled.display(); +} + +/***************************************************** +* Place elements on Recipe screen * +*****************************************************/ + +void curveSetupScreen(){ + scrNr = 2; + layoutput(2); + + // Draw border + oled.drawLine(9*font_with+2, 0, 9*font_with+2, 19, bordercolor); + oled.drawLine(20*font_with+4, 0, 20*font_with+4, 19, bordercolor); + oled.drawLine(7*font_with+4, 19, 7*font_with+4, 49, bordercolor); + oled.drawLine(14*font_with, 19, 14*font_with, 49, bordercolor); + oled.drawLine(21*font_with+4, 19, 21*font_with+4, 49, bordercolor); + oled.drawLine(0, 0, 0, 48, bordercolor); + oled.drawLine(255, 0, 255, 48, bordercolor); + oled.drawLine(0, 0, 255, 0, bordercolor); + oled.drawLine(0, 49, 255, 49, bordercolor); + oled.drawLine(0, 19, 255, 19, bordercolor); + + oled.drawCircle(15*font_with+5, 7, 2, SSD1322_WHITE); // degrees Celsius 'o' + oled.drawCircle(19*font_with+5, 39, 2, SSD1322_WHITE); // degrees Celsius 'o' + + tempControl(POSX[1][2]+1); + + tempValue1 = CURVES[curveNr1][pointNr1][0]; + oldtempValue1 = tempValue1; + timeValue1 = CURVES[curveNr1][pointNr1][1]; + oldtimeValue1 = timeValue1; + + placeValue(0, POSX[1][3]+1, 3, 0, timeCounter1, timeCounter1); // place actual procestime on screen + placeValue(2, POSX[2][1]+1, 2, 0, curveNr1, curveNr1); // place set curve number on screen + placeValue(2, POSX[2][2]+1, 2, 0, pointNr1, pointNr1); // place set point number on screen + placeValue(2, POSX[2][3]+1, 3, 0, oldtempValue1, tempValue1); // place set temperature on screen + placeValue(2, POSX[2][4]+1, 3, 0, oldtimeValue1, timeValue1); // place set procestime on screen + + + changeMode(oldenter1Pos, enter1Pos); + statusMessage(enter1Pos); // Show the status message + curpos = 0; + changePos(curpos, true); // Place the cursor + //oled.display(); +} + +/***************************************************** +* Place elements on Curve screen * +*****************************************************/ + +void curveScreen(){ + + pointcnt = 1; + scrNr = 3; + layoutput(3); + + // Draw border + oled.drawLine(7*font_with+2, 0, 7*font_with+2, 19, bordercolor); + oled.drawLine(15*font_with+4, 0, 15*font_with+4, 19, bordercolor); + oled.drawLine(22*font_with+4, 0, 22*font_with+4, 19, bordercolor); + oled.drawLine(0, 0, 0, 63, bordercolor); + oled.drawLine(255, 0, 255, 63, bordercolor); + oled.drawLine(0, 0, 255, 0, bordercolor); + oled.drawLine(0, 63, 255, 63, bordercolor); + oled.drawLine(0, 19, 255, 19, bordercolor); + + oled.drawCircle(19*font_with+5, 7, 2, SSD1322_WHITE); // degrees Celsius 'o' + oled.drawCircle(12*font_with+5, 7, 2, SSD1322_WHITE); // degrees Celsius 'o' + + placeValue(0, POSX[1][2] -2, 3, 0, oldSetpoint, Setpoint); + + tempControl(POSX[1][2]+1); + placeValue(0, POSX[1][3]+1, 3, 0, timeCounter1, timeCounter1); // place actual procestime on screen + + + oled.setFont(&DejaVu_Sans_Mono_9); + + oled.setTextColor(SSD1322_WHITE); + oled.setCursor(7*font_with+3, 12); oled.print("sp"); + + curvetimescale = 0; + for (int i = 0; i <= 10; i++) { + if (CURVES[curveNr1][i][1] > curvetimescale){ + curvetimescale = CURVES[curveNr1][i][1]; + } + } + float timedev = curvetimescale/10; + curvetempscale = 0; + for (int i = 0; i <= 10; i++) { + if (CURVES[curveNr1][i][0] > curvetempscale){ + curvetempscale = CURVES[curveNr1][i][0]; + } + } + float tempdev = curvetempscale/50; + + oled.setTextColor(SSD1322_WHITE); + oled.setCursor(2, 28); oled.print(curvetempscale,0); + oled.drawCircle(12, 32, 1, SSD1322_WHITE); // degrees Celsius 'o' + oled.setCursor(14, 38); oled.print("C"); + oled.setCursor(14, 62); oled.print(0); + oled.setCursor(235, 55); oled.print(curvetimescale,0); + oled.setCursor(235, 62); oled.print("sec"); + oled.drawLine(22, 60, 232, 60, bordercolor); + //for (int i = 0; i <= 10; i++) { + // oled.drawLine(22+i*21, 59, 22+i*21, 61, bordercolor); + //} + for (int i = 0; i <= timedev; i++) { + oled.drawLine(22+i*210/timedev, 59, 22+i*210/timedev, 61, bordercolor); + } + oled.drawLine(22, 22, 22, 60, bordercolor); + //for (int i = 0; i <= 2; i++) { + // oled.drawLine(21, 22+i*19, 23, 22+i*19, bordercolor); + //} + for (int i = 0; i <= tempdev; i++) { + oled.drawLine(21, 60-i*38/tempdev, 23, 60-i*38/tempdev, bordercolor); + } + for (int i = 1; i <= 10; i++) { + int x1 = 22+(CURVES[curveNr1][i-1][1]/curvetimescale)*210; + int x2 = 22+(CURVES[curveNr1][i][1]/curvetimescale)*210; + int y1 = 60-(CURVES[curveNr1][i-1][0]/curvetempscale)*38; + int y2 = 60-(CURVES[curveNr1][i][0]/curvetempscale)*38; + oled.drawLine(x1, y1, x2 , y2, curvecolor); + } + oled.setFont(&DejaVu_Sans_Mono_14); + changeMode(oldenter1Pos, enter1Pos); + //curpos = 0; + //changePos(curpos, true);// Place the cursor + oled.display(); +} + +/***************************************************** +* Setup I/O * +*****************************************************/ + +void setupGPIO(){ + pinMode(enter, INPUT_PULLUP); + pinMode(up, INPUT_PULLUP); + pinMode(down, INPUT_PULLUP); + pinMode(right, INPUT_PULLUP); + pinMode(left, INPUT_PULLUP); + + pinMode(klixon, INPUT_PULLUP); // Declaring high temperature alert as INPUT + + pinMode(pins, OUTPUT); // Declaring lifting pins pin as OUTPUT + pinMode(vacuum, OUTPUT); // Delcaring vacuumpump pin as OUTPUT + pinMode(heat, OUTPUT); // Declaring heater pin as OUTPUT + + digitalWrite(pins, false); + digitalWrite(vacuum, false); + digitalWrite(heat, false); + + pinMode(CS, OUTPUT); // Declaring CS as OUTPUT + + // configure LED PWM functionalitites + analogWriteResolution(resolution); + analogWriteFrequency(heat, freq); + //ledcSetup(ledChannel, freq, resolution); + + // attach the channel to the GPIO to be controlled + //ledcAttachPin(heat, ledChannel); +} + +/********************************************* +* eeprom empty test * +**********************************************/ +void TestEepromEmpty(){ + short eetest = 0; + EEPROM.get(0, eetest); + if(eetest != 12345){ + EEPROM.put(0, 12345); + PutEeprom(); + //Serial.println(EEPROM.get(0, eetest)); + } +} + + + +/********************************************* +* Put recipes in eeprom * +**********************************************/ +void PutEeprom(){ + for (int i = 0; i < recipeMax0+1; i++) { + for (int j = 0; j < 2; j++) { + EEPROM.put((i*2+j)*2+10, RECIPES[i][j]); + //Serial.print((i*2+j)*2+10); Serial.print(" "); Serial.print(RECIPES[i][j]); Serial.print(" "); + } + //Serial.println(); + } + + for (int h = 0; h < curveMax1+1;h++) { + for (int i = 0; i < pointMax1+1;i++) { + for (int j = 0; j < 2; j++) { + EEPROM.put(((h*(pointMax1+1)+i)*2+j)*2+100, CURVES[h][i][j]); + //Serial.print(((h*(pointMax1+1)+i)*2+j)*2+100); Serial.print(" "); Serial.print(CURVES[h][i][j]); Serial.print(" "); + } + } + //Serial.println(); + } +} + +/*********************************************** +* Get recipes from eeprom * +************************************************/ +void GetEeprom(){ + for (int i = 0; i < recipeMax0+1; i++) { + for (int j = 0; j < 2; j++) { + EEPROM.get((i*2+j)*2+10, RECIPES[i][j]); + //Serial.print((i*2+j)*2+10); Serial.print(" "); Serial.print(RECIPES[i][j]); Serial.print(" "); + } + //Serial.println(); + } + + for (int h = 0; h < curveMax1+1;h++) { // 0 - 10 + for (int i = 0; i < pointMax1+1;i++) { // 0 - 10 + for (int j = 0; j < 2; j++) { //0 - 1 + EEPROM.get(((h*(pointMax1+1)+i)*2+j)*2+100, CURVES[h][i][j]); + //Serial.print(((h*(pointMax1+1)+i)*2+j)*2+100); Serial.print(" "); Serial.print(CURVES[h][i][j]); Serial.print(" "); + } + } + //Serial.println(); + } +} diff --git a/Hotplate_Oled_420CW_31856_20221122_eeprom/Hotplate_Oled_420CW_31856_20221122_eeprom.ino b/Hotplate_Oled_420CW_31856_20221122_eeprom/Hotplate_Oled_420CW_31856_20221122_eeprom.ino new file mode 100644 index 0000000..64f2539 --- /dev/null +++ b/Hotplate_Oled_420CW_31856_20221122_eeprom/Hotplate_Oled_420CW_31856_20221122_eeprom.ino @@ -0,0 +1,138 @@ +#include // SPI 256x64 oled display +#include "fonts/DejaVu_Sans_Mono_14.h" // Adafruit GFX font +#include "fonts/DejaVu_Sans_Mono_9.h" // Adafruit GFX font + +#include + +#include // PID controller +#include + +#include "VarInit.h" // All variables used + + +void setup() +{ + Serial.begin(115200); + + maxthermo.begin(); // Activate the MAX31856 temperature sensormodule + + maxthermo.setThermocoupleType(MAX31856_TCTYPE_K); // Choose type K thermocouple sensor + + //maxthermo.setConversionMode(MAX31856_ONESHOT_NOWAIT); + + oled.setFont(&DejaVu_Sans_Mono_14); + + myPID.SetOutputLimits(0, 4095) ; + + //turn the PID controller on + myPID.SetMode(AUTOMATIC); // Activate the temperature controller + + setupGPIO(); // Setup i/o pins + + if ( ! oled.begin(0x3D) ) { // Activate the 256x64 oled display + Serial.println("Unable to initialize OLED"); + while (1) yield(); + } + + oled.clearDisplay(); + oled.setContrast(255); // 0 = dark 255 = bright + oled.setRotation(2); // landscape mode + + layoutput(4); // Show start screen + delay(2000); + layoutput(5); // Show version screen + delay(2000); + mainScreen(); // Show main screen + + TestEepromEmpty(); + GetEeprom(); +} + + +void loop() +{ + // Check alerts + unsigned long alertnow = millis(); + if (alertnow - alerttime > alertwindow) { + alerttime = alertnow; + readKlixon(); // Check if the internal temperature is higher than 50 degrees celcius + } + + // Read the buttons + unsigned long keynow = millis(); + if (keynow - keytime > keywindow) { + keytime = keynow; + readKeys(); // Check if a key is pressed + + // if the key is a repeatable key, the repeat will go faster if you keep the key pushed longer. + if (keyIn == true && (repeatUpdownKeyblk == true || repeatRightLeftKeyblk == true || repeatEnterKeyblk == true)) { + if (first==0){ first=1; keywindow = initrepeat;} + keytottime = keytottime + keywindow; + if (keytottime > keytimecnt) { + keywindow = keywindow - 10; + if (keywindow < 0) { + keywindow = 0; + } + keytottime = 0; + } + } else { + first = 0; + keytottime = 0; + keytimecntinit = keytimecnt; + keywindow = initkeywindow; + } + } + + + // Update actual temperature + unsigned long tempnow = millis(); + if (tempnow - temptime > tempwindow && blocktemp==false) { + temptime = tempnow; + tempControl(POSX[1][2] + 1); //refresh temperature and place the value at POSX[1][2]+1 + } + + // Lifting pins on delay + if (pins_up_with_delay > 0) { + unsigned long pindelaynow = millis(); + if (pins_up_with_delay == 1) { + pindelaytime = pindelaynow; + pins_up_with_delay = 2; + } + if (pindelaynow - pindelaytime > pindelaywindow) { + pindelaytime = pindelaynow; + pins_up_with_delay = 0; + + digitalWrite(pins, true); + + } + } + + // Run process timer + if (process_start == true) { + unsigned long prctimernow = millis(); + if (prctimernow - prctimertime > prctimerwindow) { + prctimertime = prctimernow; + processTime(); + } + } + + // Run process timer Curve + if (process_startC == true) { + unsigned long prctimernowC = millis(); + if (prctimernowC - prctimertimeC > prctimerwindowC) { + prctimertimeC = prctimernowC; + processTimeC(); + } + } + + unsigned long scrsavernow = millis(); + if (start_scr_timer == true) { + if (scrsavernow - scrsavertime > scrsaverwindow) { + scrsavertime = scrsavernow; + scrsvrcnt++; + if (scrsvrcnt>=60) {oled.setContrast(30); scrsvrcnt = 0;} + } + } else { + oled.setContrast(255); scrsvrcnt = 0; + } +} diff --git a/Hotplate_Oled_420CW_31856_20221122_eeprom/VarInit.h b/Hotplate_Oled_420CW_31856_20221122_eeprom/VarInit.h new file mode 100644 index 0000000..7135559 --- /dev/null +++ b/Hotplate_Oled_420CW_31856_20221122_eeprom/VarInit.h @@ -0,0 +1,244 @@ +// name the spi inputs and outputs +#define DC 9 //17 // Display Data/Command +#define RES 8 //16 // Display Reset +#define CS 10 //5 // Display Chip Select +#define thermoCS 14 //15 // MAX31856 temperature sensor Chip Select + +// name the other inputs and the outputs +#define enter 4 //32 +#define up 6 //33 +#define down 5 //25 +#define right 3 //26 +#define left 7 //27 +#define klixon 15 //2 // over temperature alart +#define pins 21 //14 // 1 = pins up = green led +#define vacuum 22 //13 // 1 = vacuum on = yellow led +#define heat 23 //12 // 1 = heater on = red led + +#define bordercolor 5 // border grey value +#define curvecolor 8 // curve grey value + +#define pressed 0 // button pressed +#define released 1 // button released + +// both hardware SPI +Adafruit_MAX31856 maxthermo = Adafruit_MAX31856(14); +Adafruit_SSD1322 oled(256, 64, &SPI, DC, RES, CS, 32000000); // name de display struct + +// setting PWM properties +const int freq = 500; // PWM frequenvy for heater output +//const int ledChannel = 0; // +const int resolution = 12; // Output resolution 0-4095 + +bool blocktemp = false; + +// contains the position of the button true = released false = pressed +bool enterKey = true; +bool upKey = true; +bool downKey = true; +bool rightKey = true; +bool leftKey = true; + +// latch for single push or repeat button +bool enterKeyblk = false; +bool upKeyblk = false; +bool downKeyblk = false; +bool rightKeyblk = false; +bool leftKeyblk = false; + +bool keyIn = false; // false if no button is pressed true if any button is pressed + +bool repeatUpdownKeyblk = false; // true = single push false = repeat +bool repeatRightLeftKeyblk = false; // true = single push false = repeat +bool repeatEnterKeyblk = false; // true = single push false = repeat + +bool first = 0; + +const char LAYOUT[6][4][29] = + { + {" C s ", + " Single temperature/time ", + " Curve temperature/time ", + " "}, + {" C s ", + " Recipe Setpoint Time ", + " C s ", + " "}, + {" C s ", + " Curve Point Value Time ", + " C s ", + " "}, + {" C C s ", + " ", + " ", + " "}, + {" Development & design ", + " ", + " Herman Adema ", + " "}, + {" ", + " A009082023 ", + " TEENSY 4.0 ", + " "} + }; + +const char STATUSLINE[18][29] = + {" PROCESS STOPPED ", + " ", + " ", + " PROCESS STANDBY ", + "WARNING:INTERNAL TEMP > 50 C", + " ", + " TC OPEN CIRCUIT ", + "TC OVERVOLTAGE/UNDERVOLTAGE ", + " COLD JUNCTION OUT OF RANGE ", + " TC OUT OF RANGE ", + " Cold Junction Range Fault ", + " Thermocouple Range Fault ", + " Cold Junction High Fault ", + " Cold Junction Low Fault ", + " Thermocouple High Fault ", + " Thermocouple Low Fault ", + " Over/Under Voltage Fault ", + " Thermocouple Open Fault "}; + +const char MODE[4][9] = {" Stop "," Heat "," Run "," St-by "}; + + +const byte POSX[4][5] = { + {2, 1, 1, 0, 0}, // screen 0 // single // curve + {3, 3, 11, 22, 0}, // screen 1 // number // recipe // temp // time + {4, 2, 9, 15, 22}, // screen 2 // number // point // temp // time + {3, 3, 11, 21, 0} // screen 3 // number and cursor positions screen 2 + }; +const byte POSY[4][5] = { + {2, 31, 47, 0, 0}, // screen 0 // single // curve + {3, 47, 47, 47, 0}, // screen 1 // number // recipe // temp // time + {4, 47, 47, 47,47}, // screen 2 // number // point // temp // time + {3, 3, 11, 21, 0} // screen 3 // number and cursor positions screen 2 + }; + +int font_with = 9; // Used for calculation of position on display + +int curpos = 0; // cursor position + +// scrNr = 1 main screen +int recipeNr0 = 0; // hotplate recipe number +int oldrecipeNr0 = 0; // previous hotplate recipe number +int timeValue0 = 0; // hotplate recipe process time value +int oldtimeValue0 = 0; // previous hotplate recipe process time value +float tempValue0 = 0; // hotplate recipe temperature value +float oldtempValue0 = 0; // previous hotplate recipe temperature value +const int recipeMax0 = 10; // maximum number of recipes +const int timeMax0 = 999; // maximum process time +const float tempMax0 = 350; // maximum hotplate temperature + +// scrNr = 2 curve screen +int curveNr1 = 0; // hotplate curve number +int oldcurveNr1 = 0; // previous hotplate curve number +int pointNr1 = 0; // curve point number +int oldpointNr1 = 0; // previous curve point number +int timeValue1 = 0; // hotplate curve process time value +int pointcnt = 1; // current point number +int oldtimeValue1 = 0; // previous hotplate curve process time value +float tempValue1 = 0; // hotplate curve temperature value +float oldtempValue1 = 0; // previous hotplate curve temperature value +const int curveMax1 = 10; // maximum number of curves +const int pointMax1 = 10; // maximum number of points +const int timeMax1 = 999; // maximum process time +const float tempMax1 = 350; // maximum hotplate temperature + +int timeCounter0 = 0; // hotplate timer value +int oldtimeCounter0 = 0; // previous hotplate timer value +bool process_start = false; // start the process timer + +int timeCounter1 = 0; // hotplate timer value +int oldtimeCounter1 = 0; // previous hotplate timer value +bool process_startC = false; // start the process timer Curve + +uint8_t fault; +double tempMeas = 0; // actual hotplate temperature +double oldtempMeas = 0; // previous hotplate temperature +int bacTemp[256]; // temperature curve backup +int bacPoints[256]; // curve points backup +int lastx = 0; // last temperature position on curve screen + +// enter button modes +int enter1Pos = 0; // actual enter button position +int oldenter1Pos = 0; // previous enter button position +int enterMax = 3; // maximum number of enter button positions + +double Input = 0; // PID input +double oldSetpoint = 0; +double Setpoint = 0; // PID setpoint +double Output = 0; // PID output + +// initialize the PID controller +double Kp=400, Ki=0.1, Kd=0.01; //50,2,0.01 +//PID myPID(&Input, &Output, &Setpoint, P_ON_M, Kp, Ki, Kd, DIRECT); +PID myPID(&Input, &Output, &Setpoint, Kp, Ki, Kd, DIRECT); + +bool setAlert = false; // set/reset alert +byte pins_up_with_delay = 0; // pins on delaytime --- does not hold the programm + +int statusMsgOld = 5; // previous status message +int statusMsg = enter1Pos; // actual status message + +// recipes temperature,processtime +short RECIPES[recipeMax0+1][2] = + { + {85,60},{80,60},{80,90},{85,60},{90,60},{95,60},{100,90},{120,60},{120,600},{180,90},{100,90} + }; + +short CURVES[curveMax1+1][pointMax1+1][2] = + { + {{90,0},{100,30},{110,60},{120,90},{150,120},{150,150},{170,180},{190,210},{200,240},{200,270},{200,300}}, + {{10,0},{80,60},{80,90},{85,60},{90,60},{95,60},{100,90},{120,60},{120,600},{180,90},{100,90}}, + {{20,0},{80,60},{80,90},{85,60},{90,60},{95,60},{100,90},{120,60},{120,600},{180,90},{100,90}}, + {{0,0},{80,60},{80,90},{85,60},{90,60},{95,60},{100,90},{120,60},{120,600},{180,90},{100,90}}, + {{0,0},{80,60},{80,90},{85,60},{90,60},{95,60},{100,90},{120,60},{120,600},{180,90},{100,90}}, + {{0,0},{80,60},{80,90},{85,60},{90,60},{95,60},{100,90},{120,60},{120,600},{180,90},{100,90}}, + {{0,0},{80,60},{80,90},{85,60},{90,60},{95,60},{100,90},{120,60},{120,600},{180,90},{100,90}}, + {{0,0},{80,60},{80,90},{85,60},{90,60},{95,60},{100,90},{120,60},{120,600},{180,90},{100,90}}, + {{0,0},{80,60},{80,90},{85,60},{90,60},{95,60},{100,90},{120,60},{120,600},{180,90},{100,90}}, + {{0,0},{80,60},{80,90},{85,60},{90,60},{95,60},{100,90},{120,60},{120,600},{180,90},{100,90}}, + {{0,0},{80,60},{80,90},{85,60},{90,60},{95,60},{100,90},{120,60},{120,600},{180,90},{100,90}}, + }; + +float curvetimescale = 0; // max times curve +float curvetempscale = 0; // max temp curve +int scrNr = 1; // first screen from LAYOUT[][][] + + +int trendline[4][256]; // temperature trendlines +int recipesteps[10][30]; // programmable trend follow steps + +bool start_scr_timer = false; +int scrsvrcnt = 0; + + +unsigned long keytime = 0; +unsigned long initrepeat = 200; +unsigned long keywindow = 50; // time in ms // interval for reading keyboard +unsigned long initkeywindow = keywindow; // time in ms // interval for reading keyboard used to reset timer +unsigned long keytimecnt = 300; +unsigned long keytimecntinit = keytimecnt; +unsigned long keytottime = 0; + +unsigned long temptime = 0; +unsigned long tempwindow = 100; // time in ms // interval for temperature measurement and controlling + +unsigned long alerttime = 0; +unsigned long alertwindow = 1000; // time in ms // interval for checking alert + +unsigned long pindelaytime = millis(); +unsigned long pindelaywindow = 2000; // time in ms // on delay for lifting pins + +unsigned long prctimertime = 0; +unsigned long prctimerwindow = 1000; // time in ms // interval for process timer + +unsigned long prctimertimeC = 0; +unsigned long prctimerwindowC = 1000; // time in ms // interval for process timer + +unsigned long scrsavertime = 0; +unsigned long scrsaverwindow = 60000; // time in ms // interval for screensavercounter