Robin2:
This is not right
previousHeaterMillis = currentMillis;
digitalWrite(HeaterPin, HIGH);
previousHeaterMillis += heaterInterval;
Only use one of the first or third lines, not both. My strong preference is for the first (simpler) style unless it is very important to avoid the occasional timing error of 1 millisec.
And I think this is correct either, for a different reason
else
{
digitalWrite(HeaterPin, LOW);
previousHeaterMillis += heaterInterval;
}
The ELSE clause should NOT update the timer because it would have the effect of preventing the timer from ever expiring
Also keep in mind that this ELSE clause will probably be called hundreds of times for every occasion that the IF clause is satisfied.
That's probably enough for now.
The demo [Several Things at a Time](http://forum.arduino.cc/index.php?topic=223286.0) illustrates the use of millis() to manage timing without blocking. It may help with understanding the technique.
Have a look at [Using millis() for timing. A beginners guide](http://forum.arduino.cc/index.php?topic=503368.0) if you need more explanation.
...R
Ok i have modified the code as per your suggestion, i'm now getting some action on the relay, however it seems to be acting the reverse of what i need, and i don;t think it is the digitalWrite actions that are wrong. I have modified the setpoint for testing as i've burnt my thermal fuses so can't actually heat the block right now >:(
It appears that in Stage 1 heating the relay is on more than off, i.e. it is on and blips off briefly once per 500ms window, instead of on exclusively (500ms out of every 500ms window)
In Stage 2 heating it turns on and off rapidly (should be on for 125ms in every 500ms window)
and in Stage 3 heating it is completely off, instead of blipping on for 50ms in every 500ms window.
Hopefully you can see how it is incorrect, let me know if i need to rephrase anything?
Current sketch:
// Sketch to control the temperature of a thermoblock for the production of small quatities of water
// for espresso shots.
// Non-PID version
// Three stage heating process implemented
// which analog pin to connect
#define THERMISTORPIN A0
// resistance at 25 degrees C
#define THERMISTORNOMINAL 100000
// temp. for nominal resistance (almost always 25 C)
#define TEMPERATURENOMINAL 25
// how many samples to take and average, more takes longer
// but is more 'smooth'
#define NUMSAMPLES 5
// The beta coefficient of the thermistor (usually 3000-4000)
#define BCOEFFICIENT 3950
// the value of the 'other' resistor
#define SERIESRESISTOR 100000
#define HeaterPin 6
#define PumpPin 7
#define ButtonPin 8
unsigned long startTime;
int oldState;
long shotStart;
unsigned long previousSerialMillis;
unsigned long currentPumpMillis;
unsigned long previousPumpMillis;
unsigned long previousButtonMillis = 0;
unsigned long currentHeaterMillis;
unsigned long previousHeaterMillis = 0;
unsigned long currentMillis;
const int buttonInterval = 1000;
const int pumpInterval = 500;
int heaterInterval;
byte PumpState = LOW;
unsigned long PumpPurge = 8000;
String Power;
int samples[NUMSAMPLES];
// include the library code:
#include <LiquidCrystal.h>
#include <math.h>
// initialize the library by associating any needed LCD interface pin
// with the arduino pin number it is connected to
const int rs = 12, en = 11, d4 = 5, d5 = 4, d6 = 3, d7 = 2;
LiquidCrystal lcd(rs, en, d4, d5, d6, d7);
//Define Variables we'll be connecting to
double Setpoint = 27, Input, Output;
float temp;
int WindowSize = 500;
unsigned long windowStartTime;
void setup(void) {
Serial.begin(9600);
lcd.begin(16, 2); // set up the LCD's number of columns and rows:
analogReference(EXTERNAL);
pinMode(HeaterPin, OUTPUT);
pinMode(PumpPin, OUTPUT);
pinMode(ButtonPin, INPUT_PULLUP); //no button as yet
digitalWrite(ButtonPin, HIGH);
digitalWrite(HeaterPin, HIGH); //heater off
digitalWrite(PumpPin, HIGH); //pump off
windowStartTime = millis();
}
void Get_Temp()
{
uint8_t i;
float average;
// take N samples in a row, with a slight delay
for (i = 0; i < NUMSAMPLES; i++) {
samples[i] = analogRead(THERMISTORPIN);
delay(10);
}
// average all the samples out
average = 0;
for (i = 0; i < NUMSAMPLES; i++) {
average += samples[i];
}
average /= NUMSAMPLES;
// convert the value to resistance
average = 1023 / average - 1;
average = SERIESRESISTOR / average;
//Calculates temp C from NTC resistance readings gather above
temp = average / THERMISTORNOMINAL; // (R/Ro)
temp = log(temp); // ln(R/Ro)
temp /= BCOEFFICIENT; // 1/B * ln(R/Ro)
temp += 1.0 / (TEMPERATURENOMINAL + 273.15); // + (1/To)
temp = 1.0 / temp; // Invert
temp -= 273.15; // convert to C
}
void loop(void) {
Get_Temp();
currentMillis = millis();
lcd.setCursor(0, 0);
lcd.print("Heating Water...");
if (temp < (Setpoint - 35)) { //full power for cold start
heaterInterval = (WindowSize - 0);
if (currentMillis - previousHeaterMillis >= heaterInterval)
{
previousHeaterMillis = currentMillis;
digitalWrite(HeaterPin, HIGH);
Serial.print(WindowSize);
Serial.print(" ");
Serial.print(heaterInterval);
Serial.println(" ");
}
else
{
digitalWrite(HeaterPin, LOW);
}
}
else if (temp < (Setpoint - 15)) { //reduce power to gently reach SP
heaterInterval = (WindowSize - 375);
if (currentMillis - previousHeaterMillis >= heaterInterval)
{
previousHeaterMillis = currentMillis;
digitalWrite(HeaterPin, HIGH);
Serial.print(WindowSize);
Serial.print(" ");
Serial.print(heaterInterval);
Serial.println(" ");
}
else
{
digitalWrite(HeaterPin, LOW);
}
}
else if (temp < Setpoint) { //close to Setpoint
heaterInterval = (WindowSize - 450); //reduce power even futher to stabilse on setpoint
if (currentMillis - previousHeaterMillis >= heaterInterval)
{
previousHeaterMillis = currentMillis;
Serial.print(WindowSize);
Serial.print(" ");
Serial.println(heaterInterval);
digitalWrite(HeaterPin, HIGH);
}
else
{
digitalWrite(HeaterPin, LOW);
}
}
if (millis() - previousSerialMillis >= 1000)
{
unsigned long currentTime = (millis() / 1000);
Serial.print(currentTime);
Serial.print(" ");
Serial.println(temp);
// Serial.println(" *C");
lcd.setCursor(0, 1);
lcd.print("Temp "); lcd.print(temp); lcd.print(" "); lcd.print((char)223); lcd.print("C");
Serial.print(" ");
previousSerialMillis += 1000;
}
}