Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Faster temperature sampling and moving average #1

Merged
merged 2 commits into from
Oct 14, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
128 changes: 94 additions & 34 deletions crepemaker.ino
Original file line number Diff line number Diff line change
Expand Up @@ -6,19 +6,26 @@
// libraries to be installed from the library manager
#include "max6675.h"

// other compile directives
#define LOOPTIME 500 // cycle time, in ms

// global variables and objects
MAX6675 thermocouple1(CLKPIN, CS1PIN, DOPIN);
MAX6675 thermocouple2(CLKPIN, CS2PIN, DOPIN);

// variables for the heating control
float previoustemp1 = 0;
float previoustemp2 = 0;
unsigned long timestamp = 0;
int counter = 0;

void seriallogger(float temp1, float temp2, float ror1, float ror2, float projectedtemp1, float projectedtemp2) {
unsigned long lastControlUpdate = 0; // last time controls were updated

// variables for the moving averages on temperature readings
float tempReadings1[NUMREADINGS]; // the temperature readings from the analog input
float tempReadings2[NUMREADINGS];
int readIndex = 0; // the index of the current reading
unsigned long lastRead = 0; // last time readings were updated
float tempReadingsTotal1 = 0; // the running total
float tempReadingsTotal2 = 0;
float temp1; // the average
float temp2;

void seriallogger(float temp1, float temp2, float ror1, float ror2, float projectedtemp1, float projectedtemp2, byte control) {
Serial.print(temp1);
Serial.print(",");
Serial.print(temp2);
Expand All @@ -29,42 +36,92 @@ void seriallogger(float temp1, float temp2, float ror1, float ror2, float projec
Serial.print(",");
Serial.print(projectedtemp1);
Serial.print(",");
Serial.println(projectedtemp2);
Serial.print(projectedtemp2);
Serial.print(",");
Serial.println(control);
}

void setup() {
pinMode(SSR1PIN, OUTPUT);
pinMode(SSR2PIN, OUTPUT);

Serial.begin(BAUD);

// wait for MAX chips to stabilize
delay(500);

// initialize the readings array to zero
for (int i = 0; i < NUMREADINGS; i++) {
tempReadings1[i] = 0;
tempReadings2[i] = 0;
}

// initialize the temperature readings and averages with actual values
while (readIndex < NUMREADINGS - 1) {
updateTemperatureReadings();
delay(LOOP_PERIOD_MS);
}
}

void loop() {
updateTemperatureReadings();
updateControls();
delay(LOOP_PERIOD_MS);
}

void updateTemperatureReadings() {
if (millis() - lastRead < READING_PERIOD_MS) {
return;
}

lastRead += READING_PERIOD_MS;

// subtract the last reading
tempReadingsTotal1 = tempReadingsTotal1 - tempReadings1[readIndex];
tempReadingsTotal2 = tempReadingsTotal2 - tempReadings2[readIndex];

// read from the sensor
tempReadings1[readIndex] = thermocouple1.readCelsius();
tempReadings2[readIndex] = thermocouple2.readCelsius();

// add the reading to the total
tempReadingsTotal1 = tempReadingsTotal1 + tempReadings1[readIndex];
tempReadingsTotal2 = tempReadingsTotal2 + tempReadings2[readIndex];

// advance to the next position in the array
readIndex = readIndex + 1;

// if we are at the end of the array...
if (readIndex >= NUMREADINGS) {
// ...wrap around to the beginning
readIndex = 0;
}

// calculate the average
temp1 = tempReadingsTotal1 / NUMREADINGS;
temp2 = tempReadingsTotal2 / NUMREADINGS;
}

void loop() {
void updateControls()
{
unsigned long timeelapsed = 0;
float temp1;
float temp2;
float ror1;
float ror2;
float projectedtemp1;
float projectedtemp2;

temp1 = thermocouple1.readCelsius();
temp2 = thermocouple2.readCelsius();

if (counter >= SAMPLING) {
timeelapsed = (millis() - timestamp);
ror1 = (((temp1 - previoustemp1) / timeelapsed) * 1000 * 60); //Raise of rise in C/min
ror2 = (((temp2 - previoustemp2) / timeelapsed) * 1000 * 60); //Raise of rise in C/min
timestamp = millis();
counter = 0;
previoustemp1 = temp1; // We should really calculate an average rather...
previoustemp2 = temp2;
timeelapsed = (millis() - lastControlUpdate);

if (timeelapsed < CONTROL_UPDATE_PERIOD_MS) {
return;
}

counter++;

lastControlUpdate += CONTROL_UPDATE_PERIOD_MS; // do not use timeelapsed here to avoid drift

ror1 = (((temp1 - previoustemp1) / timeelapsed) * 1000 * 60); //Raise of rise in C/min
ror2 = (((temp2 - previoustemp2) / timeelapsed) * 1000 * 60); //Raise of rise in C/min
previoustemp1 = temp1;
previoustemp2 = temp2;

if (ror1 >= 0) {
projectedtemp1 = (temp1 + (ror1 * RISEINERTIA));
Expand All @@ -80,21 +137,24 @@ void loop() {
projectedtemp2 = (temp2 + (ror2 * FALLINERTIA));
}

seriallogger(temp1,temp2,ror1,ror2,projectedtemp1,projectedtemp2);
byte control = 0;

if (projectedtemp1 <= SV1) {
digitalWrite(SSR2PIN, LOW);
digitalWrite(SSR1PIN, HIGH);
}
if (projectedtemp1 <= SV1) {
digitalWrite(SSR2PIN, LOW);
digitalWrite(SSR1PIN, HIGH);
control = 1;
}
else {
digitalWrite(SSR1PIN, LOW);
digitalWrite(SSR1PIN, LOW);

if (projectedtemp2 <= SV2) {
digitalWrite(SSR2PIN, HIGH);
digitalWrite(SSR2PIN, HIGH);
control = 2;
}
else {
digitalWrite(SSR2PIN, LOW);
digitalWrite(SSR2PIN, LOW);
}
}
delay(LOOPTIME);

seriallogger(temp1, temp2, ror1, ror2, projectedtemp1, projectedtemp2, control);
}
14 changes: 11 additions & 3 deletions user.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,22 @@
#define RISEINERTIA 3 //how long it takes the system to stop rising (in min)
#define FALLINERTIA 1 //how long it takes the system to stop falling (in min)

#define SAMPLING 5 //loops to calculate ror
// cycle time, in ms
#define LOOP_PERIOD_MS 1

// Delay time between temperature readings
// from the temperature sensor (ms).
#define DELAY_TIME 20
// (must be larger than LOOP_PERIOD_MS)
// MAX6675 takes about 200 ms to convert
#define READING_PERIOD_MS 200

// How many readings are taken to determine a mean temperature.
#define READINGS 10
// accounts for the thermocouple noise
#define NUMREADINGS 10

// delay between 2 control updates
// (must be larger than LOOP_PERIOD_MS)
#define CONTROL_UPDATE_PERIOD_MS 2000

// Pin mapping
// Common SPI pins
Expand Down