Tonight I was playing with the PID-library and it works nicely.
I heat a pot of water with an immersion heater controlled by the arduino through a solid state relay.
I get the temperature input from an LM35.
For the moment I print a temperature reading to the serial monitor each time the loop runs, and that is an awful lot of readings!
How do I call my Serial.println(tempC);
every ten seconds or once a minute while the main loop is running and taking care of the temperature regulation?
EDIT: I have a hunch that it must be something about using the millis() function.
..... maybe I should just go to bed and re-read "blink without delay" tomorrow?
The entire loop is here, just like the example in the library:
(Pin 13 is lit to indicate when the SSR is on)
#include <PID_v1.h>
#define RelayPin 6
//Define Variables we'll be connecting to
double Setpoint, Input, Output;
//Specify the links and initial tuning parameters
PID myPID(&Input, &Output, &Setpoint,2,5,1, DIRECT);
// For the temperature:
float tempC;
float reading;
int tempPin = 0;
const float korr = 0.01; // Just in case there was an offset
int WindowSize = 1000; // 5000 in example
unsigned long windowStartTime;
void setup()
{
pinMode(RelayPin, OUTPUT);
pinMode(13, OUTPUT);
analogReference(INTERNAL); // for the temperature
Serial.begin(9600); // serial comm
windowStartTime = millis();
//initialize the variables we're linked to
Setpoint = 50;
//tell the PID to range between 0 and the full window size
myPID.SetOutputLimits(0, WindowSize);
//turn the PID on
myPID.SetMode(AUTOMATIC);
}
// and now the loop
void loop()
{
reading = analogRead(tempPin);
tempC = reading / 9.31;
Serial.println(tempC);
Input = tempC;
myPID.Compute();
/************************************************
* turn the output pin on/off based on pid output
************************************************/
if(millis() - windowStartTime>WindowSize)
{ //time to shift the Relay Window
windowStartTime += WindowSize;
}
if(Output < millis() - windowStartTime)
{digitalWrite(RelayPin,LOW);
digitalWrite(13,LOW);
}
else
{digitalWrite(RelayPin,HIGH);
digitalWrite(13,HIGH);
}
}
Thanks for the good vibrations that made me think and read!
A few lines and the principle from "Blink without delay" did the trick.
(messy code, but it works.... will clean it up later)
#include <PID_v1.h>
#define RelayPin 6
//Define Variables we'll be connecting to
double Setpoint, Input, Output;
//Specify the links and initial tuning parameters
PID myPID(&Input, &Output, &Setpoint,2,5,1, DIRECT);
// For the temperature:
float tempC;
float reading;
int tempPin = 0;
const float korr = 0.01; // korr trækkes fra sensors værdi
long previousMillis = 0; // will store last time of write
long interval = 1000; // interval at which to write
int WindowSize = 1000; // var 5000
unsigned long windowStartTime;
void setup()
{
pinMode(RelayPin, OUTPUT);
pinMode(13, OUTPUT);
analogReference(INTERNAL); // til temperaturmåling
Serial.begin(9600); // se hvad temperaturen er målt til
windowStartTime = millis();
//initialize the variables we're linked to
Setpoint = 50;
//tell the PID to range between 0 and the full window size
myPID.SetOutputLimits(0, WindowSize);
//turn the PID on
myPID.SetMode(AUTOMATIC);
}
// and now the loop
void loop()
{
reading = analogRead(tempPin);
tempC = reading / 9.31;
// Serial.println(tempC);
unsigned long currentMillis = millis();
if(currentMillis - previousMillis > interval)
{
previousMillis = currentMillis;
Serial.println(tempC);
}
Input = tempC;
myPID.Compute();
/************************************************
* turn the output pin on/off based on pid output
************************************************/
if(millis() - windowStartTime>WindowSize)
{ //time to shift the Relay Window
windowStartTime += WindowSize;
}
if(Output < millis() - windowStartTime)
{digitalWrite(RelayPin,LOW);
digitalWrite(13,LOW);
}
else
{digitalWrite(RelayPin,HIGH);
digitalWrite(13,HIGH);
}
}