Hey guys,
Sorry I only pasted a snippet but I was posting from my phone and the full code wasn't exactly for public viewing (I was hoping to avoid the forums).
Koepel:
That is not the way to use a single shot timer with millis().
Maybe one of my examples will help.
We like to help, but as you noticed, you can make it easier for us.
No snippets, there is even a website for that : https://snippets-r-us.com/. The problem is often in the part that someone refuses to show us :o
I have even made up a "law" for that: "Fifty percent chance that the problem is in the section that was ignored from the beginning, because you thought that the problem could not be caused by that section".
The others have not asked enough questions
I also want to know which Arduino board you use 
I tried something similar to this originally but changed it because I thought it might of been the problem. I implemented your code and the coldRelay works once or twice but then will remain on.
All other functions work whilst the coldRelay is frozen.
I have commented out all the other functions in the loop and nothing changes.
I have tried using the relay with the BWOD example and it turns on and off so I have a hard time imagining its the wiring.
The main code below is with Koepel example implemented.
#include <SD.h>
// #include <RTClib.h>
#include <PID_v1.h>
#include <DallasTemperature.h>
double Setpoint, Input, Output;
int one_wire_bus = 5 ;
int hotRelay = 6;
int fanRelay = 7;
int coldRelay = 8;
int CS_pin = 10;
int setPoint = 22;
double consKp=500, consKi=0, consKd=0;
int windowSize = 10000;
long interval = 10000;
unsigned long windowStartTime;
unsigned long previousMillisH = 0;
unsigned long previousMillisF = 0;
unsigned long previousMillisS = 0;
bool enabled = false;
unsigned long previousHour = 0;
float currentFreezerTemp;
float currentHeaterTemp;
File data_file;
//RTC_DS1307 rtc;
PID myPID(&Input, &Output, &Setpoint, consKp, consKi, consKd, DIRECT);
OneWire oneWire(one_wire_bus);
DallasTemperature sensors(&oneWire);
void setup() {
initPins();
initSerial();
initSensors();
windowStartTime = millis ();
Setpoint = setPoint-1;
myPID.SetOutputLimits(0, windowSize);
myPID.SetMode(AUTOMATIC);
sensors.begin();
Input = currentHeaterTemp;
printSerial();
printData();
}
void loop() {
initSensors();
Input = currentHeaterTemp;
if (Input<(Setpoint-1));{
controlHeater();}
if (Input>(Setpoint+1)){
controlFreezer();
}
if (currentHeaterTemp != currentFreezerTemp){
digitalWrite (fanRelay, HIGH);}
else {digitalWrite (fanRelay, LOW);}
unsigned long currentS = millis();
if (currentS - previousMillisS >= 30000) {
previousMillisS = currentS;
printSerial();
printData();
}
}
void initPins(){
pinMode (fanRelay, OUTPUT);
pinMode(hotRelay, OUTPUT);
pinMode(coldRelay, OUTPUT);
pinMode(CS_pin, OUTPUT);
}
void initSerial(){
Serial.begin(9600);
Serial.print("Initializing SD card...");
if (!SD.begin(CS_pin)) {
Serial.println("Card failed, or not present");
while (1) ;
}
Serial.println("card initialized.");
data_file = SD.open("datalog.txt", FILE_WRITE);
if (! data_file) {
Serial.println("error opening datalog.txt");
while (1) ;
}
else data_file.close();
/* if (! rtc.begin()) {
Serial.println("Couldn't find RTC");
while (1)
}*/
}
void initSensors(){
sensors.requestTemperatures();
currentHeaterTemp = sensors.getTempCByIndex(0);
currentFreezerTemp= sensors.getTempCByIndex(1);
}
void controlHeater(){
myPID.SetTunings(consKp, consKi, consKd);
myPID.Compute();
unsigned long relayNow = millis();
if (relayNow - windowStartTime > windowSize){
windowStartTime += windowSize;
}
if (Output > relayNow - windowStartTime){
digitalWrite(hotRelay, HIGH);}
else {digitalWrite(hotRelay, LOW);}
unsigned long current = millis();
if (current - previousMillisH > interval) {
previousMillisH = current;}
}
void controlFreezer(){
unsigned long currentFreezer = millis();
if( digitalRead( coldRelay) == LOW) // low is active
{
digitalWrite( coldRelay, HIGH); // turn on led
previousMillisF = currentFreezer;
enabled = true; // turn on software timer
}
if( enabled) // software timer is active ?
{
if( currentFreezer - previousMillisF >= 6000)
{
digitalWrite( coldRelay, LOW); // turn off led
enabled = false; // stop software timer
}
}
}
void printSerial (){
// DateTime now = rtc.now();
/*Serial.print(now.hour(), DEC);
Serial.print(':');
Serial.print(now.minute(), DEC);
Serial.print(':');
Serial.print(now.second(), DEC);*/
Serial.print("\t");
Serial.print("hTem=");
Serial.print("\t");
Serial.print(currentHeaterTemp, 1);
Serial.print("\t");
Serial.print("ftem=");
Serial.print("\t");
Serial.print(currentFreezerTemp, 1);
Serial.print("\t");
Serial.print("o=");
Serial.print("\t");
Serial.print(Output / windowSize *100);
Serial.print("\t");
Serial.print("Set =");
Serial.print("\t");
Serial.println(Setpoint);
}
void printData(){
/* DateTime now = rtc.now();
unsigned long currentHour = now.minute();
if (currentHour != previousHour) {
previousHour = currentHour ;*/
data_file = SD.open("datalog.txt", FILE_WRITE);
if (data_file) {;
data_file.print(currentHeaterTemp);
data_file.print("\t");
data_file.print("airTemp = ");
data_file.print("\t");
data_file.print("freezeTemp=");
data_file.print("\t");
data_file.print(currentFreezerTemp);
data_file.print("output = ");
data_file.println(Output / windowSize*100);
data_file.close();
}
}
- I originally had a real time clock controlling the timing but got rid of it because of a new design but plan to use at a later time