programs thermocouple with lcd i2c FLC won't work

hallo i have problem with my program. my program work if i use serial monitor but don't work if I add lcd.print on void loop(). its just stuck at first condition without any progress. please help where should i do to my project. here is my code.

//perkenalan lcd
#include <Wire.h> 
#include <LiquidCrystal_I2C.h>

LiquidCrystal_I2C lcd(0x3F,16,2);

//perkenalan library max6675 dan tc//
#include "max6675.h"
int thermoDO = 4;
int thermoCS = 5;
int thermoCLK = 6;

MAX6675 thermocouple(thermoCLK, thermoCS, thermoDO);

int Err, Der;
double t, tmilli, told, setp=30;
double Eneg, ENneg, ENpos, Epos, dEneg, dENneg, dENpos, dEpos;

double apr1, apr2, apr3, apr4, apr5, apr6, apr7, apr8;
double apr9, apr10, apr11, apr12, apr13, apr14, apr15, apr16;
double z1, z2, z3, z4, z5, z6, z7, z8, z9, z10, z11, z12, z13, z14, z15, z16;
double zt1, zt2, zt3, zt4, zt5, zt6, zt7, zt8, zt9, zt10, zt11, zt12, zt13, zt14, zt15, zt16;
double ztot, aprtot;


int OutPWM, PWM;
unsigned long last;

void setup() {
  lcd.init(); // initialize the lcd 
  lcd.init(); // Print a message to the LCD.
  lcd.backlight();
  lcd.setCursor(2,0);
  lcd.print("PROJECT AQUA");
  lcd.setCursor(0,1);
  lcd.print("C=");
  lcd.setCursor(8,1);
  lcd.print("PWM=");
    
  Serial.begin(9600);
  pinMode(3, OUTPUT);
}

void loop() {
 
  t = thermocouple.readCelsius();
  tmilli = t * 1000;
  lcd.setCursor(2,1);
  lcd.print(t);
  lcd.setCursor(12,1);
  lcd.print(OutPWM);
  
  unsigned long Time = millis();
  if (Time - last >= 1000) {
    last = Time;
    Err = setp * 1000 - tmilli;
    Der = tmilli - told;
   
   //mencari keanggotaan error
    switch (Err) {
      case -10000 ... -4001:
        Eneg = 1;
        ENneg = 0;
        ENpos = 0;
        Epos = 0;
        break;

      case -4000 ... -2001:
        Eneg = (0 - Err) / 4000.00;
        ENneg = 0;
        ENpos = 0;
        Epos = 0;
        break;

      case -2000 ... -1:
        Eneg = (0 - Err) / 4000.00;
        ENneg = (Err + 2000) / 2000.00;
        ENpos = 0;
        Epos = 0;
        break;

      case 0 ... 4000:
        Eneg = 0;
        ENneg = 0;
        ENpos = (4000 - Err) / 4000.00;
        Epos = Err / 8000.00;
        break;

      case 4001 ... 8000:
        Eneg = 0;
        ENneg = 0;
        ENpos = 0;
        Epos = Err / 8000.00;
        break;

      case 8001 ... 20000:
        Eneg = 0;
        ENneg = 0;
        ENpos = 0;
        Epos = 1;
        break;
    }   
    
    // Mencari Derajat Keanggotaan Delta Error

    switch (Der) {
      case -400 ... -200:
        dEneg = 1;
        dENneg = 0;
        dENpos = 0;
        dEpos = 0;
        break;

      case -199 ... -100:
        dEneg = ( 0 - Der) / 200.00;
        dENneg = 0;
        dENpos = 0;
        dEpos = 0;
        break;

      case -99 ... 0:
        dEneg = ( 0 - Der) / 200.00;
        dENneg = (Der + 100) / 100.00;
        dENpos = 0;
        dEpos = 0;
        break;

      case 1 ... 100:
        dEneg = 0;
        dENneg = 0;
        dENpos = (100 - Der) / 100.00;
        dEpos = (Der - 0) / 200.00;
        break;
      case 101 ... 200:
        dEneg = 0;
        dENneg = 0;
        dENpos = 0;
        dEpos = (Der - 0) / 200.00;
        break;
      case 201 ... 400:
        dEneg = 0;
        dENneg = 0;
        dENpos = 0;
        dEpos = 1;
        break;
    }

    //mencari a predikat
    apr1 = min(Eneg, dEneg);
    apr2 = min(Eneg, dENneg);
    apr3 = min(Eneg, dENpos);
    apr4 = min(Eneg, dEpos);
    apr5 = min(ENneg, dEneg);
    apr6 = min(ENneg, dENneg);
    apr7 = min(ENneg, dENpos);
    apr8 = min(ENneg, dEpos);
    apr9 = min(ENpos, dEneg);
    apr10 = min(ENpos, dENneg);
    apr11 = min(ENpos, dENpos);
    apr12 = min(ENpos, dEpos);
    apr13 = min(Epos, dEneg);
    apr14 = min(Epos, dENneg);
    apr15 = min(Epos, dENpos);
    apr16 = min(Epos, dEpos);


    //mecari z
    z1 = (apr1 * 50);
    z2 = (apr2 * 50);
    z3 = 50 - (apr3 * 50);
    z4 = 50 - (apr4 * 50);
    z5 = apr5 * 50;
    z6 = apr6 * 50;
    z7 = 50 - (apr7 * 50);
    z8 = 50 - (apr8 * 50);
    z9 = 50 + (apr9 * 50);
    z10 = 50 + (apr10 * 50);
    z11 = 100 - (apr11 * 50);
    z12 = 100 - (apr12 * 50);
    z13 = 50 + (apr13 * 50);
    z14 = 50 + (apr14 * 50);
    z15 = 100 - (apr15 * 50);
    z16 = 100 - (apr16 * 50);

    zt1 = apr1 * z1;
    zt2 = apr2 * z2;
    zt3 = apr3 * z3;
    zt4 = apr4 * z4;
    zt5 = apr5 * z5;
    zt6 = apr6 * z6;
    zt7 = apr7 * z7;
    zt8 = apr8 * z8;
    zt9 = apr9 * z9;
    zt10 = apr10 * z10;
    zt11 = apr11 * z11;
    zt12 = apr12 * z12;
    zt13 = apr13 * z13;
    zt14 = apr14 * z14;
    zt15 = apr15 * z15;
    zt16 = apr16 * z16;

    ztot = zt1 + zt2;
    ztot = ztot + zt3;
    ztot = ztot + zt4;
    ztot = ztot + zt5;
    ztot = ztot + zt6;
    ztot = ztot + zt7;
    ztot = ztot + zt8;
    ztot = ztot + zt9;
    ztot = ztot + zt10;
    ztot = ztot + zt11;
    ztot = ztot + zt12;
    ztot = ztot + zt13;
    ztot = ztot + zt14;
    ztot = ztot + zt15;
    ztot = ztot + zt16;

    aprtot = apr1 + apr2;
    aprtot = aprtot + apr3;
    aprtot = aprtot + apr4;
    aprtot = aprtot + apr5;
    aprtot = aprtot + apr6;
    aprtot = aprtot + apr7;
    aprtot = aprtot + apr8;
    aprtot = aprtot + apr9;
    aprtot = aprtot + apr10;
    aprtot = aprtot + apr11;
    aprtot = aprtot + apr12;
    aprtot = aprtot + apr13;
    aprtot = aprtot + apr14;
    aprtot = aprtot + apr15;
    aprtot = aprtot + apr16;

    PWM = (ztot / aprtot)*1.1 - 150;
    OutPWM = abs(PWM);
    analogWrite (3, OutPWM);

    Serial.print (t);
    Serial.print ("\t");
    Serial.print (Err);
    Serial.print ("\t");
    Serial.print (Der);
    Serial.print ("\t");
    Serial.print (told/1000);
    Serial.print ("\t");
    Serial.print (ztot);
    Serial.print ("\t");
    Serial.print (aprtot);
    Serial.print ("\t");
    Serial.print (OutPWM);
    Serial.println ("\t");
    
    told = tmilli;
    
  }
}

sorry iam bad at english,thank you for your help

your switch statement is not correct. You can not use ranges for the case value. You need to use a series of if() else() statements to see what range 'Err' is and act accordingly.

The case statements with ellipsis (0 ... 4000) are legal. See this page.

Good job with using code tags on your first post. :slight_smile:

its just stuck at first condition without any progress.

Can you please explain little more about where the program appears to get stuck?

Is the display showing any printing?

groundFungus:
The case statements with ellipsis (0 ... 4000) are legal. See this page.

I stand corrected. Thanks!

cattledog:
Good job with using code tags on your first post. :slight_smile:

Can you please explain little more about where the program appears to get stuck?

Is the display showing any printing?

it shows 27 celcius in lcd but actually 31 celcius after i activated my machine 1hour, and i check output voltage to heater was not controlled. but if i use serial monitor and delete lcd.print on void loop it works normally

It would appear that the lcd is interfering with the reading of the thermocouple. It is sounding like the value of t does not change when the lcd is printing.

When you run the lcd are you running the serial output as well? Are both diplays not changing?

I would try to write simple program which just uses the max6675 and lcd output of the temperature. Can you see the readout vary?

There is a max6675.h library example which uses the max6675 and a parallel lcd. You can adopt that to your i2c lcd and verify what is going on.

EDIT: When he display is stuck at 27C what is the value of the pwm output? I am a little unclear if you think the input of the temperature is not working properly, or the output of the pwm is at issue. Separating these two issues would be helpful.

cattledog:
When you run the lcd are you running the serial output as well? Are both diplays not changing?

serial output not running and lcd display not changing.. ouput pwm on 25(HIGH) because i use reverse pwm to controling my heater, and it not change.

serial output not running

Does this mean it should be running, but is not, or is it commented out of the code when the lcd is active.

If the serial output is actually blocked, and the lcd display is unchanging there's something very strange going on, and you will need to trouble shoot this by writing more simple test programs.

Can you get the i2c lcd and the thermocouple running together using the library test code?

There is a very good possibility that the code is blocking while trying to communicate with the lcd. The Wire library blocks waiting for certain conditions to be true when using i2c. Any noise on the lines (like from switching a heater on/off) can put it into an endless loop.

On a project I worked on, I ended up going with a different version of the wire library that had a timeout built in so when a timeout happens, I reset the i2c hardware. There is also the software version of the wire library that doesn't use the build-in hardware.

Here's the order of trouble shooting I recommend.

First, get the i2c lcd displaying readings from the thermocouple which show responsiveness to temperature changes. No heater output.

Then add back the heater output, in response to the temperatures. What is being switched with the PWM and how is it wired? It's indeed possible that noise from the switching is creating a problem.

Finally put back in the Serial output.