Heater Controller not displaying the actual temperature

Hi

I am using an UNO with I2C LCD and SPI thermocouple module based on MAX6675 to make a temperature controller for an AC heater.

The other hardware arrangement includes one opto-coupler to detect zero-crossing and other for driving a triac. Both of them are working fine.

The problem is that the real temperature of the heater is not being updated on the LCD. The MAX6675 is working fine because when I reset the UNO, the temperature gets updated.

Here is my piece of code:

#include <SPI.h>
#include <Wire.h>
#include <max6675.h>
#include <LiquidCrystal_I2C.h>

LiquidCrystal_I2C lcd(0x27, 20, 4); 

#define thermoSO 11
#define thermoCS 12
#define thermoCLK 13

#define potentiometer A3
#define zerocrossing 8
#define firePin 7     // firing pin

int realTemperature = 0;
int potTemperature = 0;
int wavesCounter = 0;

bool zeroCrossDetected = false;

MAX6675 thermocouple(thermoCLK, thermoCS, thermoSO);

void setup() 
{
  Serial.begin(9600);
  
  lcd.init();       
  lcd.backlight();  
  lcd.clear();
  
  pinMode(potentiometer, INPUT);
  pinMode(zerocrossing, INPUT_PULLUP);
  pinMode(firePin, OUTPUT);
  
  PCICR |= (1 << PCIE0);    //enable PCMSK0 scan                                                 
  PCMSK0 |= (1 << PCINT0);  //Set pin D8 (zero cross input) trigger an interrupt on state change.
      
}

void loop()
{
  readTemperatures();
  updateDisplay();
  /*Serial.println(" Set: ");
  Serial.print(potTemperature);
  Serial.print("°C - Now: "); 
  Serial.print(realTemperature);
  Serial.println("°C"); */
      
  if (zeroCrossDetected)     
  {
    wavesCounter++;
    readTemperatures();
    
    if (wavesCounter < 50) // Increase or Decrease temperature during 50 half-waves
    {
      if (realTemperature > potTemperature)
      {
        digitalWrite(firePin, LOW);
      }
      else
      {
        digitalWrite(firePin, HIGH);
      }
    }

    if (wavesCounter == 50) // Read/Display Temperatures after 50 half-waves
    {
      digitalWrite(firePin, LOW);
      readTemperatures();
      /*Serial.print(" Set: ");
      Serial.print(potTemperature);
      Serial.print("°C - Now: "); 
      Serial.print(realTemperature);
      Serial.print("°C");*/ 
      updateDisplay();
      wavesCounter = 0;
    }

    zeroCrossDetected = false;
  }
}

void readTemperatures()
{
  realTemperature = thermocouple.readCelsius();
  potTemperature = analogRead(potentiometer);
  potTemperature = map(potTemperature, 0, 1023, 0, 300);
}

void updateDisplay()
{
  lcd.setCursor(0, 0);
  lcd.print("Set: ");
  lcd.print(potTemperature);
  lcd.print((char)223);
  lcd.print("C  ");
  lcd.setCursor(0, 1);
  lcd.print("Now: ");
  lcd.print(int(realTemperature));
  lcd.print((char)223);
  lcd.print("C   ");
}

// Pin 8 (Zero Cross detection) Interrupt routine

ISR(PCINT0_vect)
{
  if(PINB & B00000001)            
  {
    zeroCrossDetected = true; 
  }
}

If you open the Arduino IDE's Serial Monitor while your program is running, do you see the expected output?

abuhafss:

bool zeroCrossDetected = false;

Since this is updated in the ISR, you should make it volatile:
https://www.arduino.cc/reference/en/language/variables/variable-scope--qualifiers/volatile/
I don't see that this would be the cause of the problem you're having though, because you are calling updateTemperature() and updateDisplay() regardless of the value of zeroCrossDetected.

pert:
If you open the Arduino IDE's Serial Monitor while your program is running, do you see the expected output?

No, same output in the serial monitor.

It is very strange, even when I switch off the 220V AC mains (no zero crossing) there is no update in the temperature display though there are only 2 code lines functional in the void loop.

readTemperatures();
updateDisplay();

Please post a link (using the chain links icon on the forum toolbar to make it clickable) to where you downloaded the max6675 library from. Or if you installed it using Library Manger (Sketch > Include Library > Manage Libraries in the Arduino IDE or Libraries > Library Manager in the Arduino Web Editor) then say so and state the full name of the library.

What happens if you run a minimal sketch that only reads the thermocouple module and prints it repeatedly to the Serial Monitor?

I would try moving the CS pin of the Max chip from pin 12 to pin 10 and recompile. Pin 12 is assigned in hardware as the SPI MOSI pin and is probably in conflict with your reassignment as the chip select.

pert:
Please post a link (using the chain links icon on the forum toolbar to make it clickable) to where you downloaded the max6675 library from. Or if you installed it using Library Manger (Sketch > Include Library > Manage Libraries in the Arduino IDE or Libraries > Library Manager in the Arduino Web Editor) then say so and state the full name of the library.

I had installed MAX6675 Library by Adafruit version 1.0.0 using Library Manager.

What happens if you run a minimal sketch that only reads the thermocouple module and prints it repeatedly to the Serial Monitor?

I have already mentioned that when I switch off the 220V AC mains, only temperatures are to be read and displayed. But they are not being updated.

WattsThat:
I would try moving the CS pin of the Max chip from pin 12 to pin 10 and recompile. Pin 12 is assigned in hardware as the SPI MOSI pin and is probably in conflict with your reassignment as the chip select.

Maybe you are right, I will check that tomorrow morning.
However, it has been working perfectly fine since last one week. The strange behavior occurred today afternoon.

I had installed MAX6675 Library by Adafruit version 1.0.0 using Library Manager.

I have updated the library to version 1.0.1 and will check tomorrow if it resolves the issue.

However, it has been working perfectly fine since last one week. The strange behavior occurred today afternoon.

And you did not think this was important enough to mention in your original post? After all, that’s only a minor detail, right?

Don’t bother to swap the CS pin because if it worked for a week, that’s not the problem. It’s not a library issue either.

Since software doesn’t go bad after a week, it’s a bad solder connection, loose wire or a bad component.

Don't get confused here. I meant to say that the thermocouple module has been working fine with simple test codes. I have checked it again with minimum code, it is performing perfectly.

The heater controller code which I included in the original post is still at debugging stage. In that code, the actual temperature (sensed by MAX6675) is not being updated after entering the void loop(). The target temperature set by the POT is updated.

abuhafss:
I have updated the library to version 1.0.1 and will check tomorrow if it resolves the issue.

No, the issue is not resolved even after updating the library.

I got the clue of strange behavior!

The MAX6675 is not fast enough to respond so quickly.
I included a 500ms delay and now it working. Though I need to tweak the code to minimize the temperature oscillation around the set point.

Thanks all for your kind inputs.