Guys, need some advice, especially as the person who was tutoring me is now no longer with us so i'm a little stuck.
Over the past year or so I've been developing a reptile environment controller using a Mega2560. The code may be very unstructured as I basically duplicated the single output section for the remaining 7 channels once we had the basic single channel working.
The code for the output stage should be self explanatory, but notes have been included. Basically if the temperature read from the DS18B20 is within a degree of the target temperature the pulse duration is adjusted each time the cycle loops round. If it is more than a degree it turns the pin low, if it less than degree its high. There are also some error checking to make the output low and sound a buzzer if the sensor can't be read, or the temperature is outside the safe range.
void newoutput1 () {
frequency=5000;
error1 = ((setpoint1+0.5)-temperature1); // Obtain the value for the difference between desired tempertaure and actual temperature
if (error1>1.0) // if the difference is more than a degree
dutyCycle1=1.0; // then set the value of the duty cycle (pulse) to 100%
else if (error1<0.0) // or if the value is negative and below zero
dutyCycle1=0.0; // then set the value of the duty cycle to 0%
else // or if the value is between 1.0 and 0.0
dutyCycle1=error1; // set the value of the duty cycle to match that value
if (error1 > 1.0) { // if the dutycycle value is 0
digitalWrite(output1, HIGH); // set output 1 high
var1A = 1; // and set var1A to 1
}
else {
digitalWrite(output1, LOW); // set output 1 low
var1A = 0; // and set var1A to 0 and continue through this routine
}
if (temperature1 == -127.00) // if aa misread or incorrect response from DS18B20 produces a value of -127.00
{
dutyCycle1=0; // set control to 0
digitalWrite(alarm, HIGH); // sound the buzzer to notify there is a problem
digitalWrite(output1, LOW); // turn off the heater
}
else if ((temperature1 >= AlarmHIGH1) || (temperature1 <= AlarmLOW1)) // if the read tempertaure is outside the high and low thresholds
{
dutyCycle1=0; // set control to zero
digitalWrite(alarm, HIGH); // and sound the buzzer to notify the user of a problem
digitalWrite(output1, LOW); // turn off power to heater
}
heatpulse1 = (millis() + (frequency * dutyCycle1)); // current millis() time + On time( freq*duty) in Milli seconds
do { // The DO / WHILE CONDITIONAL LOOP
if (heatpulse1 > millis() && var1A == 0 ) { // if Var1A is low, ie not running Full heating, then pulse ON, if needed.
digitalWrite(output1, HIGH); // if Var1A is High, full heating is ON , so - Skip
var1 = 1;
}
else if (var1A == 0) { // if Var1A is low, ie not running Full heating, then pulse can be turned OFF
digitalWrite(output1,LOW); // if Var1A is High full heating is ON, so - Skip
var1 = 0;
}
if (var1 == 0) { // TEST IF ALL THE PULSES HAVE FINISHED, WHEN THEY HAVE VAR5 BECOMES ZERO
var9 = 0;
}
else var9 = 1 ;
}
while ( var9 >0 ); // THE WHILE BOOL CONDITION IF VAR9 IS GREATER THAN 0 CONTINUE WITH THE LOOP
void loop();
}
The problem I'm experiencing is that when first booted it works fine. If the temperature exceeds the set point the monitoring LED goes out and remains off (and the same is for each of the eight outputs). But if left running for a few days, it then starts misbehaving, in that it never actually makes the output low if the temperature exceeds the set point, and the LED gives a very short but noticeable pulse.
As mentioned, the chap who was supporting me and helping me migrate form PICs and PicBASIC Pro is no longer here, so I'm a tad stuck as to why it does this.
My guess... is it something to do with millis timer that somehow isn't being reset and after so many days overflows ??
Comments welcome