plt temperature

This commit is contained in:
2021-08-23 07:48:44 +02:00
parent d0fbc713a5
commit 42dd5f9261
12 changed files with 175 additions and 67 deletions

View File

@@ -16,10 +16,10 @@ upload_protocol = stlink
debug_tool = stlink
monitor_speed = 115200
lib_deps =
yuriisalimov/MAX6675_Thermocouple@^2.0.2
bodmer/TFT_eSPI@^2.3.70
br3ttb/PID@^1.2.1
;siruli/MAX6675@^2.1.0
zhenek-kreker/MAX6675 with hardware SPI@^1.0.0
lib_ldf_mode = deep+
build_flags =
-D USER_SETUP_LOADED=1

View File

@@ -7,9 +7,11 @@
// #define LCD_DC PB1
// #define LCD_CS PB0
#define THERM_CS PB5
#define THERM_SO PB4
#define THERM_CL PB6
#define THERM_SS PB12
#define THERM_MISO PB13
#define THERM_CLK PB14
#define THERM_MOSI PB15 //not used
#define HEAT_OUT PA2

View File

@@ -4,13 +4,9 @@
#include "button.h"
#include "lcd.h"
// Button AXIS_Y = Button(BUTTON_AXIS_Y, true, DEBOUNCE_MS);
// Button AXIS_X = Button(BUTTON_AXIS_X, true, DEBOUNCE_MS);
/*******************************************************************************
Title: Reflow Oven Controller
Version: 1.20
@@ -157,6 +153,7 @@ int oldTemp = 0;
byte state;
bool disableMenu;
bool profileIsOn;
uint32_t processStartTime = 0;
// Specify PID control interface & it must be here, after all declaration
PID reflowOvenPID(&input, &output, &setpoint, kp, ki, kd, DIRECT);
@@ -169,8 +166,9 @@ void initControlLoop(void)
nextCheck = millis();
// Initialize thermocouple reading variable
nextRead = millis();
}
pinMode(HEAT_OUT, OUTPUT);
}
String getReflowStatus_str(void)
{
@@ -258,6 +256,59 @@ bool getOutputState(void)
return outputState;
}
uint32_t safetyTimer = 0;
#define SAFETYTIMEOUT 5000 //ms
double oldinput = 0;
#define SAFETYMARGIN 5 //degrees C
bool SafetyError = false;
bool getSafetyCheck(void)
{
uint32_t timeNow = millis();
if (!outputState)
{
safetyTimer = timeNow;
oldinput = input;
return true;
}
else
{
if (timeNow - safetyTimer > SAFETYTIMEOUT)
{
if (input - oldinput < SAFETYMARGIN)
{
setReflowStatus(false);
return false;
}
else
{
return true;
oldinput = input;
}
}
}
return true;
}
float getProcessTime(void)
{
if ((reflowStatus == REFLOW_STATUS_ON) && (processStartTime > 0))
{
float retval = (millis() - processStartTime);
retval /= 1000;
return retval;
}
else
{
return 0;
}
}
bool getOverheating(void)
{
return (reflowState == REFLOW_STATE_TOO_HOT);
}
void handleReflowStatemachine(void)
{
// Reflow oven controller state machine
@@ -265,6 +316,7 @@ void handleReflowStatemachine(void)
{
case REFLOW_STATE_IDLE:
activeStatus = "Idle";
processStartTime = 0;
// If oven temperature is still above room temperature
if (input >= TEMPERATURE_ROOM)
{
@@ -284,7 +336,7 @@ void handleReflowStatemachine(void)
// Initialize PID control window starting time
windowStartTime = millis();
// Ramp up to minimum soaking temperature
setpoint = TEMPERATURE_SOAK_MIN;
setpoint = TEMPERATURE_SOAK_MIN + 5;
// Tell the PID to range between 0 and the full window size
reflowOvenPID.SetOutputLimits(0, windowSize);
reflowOvenPID.SetSampleTime(PID_SAMPLE_TIME);
@@ -292,6 +344,8 @@ void handleReflowStatemachine(void)
reflowOvenPID.SetMode(AUTOMATIC);
// Proceed to preheat stage
reflowState = REFLOW_STATE_PREHEAT;
// log process start time
processStartTime = millis();
}
}
break;
@@ -520,7 +574,6 @@ void handleTemperatureReadings(void)
}
}
/* ---- REFLOW MAIN LOOP ---- */
void handleControlLoop()
{
@@ -529,7 +582,7 @@ void handleControlLoop()
Serial.println("handlecontrolloop: ERROR state");
return;
}
getSafetyCheck();
handleTemperatureReadings();
handleReflowStatemachine();
handleReflowPID();

View File

@@ -77,3 +77,5 @@ reflowStatus_t getReflowStatus(void);
void setReflowStatus(bool newStatus);
double getReflowTargetTemp(void);
bool getOutputState(void);
float getProcessTime(void);
bool getOverheating(void);

View File

@@ -1,20 +0,0 @@
#include "heater.h"
uint16_t heatingProfile[] =
{
30,
50,
70,
90
};
void initHeater(void)
{
pinMode(HEAT_OUT,OUTPUT);
digitalWrite(HEAT_OUT, LOW);
}
void handleHeater(void)
{
}

View File

@@ -1,7 +0,0 @@
#pragma once
#include "Arduino.h"
#include "board.h"
void initHeater(void);
void handleHeater(void);

View File

@@ -3,6 +3,7 @@
#include "thermo.h"
#include "controlloop.h"
#include "button.h"
#include <vector>
#include <TFT_eSPI.h> // Include the graphics library
@@ -27,11 +28,11 @@ uint32_t lastButtonTime = 0;
void updateTemperature(void)
{
//draw actualTemperature
chartArea_spr.fillRoundRect(TEMP_X, 0, 60-TEMP_R, TEMP_H, TEMP_R, TEMP_BG_COLOR);
chartArea_spr.fillRoundRect(TEMP_X, 0, 60 - TEMP_R, TEMP_H, TEMP_R, TEMP_BG_COLOR);
chartArea_spr.drawString("A:", TEMP_X + TEMP_LABEL_X, TEMP_H / 4);
chartArea_spr.drawString("T:", TEMP_X + TEMP_LABEL_X, TEMP_H / 4 * 3);
chartArea_spr.drawNumber(getTemperature(), TEMP_X + TEMP_VALUE_X, TEMP_H / 4);
chartArea_spr.drawFloat(getTemperature(), 1, TEMP_X + TEMP_VALUE_X, TEMP_H / 4);
if (getReflowStatus() == REFLOW_STATUS_OFF)
{
chartArea_spr.drawString("--", TEMP_X + TEMP_VALUE_X, TEMP_H / 4 * 3);
@@ -45,7 +46,12 @@ void updateTemperature(void)
uint32_t calcTemp(double temp)
{
//map(long x, long in_min, long in_max, long out_min, long out_max)
return CHART_H - map(temp, CHART_TEMP_MIN, CHART_TEMP_MAX, CHART_Y_AXIS_OFFSET, CHART_H) + CHART_X_AXIS_OFFSET;
return CHART_H - map(temp, CHART_TEMP_MIN, CHART_TEMP_MAX, CHART_X_AXIS_OFFSET, CHART_H) + CHART_X_AXIS_OFFSET;
}
uint32_t calcTempY(uint32_t inputY)
{
return map(inputY, CHART_H, CHART_X_AXIS_OFFSET, CHART_TEMP_MIN, CHART_TEMP_MAX);
}
uint32_t calcTime(uint32_t timeMs)
@@ -53,6 +59,40 @@ uint32_t calcTime(uint32_t timeMs)
return map((timeMs / 1000), 0, CHART_TIME_MAX, 0, CHART_W - CHART_Y_AXIS_OFFSET);
}
std::vector<double> temperatureReading;
uint32_t lastReading = 0;
#define TEMPINTERVAL 1000
void updateRealtimeGraph(void)
{
if(getReflowStatus() == REFLOW_STATUS_OFF)
{
temperatureReading.clear();
return;
}
//record temperature
uint32_t timeNow = millis();
if (timeNow - lastReading > TEMPINTERVAL)
{
temperatureReading.push_back(getTemperature());
lastReading = timeNow;
}
//draw graph
uint32_t timeIndex = 0;
uint32_t lastX = 0;
uint32_t lastY = 0;
for (auto &&sample : temperatureReading)
{
uint32_t nowX = calcTime(timeIndex * TEMPINTERVAL);
uint32_t nowY = calcTemp(sample);
chartArea_spr.drawLine(lastX,lastY, nowX, nowY, CHART_ACTUAL_COLOR);
lastX = nowX;
lastY = nowY;
timeIndex ++;
}
}
void updateTargetChart(void)
{
@@ -93,6 +133,8 @@ void updateTargetChart(void)
calcTemp(TEMPERATURE_ROOM),
CHART_TARGET_COLOR);
updateRealtimeGraph();
updateTemperature();
chartArea_spr.pushSprite(CHART_X + CHART_Y_AXIS_OFFSET, CHART_Y);
}
@@ -108,7 +150,12 @@ void prepTargetChart(void)
void updateReflowState(void)
{
reflowstate_spr.fillRoundRect(STATE_OFFSET, 0, (STATE_W / 2) - (2 * STATE_OFFSET), STATE_H, STATE_R, STATE_BG_COLOR);
uint32_t statusColor = STATE_BG_COLOR;
if(getOverheating())
{
statusColor = TFT_RED;
}
reflowstate_spr.fillRoundRect(STATE_OFFSET, 0, (STATE_W / 2) - (2 * STATE_OFFSET), STATE_H, STATE_R, statusColor);
reflowstate_spr.fillRoundRect(STATE_W / 2 + STATE_OFFSET, 0, (STATE_W / 2) - (2 * STATE_OFFSET), STATE_H, STATE_R, STATE_BG_COLOR);
reflowstate_spr.drawString(getReflowState_str(), STATE_W / 4, STATE_H / 2);
reflowstate_spr.drawString(getReflowStatus_str(), STATE_W / 4 * 3, STATE_H / 2);
@@ -161,7 +208,7 @@ void prepChart(void)
for (int i = 0; i < CHART_Y_TICKS; i++)
{
//tick value
uint16_t y_tick_step = CHART_TEMP_MAX - ((CHART_TEMP_MAX - CHART_TEMP_MIN) / CHART_Y_TICKS * i + 1) + CHART_TEMP_MIN;
uint16_t y_tick_step = calcTempY( tickIndex * (i +1));//CHART_TEMP_MAX - ((CHART_TEMP_MAX - CHART_TEMP_MIN) / CHART_Y_TICKS * i + 1) + CHART_TEMP_MIN;
chartYaxis_spr.drawLine(CHART_Y_AXIS_OFFSET - 8, tickIndex * (i + 1), CHART_Y_AXIS_OFFSET, tickIndex * (i + 1), CHART_LINE_COLOR);
chartYaxis_spr.setTextDatum(BR_DATUM);
chartYaxis_spr.drawString(String(y_tick_step), CHART_Y_AXIS_OFFSET - 3, tickIndex * (i + 1), CHART_FONT);
@@ -182,14 +229,17 @@ void prepChart(void)
void prepStatus(void)
{
looptime_spr.createSprite(20, tft.fontHeight(1) + 1);
looptime_spr.createSprite(80, tft.fontHeight(1) + 1);
}
void updateStatus(void)
{
looptime_spr.fillSprite(TFT_BLACK);
looptime_spr.setTextDatum(MC_DATUM);
looptime_spr.drawNumber(getLooptime(), looptime_spr.width() / 2, looptime_spr.height() / 2, 1);
looptime_spr.setTextDatum(TL_DATUM);
looptime_spr.setTextColor(TFT_WHITE);
looptime_spr.drawNumber(getLooptime(), 1, 1, 1);
looptime_spr.drawFloat(getProcessTime(), 2, 20, 1, 1);
looptime_spr.pushSprite(1, 1);
}

View File

@@ -30,11 +30,11 @@
#define CHART_TIME_MAX 140 //time scale in seconds
#define CHART_TEMP_MIN 20 //offset in degrees
#define CHART_TEMP_MAX 240 //degrees
#define CHART_Y_TICKS 11
#define CHART_Y_TICKS 10
#define CHART_X_TICKS 7
#define CHART_LINE_COLOR TFT_WHITE
#define CHART_TEXT_COLOR TFT_RED
#define CHART_TARGET_COLOR TFT_WHITE
#define CHART_TARGET_COLOR TFT_LIGHTGREY
#define CHART_ACTUAL_COLOR TFT_RED
#define CHART_BG_COLOR TFT_BLACK
@@ -58,7 +58,7 @@
#define TEMP_BG_COLOR TFT_BLUE
#define TEMP_R TFT_DEFAULT_R
#define TEMP_LABEL_X 2
#define TEMP_VALUE_X 30
#define TEMP_VALUE_X 20
#define OUTPUT_W 12
#define OUTPUT_H 12

View File

@@ -4,7 +4,6 @@
#include "lcd.h"
#include "thermo.h"
#include "button.h"
#include "heater.h"
#include "status.h"
#include "controlloop.h"
@@ -14,7 +13,6 @@ void setup()
initLCD();
initThermo();
initButton();
initHeater();
initControlLoop();
}
@@ -25,7 +23,6 @@ void loop()
handleLCD();
handleThermo();
handleButton();
handleHeater();
handleStatus();
handleControlLoop();
}

View File

@@ -1,5 +1,6 @@
#include "status.h"
#include "controlloop.h"
uint64_t timelast = 0;
uint64_t blinkrate = 500;
@@ -33,3 +34,8 @@ uint32_t getLooptime(void)
{
return looptime;
}
double getReflowTime(void)
{
return getProcessTime();
}

View File

@@ -1,31 +1,57 @@
#include "thermo.h"
#include "controlloop.h"
Thermocouple *thermocouple = NULL;
MAX6675 thermocouple(THERM_SS, THERM_MISO, THERM_CLK);
uint32_t thermo_lastTime = 0;
double lastTemperature = 0;
bool simulation = true;
#define SIM_TEMP_STEP 1
#define SIM_TEMP_COOL 0.08
#define SIM_INTERVAL 100
uint32_t simTimer = 0;
void initThermo()
{
Thermocouple *originThermocouple = new MAX6675_Thermocouple(THERM_CL, THERM_CS, THERM_SO);
thermocouple = new SmoothThermocouple(originThermocouple, SMOOTHING_FACTOR);
if(simulation)
{
lastTemperature = TEMPERATURE_ROOM-20;
}
}
void handleThermo(void)
{
// Reads temperature
uint32_t timeNow = millis();
if (timeNow - thermo_lastTime > THERMO_INTERVAL)
if(simulation)
{
lastTemperature = thermocouple->readCelsius();
thermo_lastTime = timeNow;
uint32_t timeNow = millis();
if(timeNow - simTimer > SIM_INTERVAL)
{
if(getOutputState())
{
lastTemperature += SIM_TEMP_STEP;
}
else
{
if(lastTemperature > TEMPERATURE_ROOM-20)
{
lastTemperature -= SIM_TEMP_COOL;
}
}
simTimer = timeNow;
}
}
else
{
lastTemperature = thermocouple.readTempC();
}
}
double getTemperature(void)
{
return 23;//lastTemperature;
return lastTemperature; //lastTemperature;
}
bool getThermoCoupleFault(void)

View File

@@ -2,9 +2,8 @@
#include "Arduino.h"
#include "board.h"
#include <Thermocouple.h>
#include <MAX6675_Thermocouple.h>
#include <SmoothThermocouple.h>
#include "max6675.h"
#define THERMO_INTERVAL 200
#define SMOOTHING_FACTOR 2