Need help with this project

The issue now is how to create a profile of a constant temperature fixed to let's say +- 1 on 50 degrees C. I tried doing this without PID and I am unable to regulate the temp; With the code written below I get pretty much 60C then it doesn't stay constant. Any tips or suggestions on this? Current setup is this reflow controller + a relay + a oven (2heaters top + bot connected together)

Constant_temp_arduino.ino (2.57 KB)

Please read the first topic "How to use this Forum", especially section #7, how to post code. That will make it possible for more helpers to read Your code. Phones, tablets.... can't always run the IDE needed.

int targetTemp = 33;
int tolerance = 1;

int timer = -1;
int overrideOff = false;
int timeToCookInMilli = 3 * 60 * 60 * 1000;

void loop() {
  
  if (currentTemp > targetTemp + tolerance) {
    // close relay 
    digitalWrite(ssrPin, LOW); 
    
  } else if (currentTemp < targetTemp - tolerance) {
    digitalWrite(ssrPin, HIGH); 
  }

  if (timer == -1 && currentTemp > targetTemp - tolerance && currentTemp < targetTemp + tolerance) {
    timer = millis();
  }

  if (timer != -1 && millis() >= timer + timeToCookInMilli) {
    // jobs done. 
  }
}

This limit

int timeToCookInMilli = 3 * 60 * 60 * 1000;

makes 3 hours in calculation. Looks strange.

This line of code makes nothing

  if (timer != -1 && millis() >= timer + timeToCookInMilli) {
    // jobs done.

  }

The last line is how it would end 3hrs later , ssr pin will remain low from previous temp call; let's say we are running it for 3hrs @ constant temp of 50C what do I have to modify to make this work ?

Your reply tells me nothing, makes no sense. An empty if......

You get 60 degrees but not constant...... Why not tell in detail what's happening?

Maybe PID and PWM could make the performance better.

From the code program runs from idle 24- 25C -> ssr lights red -> heaters light up -> ssr turns off once thermocouple reads 33 -> temp still rises -> after the time runs out the temp starts to decrease

Diagram - Album on Imgur Here is a picture of the diagram setup

Measure at what temperature it's needed to shut off power to avoid too high temperature. Measure at what temperature it's needed to turn on power to avoid under temperature.
If I remember correctly thermocoupler are rather slow. Check data sheets.

Better would be to use PWM and PID control, and maybe also a faster temperature sensor.

awert7:
Diagram - Album on Imgur Here is a picture of the diagram setup

Please post pictures here. I don't accept being invaded by their cookies, adds ......

Diagram

What You did draw looks okey. How is the controller powered? (Just to be sure.) USB?
Use Serial Monitor, or Serial Plotter, and Serial.print, printing how the temperature change.

Serial is only working to upload code; if I try to run something connected on serial the thermocouple will read alot higher which will not allow me to run the code. Otherwise it works on usb only

This is the controller diagram it is connected via usb serial, power connected via ISP - 6 pin
-ATmega328P
-Built-in USB-serial interface(CH340E)

Railroader:
This limit

int timeToCookInMilli = 3 * 60 * 60 * 1000;

makes 3 hours in calculation.

Or it would, if that number fitted in a sixteen bit variable.

Hi,
What controller are you using? UNO Nano ? ? ?

What is the application?
What are you heating?
How much heating power?

Can I suggest you forget about timers and such things for the moment and just write code to get your temperature correct.

You have a tolerance of 1C, madness to begin with when prototyping a controller.
Have you checked the calibration of your temperature sensor?

Thanks.. Tom... :slight_smile:

Attach the entire code. Also improve the drawing showing the pin names.
Using Serial for debugging is more ir less mandatory. How else will You do to find out about various things happening inside the code?

TheMemberFormerlyKnownAsAWOL:
Or it would, if that number fitted in a sixteen bit variable.

OP has to be fast putting the bits there to manage before all 16 are used... Or push harder...

  • a custom board , using ATMega328P-MU 3.3V 8MHz based on Arduino Pro / Pro Mini
  • 2 x 600 w = 1200 w toaster oven
  • Building a temp controller for an oven at ~50C
  • the 1c is for test, it can be within range of 50 C
    -thermocouple is fine
    -Serial interface is not working which is an issue
    Worst case I will get one of these - https://www.amazon.ca/Inkbird-All-Purpose-Thermostat-Temperature-Controller/dp/B073Y6YQXB - and do the job, would rather not
// ***** INCLUDES *****
#include <SPI.h>
#include <Wire.h>
#include <EEPROM.h>
#include <LiquidCrystal.h>
#include <Adafruit_GFX.h>      // Comment for VERSION 1
#include <Adafruit_SSD1306.h>  // Comment for VERSION 1 
#include <Adafruit_MAX31856.h> 
#include <PID_v1.h>


#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels
#define X_AXIS_START 18 // X-axis starting position


// ***** DEGREE SYMBOL FOR LCD *****
unsigned char degree[8]  = {
  140, 146, 146, 140, 128, 128, 128, 128
};

unsigned char ssrPin = A0;
unsigned char fanPin = A1;
unsigned char thermocoupleCSPin = 10;
unsigned char ledPin = 4;
unsigned char buzzerPin = 5;
unsigned char switchStartStopPin = 3;
unsigned char switchLfPbPin = 2;

int windowSize;
unsigned long windowStartTime;
unsigned long nextCheck;
unsigned long nextRead;
unsigned long updateLcd;

unsigned int timerSeconds;
// Thermocouple fault status
unsigned char fault;

unsigned int timerUpdate;
unsigned char temperature[SCREEN_WIDTH - X_AXIS_START];
unsigned char x;

#define UPDATE_RATE 100
double input;
double output;
double setpoint;
double kp=2,ki=5,kd=1;

PID myPID(&input, &output, &setpoint,kp,ki,kd,DIRECT);

int targetTemp = 50;
int tolerance = 1;

int timer = -1;
int overrideOff = false;
int timeToCookInMilli = 3 * 60 * 1000;

Adafruit_SSD1306 oled(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire);
Adafruit_MAX31856 thermocouple = Adafruit_MAX31856(thermocoupleCSPin);


 
void setup()
{
  
  // SSR pin initialization to ensure reflow oven is off
  digitalWrite(ssrPin, LOW);
  pinMode(ssrPin, OUTPUT); 
  setpoint = 50;

  //turn the PID on
  myPID.SetMode(AUTOMATIC);

  // Initialize thermocouple interface
  thermocouple.begin();
  thermocouple.setThermocoupleType(MAX31856_TCTYPE_K);
  oled.begin(SSD1306_SWITCHCAPVCC, 0x3C);
  oled.display();
  delay(2000);
  
  ///
  
  oled.clearDisplay();
  oled.setTextSize(1);
  oled.setTextColor(WHITE);
  oled.setCursor(0, 0);
  oled.println(F("     Temp"));
  oled.println(F("     Test"));
  oled.println();
  oled.println(F("       v1.00"));
  oled.println();
  oled.println(F("      29-03-21"));
  oled.display();
  delay(3000);
  oled.clearDisplay();


  // Serial communication at 115200 bps
  Serial.begin(115200);

  // Set window size
  windowSize = 2000;
  // Initialize time keeping variable
  nextCheck = millis();
  // Initialize thermocouple reading variable
  nextRead = millis();
  // Initialize LCD update timer
  updateLcd = millis();
}

void loop()
{
  // Current time
  unsigned long now;

  // Time to read thermocouple?
  if (millis() > nextRead)
  {
    // Read current temperature
    input = thermocouple.readThermocoupleTemperature();
  }
////////////////

  if (millis() > updateLcd)
  {
    // Update LCD in the next 100 ms
    updateLcd += UPDATE_RATE;
    
    oled.clearDisplay();
    oled.setTextSize(2);
    oled.setCursor(0, 0);
    oled.setTextSize(1);
    oled.setCursor(115, 0);

    
    // Temperature markers
    oled.setCursor(0, 18);
    oled.print(F("250"));
    oled.setCursor(0, 36);
    oled.print(F("150"));
    oled.setCursor(0, 54);
    oled.print(F("50"));
    // Draw temperature and time axis
    oled.drawLine(18, 18, 18, 63, WHITE);
    oled.drawLine(18, 63, 127, 63, WHITE);
    oled.setCursor(115, 0);

      if (input < 10) oled.setCursor(91, 9);
      else if (input < 100) oled.setCursor(85,9);
      else oled.setCursor(80, 9);
      // Display current temperature
      oled.print(input);
      oled.print((char)247);
      oled.print(F("C"));
      
      Serial.print(input);
      Serial.print((char)247);
      Serial.print(F("C"));
      delay(500);

      if (timerSeconds > timerUpdate)
      {
        // Store temperature reading every 3 s
        if ((timerSeconds % 3) == 0)
        {
          timerUpdate = timerSeconds;
          unsigned char averageReading = map(input, 0, 250, 63, 19);
          if (x < (SCREEN_WIDTH - X_AXIS_START))
          {
            temperature[x++] = averageReading;
          }
       }
      }
    
    unsigned char timeAxis;
    for (timeAxis = 0; timeAxis < x; timeAxis++)
    {
      oled.drawPixel(timeAxis + X_AXIS_START, temperature[timeAxis], WHITE);
    }
    
    // Update screen
    oled.display();

  }



 
 
  if (input > targetTemp + tolerance) {
    // close relay 
    digitalWrite(ssrPin, LOW); 
    
  } else if (input < targetTemp - tolerance) {
    myPID.Compute();
    digitalWrite(ssrPin, HIGH); 
  }

  if (timer == -1 && input > targetTemp - tolerance && input < targetTemp + tolerance) {
    timer = millis();
  }

  if (timer != -1 && millis() >= timer + timeToCookInMilli) {
    // jobs done. 
    
  }


  
}

This line of code will go wrong: int timeToCookInMilli = 3 * 60 * 1000; as it ends up like 180 000.
The maximum value for an int is 32767. An unsigned int can reach up to 65535.