How to use statements to do different things depending on what is the temperature sensor readings

Hello world!!

Newbie here, I am trying to have different things happen depending on what is the reading of a temperature sensor. If the temperature is above a set point (ex: 0 deg C), it starts a heater controlled with pin 2, once the temperature reaches a second set point (ex: 30 deg C), it turns a pin 8 high and if the temperature reaches a third setpoint (ex: 60 deg C), it turns off the heater (pin 2 Low). If the temperature falls below the third setpoint (ex: 60 deg C), then the heater turns back on and so on, so the temperature is maintained at 60 deg C (similar to a PID controller). Pin 8 should remain HIGH after it has been triggered regardless of what the heater is doing.

I currently have the code below, but I know this is not going to work as is, maybe using "Switch statements would be better.

Any help on this would be greatly appreciated, I'm a newbie at this...

void loop() {
myNex.NextionListen();  // This function must be called repeatedly to response touch events
                          // Wait for Nextion to be booted.



int digitalValue = digitalRead(45);  // OK pin

if (((digitalValue == HIGH) && (digitalRead(47) == HIGH) && (thermocouple->readCelsius() > 0))) {
  digitalWrite(2, HIGH);  // Pin 2 turn ON Heater
  myNex.writeNum("bt8.val", 1);
  myNex.writeNum("bt28.val", 1);
  Serial.println("Starting PID Heater");
  }
  if (((digitalValue == HIGH) && (digitalRead(47) == HIGH) && (thermocouple->readCelsius())) > 30) {
    digitalWrite(8, HIGH);
    Serial.println("Starting something");
    }
    if (((digitalValue == HIGH) && (digitalRead(47) == HIGH) && (thermocouple->readCelsius())) > 60) {
      digitalWrite(2, LOW);
      Serial.println("Heater PID OFF");
}
...                        

Due to the reality of heaters and heating systems, thermostats have one low set point and a separated high set point. If the temperature is below the low point, the heat turns on. When the temperature gets above the high point the heat turns off.

Heat has inertia, there is mass involved. If the difference between set points is too close, the heater on/offs to high inefficiency and in many home cases, self-destruction of the starter, click-clickety-click.

That won't work. C/C++ is case-sensitive, so the keyword is "void", all lower case.

Hint: when the keyword "void" precedes a function name, it indicates that the function does not return a value.

Just a typo on my post..

void loop() {

If I run the above code, the serial monitor will continuously print: Starting PID Heater.
If I heat-up the temperature sensor with a heatgun above the other setpoints, nothing happens and the serial monitor keep printing Starting PID Heater. So it is not working.

I am not to worried about the heater not maintaining the 3rd setpoint precisely, I can install a PID library for this, the problem is that the second and third if statement are not getting activated event if the temperature rises above the setpoints...

Always post all the code, using the "copy for forum" button in the IDE, and insert using code tags.

Then you avoid making such typos.

My project use a Nextion display and I see the temperature on the display in real time.
The sketch has now over 650 lines, so not posting on here. No errors when compiling also.

I'm having problems with the execution of the code above only for now, it is not doing what's needed...

The second and third if statements are ignored...

The typo was on this post only, not on the actual sketch...

Interesting, I moved the temperature section at the beginning of the if statement and added a 100 millisecond delay, and now its working...

Changed

if (((digitalValue == HIGH) && (digitalRead(47) == HIGH) && (thermocouple->readCelsius())) > 30) {

TO

if (((thermocouple->readCelsius() > 30) && (digitalValue == HIGH) && (digitalRead(47) == HIGH))) {

Ho well.
Solved myself I guess.

So final sketch that worked maintaining temperature at setpoint is:

  int digitalValue = digitalRead(45);  // OK pin

if (((thermocouple->readCelsius() > 0) && (digitalValue == HIGH) && (digitalRead(47) == HIGH))) {
  digitalWrite(2, HIGH);  // Pin 2 turn ON Heater
  myNex.writeNum("bt8.val", 1);
  myNex.writeNum("bt28.val", 1);
  Serial.println("Starting PID Heater");
  }
  if (((thermocouple->readCelsius() > 30) && (digitalValue == HIGH) && (digitalRead(47) == HIGH))) {
    digitalWrite(8, HIGH);
    Serial.println("Starting Something");
    }
    if (((thermocouple->readCelsius() > 60) && (digitalValue == HIGH) && (digitalRead(47) == HIGH))) {
      digitalWrite(2, LOW);
      Serial.println("Heater PID OFF");
      }
      if (((thermocouple->readCelsius() <= 60) && (digitalValue == HIGH) && (digitalRead(47) == HIGH))) {
        digitalWrite(2, HIGH);
        Serial.println("Starting PID Heater");
        }   
                      

Cheers

And your rules say turn the heater off when?

This whole 3 points thing seems a bit of a sack race.

On the third if statement, I have

if (((thermocouple->readCelsius() > 60) && (digitalValue == HIGH) && (digitalRead(47) == HIGH))) {
      digitalWrite(2, LOW);
      Serial.println("Heater PID OFF");

This whole 3 points thing seems a bit of a sack race.

Man, you have no idea how much of a Newbie I am in all this Arduino programming...
But hey, my sketch is working so far and I am learning it bits by bits...
I am electronic type of guy but definitely not a coder, getting to old for this stuff.

Cheers

I'm a coder who started coding because what I knew about shop would take a coder years to learn.

Having 2 set points makes 3 regions; low, middle and high.

If low, turn heater on (unless it's already on, if (low && heater off) then turn heater on.
If middle, do nothing. The heater can be off or on.
if high, turn heater off (unless already off.
And that's it for thermostats but it's also how digital pins work.

How close the set points are makes how often the heat turns on and off. With house heat involving all to get room air warm you don't want to play it fine as too frequent cycling wrecks most heaters.

With a small container and electronic heater you can play it close and perhaps move the set points to fine tune in action what you get.

Now do the same for your 3 point that I don't pretend to get!

Is almost 70 old? Then I'm old.

Not sure what you mean with this quote 'knew about shop would take a coder years to learn'...
I have a visual memory and can design or invent stuff easily because I can visualize in my head.
(I have a 3D printer and can design stuff very fast...)

Did a few small projects with Arduino with help in contents in Arduino Libraries or asking online for help when I'm stuck.

Koodos to you if you are coding at your age, I wish I had that ability.

There are 4 "if" in this block, 3 are to bring and maintain a liquid to a set temperature (ex. 60 deg C). The other one is to bring another pin HIGH to start a process when the temperature reach a setpoint (ex. 30 deg C).

Now, the set temperature and mid process temperature values can be changed via the Nextion display that store the values in variables.

This is working so far, but I need help storing those variable values (and other ones) on the EEPROM. My Arduino is the Mega 2560.

I have no idea on how to store values on EEPROM...

I now have these variables that need their values stored on the EEPROM:
unsigned long interval;
unsigned long tempToStart;
unsigned long potPosition;
unsigned long PIDTemp;

They get their values via the Nextion Display with these:

interval = myNex.readNumber("n61.val");     // Store to interval the value of numeric box n61
tempToStart = myNex.readNumber("n62.val");  // Store to tempToStart the value of numeric box n62
PIDTemp = myNex.readNumber("n3.val");   // Store to PIDTemp the value of text box n3

The "potPosition" variable is a 10K digital potentiometer and I use #include "X9C10X.h" library to control it via the Nextion Display.

All the buttons on the Nextion display used triggers ex.:

void trigger1() {
    /* Create a button on Nextion
   * Write in the Touch Release Event of the button
   * this command:    printh 23 02 54 01
   * Every time the button is pressed, the trigger1() function will run
   * and the code inside will be executed once
   */

I can get the value for the position of the digital pot when I click a button:

void trigger19() {
    /* Create a button on Nextion
   * Write in the Touch Release Event of the button
   * this command:    printh 23 02 54 13
   * Every time the button is pressed, the trigger19() function will run
   * and the code inside will be executed once
   */
  Serial.println("SET button pressed");
  pot.getPosition();
  //Serial.println (pot.getPosition());

}

But how do I store those values on the EEPROM?
#include <EEPROM.h> is installed...

Thank you for any help that you can provide.

Cheers
Dan

The code for this block using those variable is now:

int OK = digitalRead(45);  // OK pin

if ((OK == HIGH) && (digitalRead(47) == LOW)) {
  digitalWrite(8, HIGH);  // Pin 8 turn ON something
  Serial.println("Starting something");
  }
  if (((thermocouple->readCelsius() > 0 < PIDTemp) && (OK == HIGH) && (digitalRead(47) == HIGH))) {
    digitalWrite(2, HIGH);  // Pin 2 turn ON Heater
    myNex.writeNum("bt8.val", 1);
    myNex.writeNum("bt28.val", 1);
    Serial.println("Starting PID Heater");
    }
    if (((thermocouple->readCelsius() > tempToStart) && (OK == HIGH) && (digitalRead(47) == HIGH))) {
      digitalWrite(8, HIGH);
      Serial.println("Starting something");
      }
      if (((thermocouple->readCelsius() >= PIDTemp-3) && (OK == HIGH) && (digitalRead(47) == HIGH))) {
        digitalWrite(2, LOW);
        myNex.writeNum("bt8.val", 0);
        myNex.writeNum("bt28.val", 0);
        Serial.println("Heater PID OFF");
        }
        if (((thermocouple->readCelsius() < PIDTemp -1) && (OK == HIGH) && (digitalRead(47) == HIGH))) {
          digitalWrite(2, HIGH);
          Serial.println("Starting PID Heater");
          myNex.writeNum("bt8.val", 1);
          myNex.writeNum("bt28.val", 1);
          Serial.println("Starting PID Heater");
          }   

if that help...

In your IDE under File->Examples->EEPROM is an Uno example.
If need be, ask the forum for differences to the Mega... should be few.

I would use a state machine to handle the first part as a mode or stage that once finished switches to a thermostat mode that lets you do the button while maintaining an acceptable temperature range.

By shop I mean precision metal fabrication shop and what I learned making things in middle school shop class and tech school design shop. We got small computers in 1980 and that's when I learned Basic, in my mid 20's. After 20 years I got a head full of clots that only wiped out about half of what I knew... Arduino has been about recovery for me, a bit nostalgic to code an 8-bit device!

... will have to research this...
With my current code, I noticed that the heater pin will switch ON and OFF very fast when it has reached or past the set temperature, probably caused by the loop effectuating all the sketch in very fast repetition (almost 700 lines of codes including comments). Not sure if the SSR can handle rapid ON/OFF signals like this, will investigate...

Just look at EEPROM examples on IDE.

Seems simple enough;

#include <EEPROM.h>

/** the current address in the EEPROM (i.e. which byte we're going to write to next) **/
int address = 0;

void setup() {
  /** Empty setup **/
}

void loop() {
  /***
    need to divide by 4 because analog inputs range from
    0 to 1023 and each byte of the EEPROM can only hold a
    value from 0 to 255.
  ***/
  int val = analogRead(0) / 4;

  /***
    Update the particular EEPROM cell.
    these values will remain there when the board is
    turned off.
  ***/
  EEPROM.update(address, val);

I have at least 4 variables to store in EEPROM.

#include <EEPROM.h>

/** the current address in the EEPROM (i.e. which byte we're going to write to next) **/
int address1 = 1;
int address2 = 2;
int address3 = 3;
int address4 = 4;

void setup() {
  /** Empty setup **/
}

void loop() {
  /***
    need to divide by 4 because analog inputs range from
    0 to 1023 and each byte of the EEPROM can only hold a
    value from 0 to 255.
  ***/
  int val1 = interval / 400;  // value is more than 255, approx 600000
  int val2 = tempToStar; // value is less than 255
  int val3 = potPosition; // value is between 0 and 99
  int val4 = PIDTemp;   // value is less than 255

  /***
    Update the particular EEPROM cell.
    these values will remain there when the board is
    turned off.
  ***/
  EEPROM.update(address1, val1);
  EEPROM.update(address2, val2);
  EEPROM.update(address3, val3);
  EEPROM.update(address4, val4);

Does this look right?

If yes, than I can tackle the EEPROM .read to get the values stored...

Because the EEPROM only has a limited number of write cycles, (and is slow) you might only want to update the EEPROM when a human presses a "set" button.

https://docs.arduino.cc/learn/built-in-libraries/eeprom/ :

Note: An EEPROM write takes 3.3 ms to complete. The EEPROM memory has a specified life of 100,000 write/erase cycles, so you may need to be careful about how often you write to it.

Yes, this is exactly how my code are working, those variables are updated only when I click on a set button next to the number fields on the Nextion Display. Also I think that using EEPROM.update is better than using EEPROM.write as it only write if the value has changed...

Does the code above looks OK?