diff --git a/crepemaker.ino b/crepemaker.ino index 79ba9a5..ea10fd9 100644 --- a/crepemaker.ino +++ b/crepemaker.ino @@ -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); @@ -29,7 +36,9 @@ 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() { @@ -37,34 +46,82 @@ void setup() { 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)); @@ -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); } diff --git a/user.h b/user.h index d43d8bb..87ebd0d 100644 --- a/user.h +++ b/user.h @@ -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