Combine Display+Controls with Pizza oven

Hello Guys,

im not sure if what im asking is possible but please bear with me.
My Project is basically to modify a Pizza Oven I bought (google "G3 Ferrari".

I want to add the following features:

  1. More accurate Temperature Settings (with no limits more or less)
  2. The Stone should be able to turn if I want to
  3. I want a Display to show the current Status
  4. I want a Keypad/something similar to control the oven

Now steps 1 and 2 are very easy (well, atleast the programming). I control the Temperature by connecting the 2 Heat shields to a Relay and by adding two Temperature Sensors (one in the Top and one in the bottom). Now I measure the Temperature and if its not in the range of my wished Temperature the Relay opens/closes.

The Motor is just a simple motor connected to a controller which is basically a switch (on/off, bool).

Now that you are suitably informed about my Project, lets talk about my Problem.

As a Display/Keypad I got the "1602 LCD Keypad Shield" (like Using 1602 LCD Keypad Shield w/ Arduino [w/ Examples] - Arduino Project Hub)

Now I dont want to use the labelled buttons like they are displayed, but rather to directly control the oven. Basically:

  1. If there were no User Inputs for X Seconds show the current Temperatures (I have no idea how to write this since there is no "wait for", timer or similar function)
  2. The "Select" Button should switch between "Standard" Mode (where you only select one temperature (which is for both top and bottom relay/etc)
  3. The "Left" Button should then switch if you want to change the steps between temp selection (not implemented yet but easy), change the upper temp, lower temp, or "Standard Temp".
  4. Up and Down then let you change the values selected from 3.
  5. "Right" Button will always either turn the Motor on or Off (easy)

Now I dont know how to combine the functions of the Keypad and the other "regular functions" (like controlling the relay). Because the Keypad functions rely on waiting until the user actually does something and the relay/Temp sensor has to be continuosly controlled.

Currently this is my Code:

#include <SPI.h>
#include "Adafruit_MAX31855.h"

// digital IO pins.
#define Relais1 0
#define Relais2 1
#define DO   2
#define Motorpin 3
#define CS1  12
#define CS2  13
#define CLK  11
int Array1[10];
int Array2[10];
int I=0;
float Avgc1;
float Avgc2;
bool feineinstellungen;
int Temperatur;
int SollTempOben;
int SollTempUnten;
int TempToleranzUnten;
int TempToleranzOben;
bool Motor;
int TempSel;


#include <LiquidCrystal.h>
// select the pins used on the LCD panel
LiquidCrystal lcd(8, 9, 4, 5, 6, 7);

// define some values used by the panel and buttons
int lcd_key     = 0;
int adc_key_in  = 0;
#define btnRIGHT  0
#define btnUP     1
#define btnDOWN   2
#define btnLEFT   3
#define btnSELECT 4
#define btnNONE   5

// read the buttons
int read_LCD_buttons()
{
 adc_key_in = analogRead(0);      // read the value from the sensor
 // my buttons when read are centered at these valies: 0, 144, 329, 504, 741
 // we add approx 50 to those values and check to see if we are close
 if (adc_key_in > 1000) return btnNONE; // We make this the 1st option for speed reasons since it will be the most likely result
 // For V1.1 us this threshold
 if (adc_key_in < 50)   return btnRIGHT;
 if (adc_key_in < 250)  return btnUP;
 if (adc_key_in < 450)  return btnDOWN;
 if (adc_key_in < 650)  return btnLEFT;
 if (adc_key_in < 850)  return btnSELECT;




 return btnNONE;  // when all others fail, return this...
}


// initialize the Thermocouple
Adafruit_MAX31855 thermocouple1(CLK, CS1, DO);
Adafruit_MAX31855 thermocouple2(CLK, CS2, DO);

void setup() {

//LCD INI
{
 lcd.begin(16, 2);              // start the library
 lcd.clear();
 lcd.print("Pizzamaster 3000 Startup"); // print a simple message
}

delay(5000);
  
  //Temperatursensoren
  Serial.begin(9600);

  while (!Serial) delay(1); // wait for Serial on Leonardo/Zero, etc
  lcd.setCursor(0,0);
  lcd.print("MAX31855 1 test");
  // wait for MAX chip to stabilize
  delay(500);
  lcd.setCursor(0,0);
  lcd.print("Initializing sensor 1...");
  if (!thermocouple1.begin()) {
  lcd.setCursor(0,0);
    lcd.println("ERROR.1");
    while (1) delay(10);
  }
  lcd.setCursor(0,0);
  lcd.print("DONE SENSOR 1");

  lcd.setCursor(0,1);
  lcd.print("MAX31855 2 test");
  // wait for MAX chip to stabilize
  delay(500);
  lcd.setCursor(0,1);
  lcd.print("Initializing sensor 2...");
    if (!thermocouple2.begin()) {
  lcd.setCursor(0,1);
    lcd.print("ERROR.2");
    while (1) delay(10);
  }
  lcd.setCursor(0,1);
  lcd.print("DONE SENSOR 2");
TempSel=1;


//Relaissteuerung
pinMode(Relais1, OUTPUT);
pinMode(Relais2, OUTPUT);
if (feineinstellungen==false) {
TempToleranzUnten=5;
TempToleranzOben=3;
}
 lcd.clear();
lcd.print("Pizzamaster 3000 READY");

}
void loop() {

//Display
 lcd_key = read_LCD_buttons();  // read the buttons

 switch (lcd_key)               // depending on which button was pushed, we perform an action
 {
   case btnRIGHT:
     {
     if (Motor==false) {
lcd.clear();
lcd.print("Motor an");
digitalWrite(Motorpin, HIGH);
Motor=true;
     }
      if (Motor==true){
lcd.clear();
lcd.print("Motor aus");
digitalWrite(Motorpin, LOW);
Motor=false;
      }
     break;
     }
   case btnLEFT:
     {
     TempSel=TempSel+1;
     if (TempSel==4) {
      TempSel=1;
     }
     switch (TempSel){
     case 1:
     {
       lcd.clear();
     lcd.print("Temperatur");
     }
     case 2:
     {
       lcd.clear();
     lcd.print("Temperatur");     
     lcd.setCursor(1,1);
     lcd.print("Oben");
     }
     case 3:
     {
     lcd.clear();
     lcd.print("Temperatur");
     lcd.setCursor(1,1);
     lcd.print("Unten");
     }
     break;
     }
     }
   case btnUP:
     {
     switch (TempSel){
     case 1:
     {
     Temperatur=Temperatur+5;
      lcd.clear();
     lcd.print(Temperatur);
     }
     case 2:
     {
     SollTempOben=SollTempOben+5;
      lcd.clear();
     lcd.print(SollTempOben);     
     }
     case 3:
     {
     SollTempUnten=SollTempUnten+5;
      lcd.clear();
     lcd.print(SollTempUnten);     
     }
     break;
     }
     }
   case btnDOWN:
     {
     switch (TempSel){
     case 1:
     {
     Temperatur=Temperatur-5;
      lcd.clear();
     lcd.print(Temperatur);
     }
     case 2:
     {
     SollTempOben=SollTempOben-5;
      lcd.clear();
     lcd.print(SollTempOben);     
     }
     case 3:
     {
     SollTempUnten=SollTempUnten-5;
      lcd.clear();
     lcd.print(SollTempUnten);     
     }
     break;
     }
     }
   case btnSELECT:
     {
     if (feineinstellungen==false) {
       lcd.clear();
     lcd.print("Feineinstellungen AN");
     feineinstellungen=true;
     }
     else{
       lcd.clear();
     lcd.print("Feineinstellungen AUS");
     feineinstellungen=false;
     }
     break;
     }
 }

  //Temperatursensor
   while(I!=9) {
   double c1 = thermocouple1.readCelsius();
   double c2 = thermocouple2.readCelsius();
   if (isnan(c1)) {
     Serial.println("Something wrong with thermocouple 1!");
   } else {
   if (isnan(c2)) {
     Serial.println("Something wrong with thermocouple 2!");
   }
   delay(100);
   }
   Array1[I]=c1;
   Array2[I]=c2;
   I=I+1;
   }
   I=0;
   Avgc1=(Array1[0]+Array1[1]+Array1[2]+Array1[3]+Array1[4]+Array1[5]+Array1[6]+Array1[7]+Array1[8]+Array1[9])/10;
   Avgc2=(Array2[0]+Array2[1]+Array2[2]+Array2[3]+Array2[4]+Array2[5]+Array2[6]+Array2[7]+Array2[8]+Array2[9])/10;
   //Avgc1 is the average of the last 10 readings for Sensor 1
   //Avgc2 is the average of the last 10 readings for Sensor 2

//Relaissteuerung
if (feineinstellungen==false) {
if (Avgc1<(Temperatur-TempToleranzUnten)) {
  digitalWrite(Relais1, HIGH);
}
if (Avgc1>(Temperatur+TempToleranzOben)) {
  digitalWrite(Relais1, LOW);
}
if (Avgc2<(Temperatur-TempToleranzUnten)) {
  digitalWrite(Relais2, HIGH);
}
if (Avgc2>(Temperatur+TempToleranzOben)) {
  digitalWrite(Relais2, LOW);
}
}
else {
if (Avgc1<(SollTempUnten-TempToleranzUnten)) {
  digitalWrite(Relais1, HIGH);
}
if (Avgc1>(SollTempOben+TempToleranzOben)) {
  digitalWrite(Relais1, LOW);
}
if (Avgc2<(SollTempUnten-TempToleranzUnten)) {
  digitalWrite(Relais2, HIGH);
}
if (Avgc2>(SollTempOben+TempToleranzOben)) {
  digitalWrite(Relais2, LOW);
}
}

}

Right now the structure can be described like this:

  1. Complete Setup etc (I think the order of the Steps doesnt really matter here)
  2. Loop:
    2.1 The Keypad + Display Integration with multiple Switch Cases to react according to the user Inputs
    2.2 The Temperature Sensor readings being saved into an Array (to get an averaged reading)
    2.3 The Relay either opening or closing

My actual Issue is writing Code so that the Display reacts to my Keypad Inputs, while simultaneausly controlling the Relay/Temp Sensors.
The Display works for the Setup Phase, but basically breaks when it enters the Loop section.

If you are looking for help creating a massive convoluted do-all in one logic mess, count me out. The correct way is to create the display function that looks at the variables to be shown perhaps every second and have that function only deal with the display.
Then have a function that ONLY deals with your keypad input and nothing else, no display, no temp, no nothing else. Get that to work so the variables will have the values for your display function to show.
Same with the temperature measuring function. Same with the power control function.
Tie them all together with the loop() function and you have a program is is 99% tested already.
Paul

1 Like

The processor should never wait for anything. Check the keypad 20 times a second. You won't miss any input and you can do lots of other things between checks. See the Several things at a time tutorial.

1 Like

Use more loops

for (I = 0; I < 10; I++) {

  double c1 = thermocouple1.readCelsius();
  double c2 = thermocouple2.readCelsius();

  if (isnan(c1)) {
    Serial.println("Something wrong with thermocouple 1!");
  } else {
    if (isnan(c2)) {
      Serial.println("Something wrong with thermocouple 2!");
    }
    delay(100);
  }
  Array1[I] = c1;
  Array2[I] = c2;
}

Avgc1 = 0;
Avgc2 = 0;

for (I = 0; I < 10; I++) {

  Avgc1 += Array1[I];
  Avgc2 += Array2[I];
}

Avgc1 /= 10.0;
Avgc2 /= 10o.;

Use less storage

Avgc1 = 0;
Avgc2 = 0;

for (I = 0; I < 10; I++) {

  double c1 = thermocouple1.readCelsius();
  double c2 = thermocouple2.readCelsius();

  if (isnan(c1)) {
    Serial.println("Something wrong with thermocouple 1!");
  } else {
    if (isnan(c2)) {
      Serial.println("Something wrong with thermocouple 2!");
    }
    delay(100);
  }
  
  Avgc1 +=  c1;
  Avgc2 +=  c2;
}

Avgc1 /= 10.0;
Avgc2 /= 10.0;

Read more code.

Use functions.

This temperature thing I'm compelled to tinker with while I wait for cocktail hour to officially begin could be a function. Use of functions to subordinate code that works reliably makes the main line code easier to read.

So the main line, loop() here in Arduino-land, will read more like an outline of your story than a run-on paragraph.

HTH

a7

1 Like