Hey,
Here's what I want to do.
I have a bucket of water I want to keep as cold as the water is when it comes out of the faucet. I could just leave the faucet open but that would be a waste.
So, I'm hooked on the main water line with a pipe going to a 12v NC on/off valve. This valve is controlled by the Arduino via a relay and, when opened, lets water flow in the bucket. The bucket overflows in a drain.
There is a thermistor (temp 2) in the pipe right at the outlet of the valve for fresh water temp, and another one in the bucket (temp 3) for room temperature temp.
I want the valve to open every 30 minutes (this is a test, I have to check the fluctuation of the water temperature over 24h) and let the water flow for 10 seconds to drain the pipe of it's room temperature water.
Then I take the fresh water temperature as a standard.
For the next 30 minutes if the temperature in the bucket gets more than 1 C warmer than the standard, the valve opens until the temperature in the bucket is less than 1C warmer than the standard.
After 30 minutes (or so) it starts over to reset the standard
here's the code, its a modification of the thermistor code I found here Sensor tutorials - Thermistor
// which analog pin to connect
#define THERMISTORPIN2 A2
#define THERMISTORPIN3 A3
// resistance at 25 degrees C
#define THERMISTORNOMINAL 10000
// 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 NUMSAMPLES2 5
#define NUMSAMPLES3 5
// The beta coefficient of the thermistor (usually 3000-4000)
#define BCOEFFICIENT 3950
// the value of the 'other' resistor
#define SERIESRESISTOR2 10000
#define SERIESRESISTOR3 10000
int samples2[NUMSAMPLES2];
int samples3[NUMSAMPLES3];
int ledPin2 = 2;
int ledPin3 = 3;
int ledPinRelay = 4;
long previousPurgeMillis = 0; // Purge reset (t0)
long previousFlowMillis = 0; // Flow reset (t0)
long previousCycleMillis = 0; // Cycle reset (t0)
long purgeInterval = 1000; // 10 seconds
long flowInterval = 10000; // 1 minute
long cycleInterval = 1800000; // half hour
unsigned long currentPurgeMillis = millis(); //for the purge
unsigned long currentFlowMillis = millis(); //for the every-minute-update
unsigned long currentCycleMillis = millis(); //for the half-hour-update
void setup(void) {
Serial.begin(9600);
analogReference(EXTERNAL);
pinMode (ledPin2, OUTPUT);
pinMode (ledPin3, OUTPUT);
pinMode (ledPinRelay, OUTPUT);
}
void loop(void) {
unsigned long currentCycleMillis = millis(); //for the half-hour-update
unsigned long currentFlowMillis = millis(); //for the every-minute-update
unsigned long currentPurgeMillis = millis();
uint8_t i, j;
float average2;
float average3;
// take N samples in a row, with a slight delay
for (i=0; i< NUMSAMPLES2; i++) {
samples2[i] = analogRead(THERMISTORPIN2);
delay(10); // Here are short delays, should I avoid them as well?
}
for (j=0; j< NUMSAMPLES3; j++) {
samples3[j] = analogRead(THERMISTORPIN3);
delay(10);
}
// average all the samples out
average2 = 0;
average3 = 0;
for (i=0; i< NUMSAMPLES2; i++) {
average2 += samples2[i];
}
for (j=0; j< NUMSAMPLES3; j++) {
average3 += samples3[j];
}
average2 /= NUMSAMPLES2;
average3 /= NUMSAMPLES3;
Serial.print("Average2 analog reading ");
Serial.println(average2);
Serial.print("Average3 analog reading ");
Serial.println(average3);
// convert the value to resistance
average2 = 1023 / average2 - 1;
average2 = SERIESRESISTOR2 / average2;
Serial.print("Thermistor resistance2 ");
Serial.println(average2);
average3 = 1023 / average3 - 1;
average3 = SERIESRESISTOR3 / average3;
Serial.print("Thermistor resistance3 ");
Serial.println(average3);
float steinhart2;
steinhart2 = average2 / THERMISTORNOMINAL; // (R/Ro)
steinhart2 = log(steinhart2); // ln(R/Ro)
steinhart2 /= BCOEFFICIENT; // 1/B * ln(R/Ro)
steinhart2 += 1.0 / (TEMPERATURENOMINAL + 273.15); // + (1/To)
steinhart2 = 1.0 / steinhart2; // Invert
steinhart2 -= 273.15; // convert to *C
if(steinhart2 > 27)
{
digitalWrite(ledPin2, HIGH);
}
else
{
digitalWrite(ledPin2, LOW);
}
Serial.print("Temperature2 ");
Serial.print(steinhart2);
Serial.println(" *C");
float steinhart3;
steinhart3 = average3 / THERMISTORNOMINAL; // (R/Ro)
steinhart3 = log(steinhart3); // ln(R/Ro)
steinhart3 /= BCOEFFICIENT; // 1/B * ln(R/Ro)
steinhart3 += 1.0 / (TEMPERATURENOMINAL + 273.15); // + (1/To)
steinhart3 = 1.0 / steinhart3; // Invert
steinhart3 -= 273.15; // convert to C
if(steinhart3 < 27)
{
digitalWrite(ledPin3, HIGH);
}
else
{
digitalWrite(ledPin3, LOW);
}
Serial.print("Temperature3 ");
Serial.print(steinhart3);
Serial.println(" *C");
int temp2 = steinhart2; //fresh water temp.
int temp3 = steinhart3; //room temp water.
if(currentCycleMillis - previousCycleMillis > cycleInterval) //Cycle = half_hour cycle
{
previousCycleMillis = currentCycleMillis;
digitalWrite(ledPinRelay, HIGH);
if(currentPurgeMillis - previousPurgeMillis > purgeInterval) //THIS IS WHERE THE PROBLEM LIES, I can't keep it on! If replaced with a delay()
{ // it kind of works but it's far from being elegant.
digitalWrite(ledPinRelay, LOW);
}
}
if(currentFlowMillis - previousFlowMillis > flowInterval) //Flow = check temp3 every minute, but ideally it would be continuous
{
previousFlowMillis = currentFlowMillis;
if(abs (steinhart3 - steinhart2) >= 1) //compare room temp water / fresh water temp, (is abs necessary since t3 will always be higher?)
{
digitalWrite(ledPinRelay, HIGH); //open valve if the temp diff. is more than 1 *Celcius
}
if(abs (steinhart3 - steinhart2) <= 1) //compare room temp water / fresh water temp, (is abs necessary since t3 will always be higher?)
{
digitalWrite(ledPinRelay, LOW); //close valve if the temp diff. is less than 1 *Celcius
}
}
delay(1000); //this delay is used to make serial.print usable (i think) should it also be millisied?
}
As you can also see, there are 3 other short delays, two at the beginning of the loop where a sampling is done to average the temperatures and another on at the very end to make the serial.print readable. Should I replace them with millis() as well? or are sort ones ok?