(code continued because of maximum message length limit)
// function to calculate the trend of the current temperature vs the average of the temperatures
// over the last 60 minutes. If the Arduino has been on less than 60 minutes then a nice hourglass
// is displayed instead of the up/steady/down trend arrow.
// case 1 = fridge sensor
// case 2 = freezer sensor
void calcTrend(float prevAvg, float currAvg, int sensorNum) {
if (millis() < 3600000/timeFactor) {
lcd.setCursor(19,0);
lcd.write(charNA);
lcd.setCursor(19,2);
lcd.write(charNA);
} else {
//if (millis() - lastCalcTrendMillis > 3600000/timeFactor) { //calc trend every hour
switch (sensorNum) {
case 1:
sumAvgFridgeTemp = 0;
for (int i=0; i <= 11; i++) {
sumAvgFridgeTemp += storedFridgeTemp[i];
Serial.print("calcTrend() sumAvgFridgeTemp: ");
Serial.println(sumAvgFridgeTemp);
}
sumAvgFridgeTemp /= 12;
Serial.print("calcTrend() sumAvgFridgeTemp/12= ");
Serial.println(sumAvgFridgeTemp);
if (currAvg > (sumAvgFridgeTemp + trendDelta)) {
lcd.setCursor(19,0);
lcd.write(2);
return;
}
if ((currAvg <= (sumAvgFridgeTemp + trendDelta)) && ((currAvg >= sumAvgFridgeTemp - trendDelta))) {
lcd.setCursor(19,0);
lcd.write(3);
return;
}
if (currAvg < (sumAvgFridgeTemp - trendDelta)) {
lcd.setCursor(19,0);
lcd.write(4);
return;
}
case 2:
sumAvgFreezerTemp = 0;
for (int i=0; i <= 11; i++) {
sumAvgFreezerTemp += storedFreezerTemp[i];
Serial.print("calcTrend() sumAvgFreezerTemp: ");
Serial.println(sumAvgFreezerTemp);
}
sumAvgFreezerTemp /= 12;
Serial.print("calcTrend() sumAvgFreezerTemp/12= ");
Serial.println(sumAvgFreezerTemp);
if (currAvg > (sumAvgFreezerTemp + trendDelta)) {
lcd.setCursor(19,2);
lcd.write(2);
return;
}
if ((currAvg <= (sumAvgFreezerTemp + trendDelta)) && ((currAvg >= sumAvgFreezerTemp - trendDelta))) {
lcd.setCursor(19,2);
lcd.write(3);
return;
}
if (currAvg < (sumAvgFreezerTemp - trendDelta)) {
lcd.setCursor(19,2);
lcd.write(4);
return;
}
}
}
lastCalcTrendMillis = millis();
}
// function to check if an alarm needs to be raised. the function is also signaling if the alarm
// raised is the same type as in the previous loop or not. this is in turned used for the silence
// button interrupt result parsing. I want to keep the piezo quiet if the silence alarm button was
// pressed before and the alarm type hasn't changed, but I want the piezo to sound if the alarm
// has been silenced before but its type has changed (i.e. went from HIGH_TEMP to CRITICAL_TEMP or
// from HIGH_TEMP to NO_ALARM to LOW_TEMP.
// case 1 = fridge sensor
// case 2 = freezer sensor
int checkAlarm(float currAvg,int sensorNum) {
switch (sensorNum) {
case 1:
if (currAvg >= 0 && currAvg <= 3) {
lcd.setCursor(2,1);
lcd.print("LOW TEMP");
lcd.setCursor(0,1);
lcd.write(6); // sad smiley
currFridgeAlarm = LOW_TEMP;
if (currFridgeAlarm != prevFridgeAlarm) {
fridgeAlarmChanged = 1;
} else {
fridgeAlarmChanged = 0;
}
prevFridgeAlarm = currFridgeAlarm;
return currFridgeAlarm;
}
if (currAvg > 3 && currAvg <= 5) {
lcd.setCursor(2,1);
lcd.print("OK");
lcd.setCursor(0,1);
lcd.write(5); // happy smiley
currFridgeAlarm = NO_ALARM;
if (currFridgeAlarm != prevFridgeAlarm) {
fridgeAlarmChanged = 1;
} else {
fridgeAlarmChanged = 0;
}
prevFridgeAlarm = currFridgeAlarm;
return currFridgeAlarm;
}
if (currAvg > 5 && currAvg <= 10) {
lcd.setCursor(2,1);
lcd.print("HIGH TEMP");
lcd.setCursor(0,1);
lcd.write(6); // sad smiley
currFridgeAlarm = HIGH_TEMP;
if (currFridgeAlarm != prevFridgeAlarm) {
fridgeAlarmChanged = 1;
} else {
fridgeAlarmChanged = 0;
}
prevFridgeAlarm = currFridgeAlarm;
return currFridgeAlarm;
}
if (currAvg < 0 || currAvg > 10) {
lcd.setCursor(2,1);
lcd.print("CRITICAL TEMP");
lcd.setCursor(0,1);
lcd.write(7); // critical smiley
currFridgeAlarm = CRITICAL_TEMP;
if (currFridgeAlarm != prevFridgeAlarm) {
fridgeAlarmChanged = 1;
} else {
fridgeAlarmChanged = 0;
}
prevFridgeAlarm = currFridgeAlarm;
}
case 2:
if (currAvg >= -30 && currAvg <= -21) {
lcd.setCursor(2,1);
lcd.print("WARNING: low temp");
lcd.setCursor(0,1);
lcd.write(6); // sad smiley
currFreezerAlarm = LOW_TEMP;
if (currFreezerAlarm != prevFreezerAlarm) {
freezerAlarmChanged = 1;
} else {
freezerAlarmChanged = 0;
}
prevFreezerAlarm = currFreezerAlarm;
return currFreezerAlarm;
}
if (currAvg > -21 && currAvg <= -15) {
lcd.setCursor(2,3);
lcd.print("OK");
lcd.setCursor(0,3);
lcd.write(5); // happy smiley
currFreezerAlarm = NO_ALARM;
if (currFreezerAlarm != prevFreezerAlarm) {
freezerAlarmChanged = 1;
} else {
freezerAlarmChanged = 0;
}
prevFreezerAlarm = currFreezerAlarm;
return currFreezerAlarm;
}
if (currAvg > -15 && currAvg <= -5) {
lcd.setCursor(2,3);
lcd.print("WARNING: high temp");
lcd.setCursor(0,3);
lcd.write(6); // sad smiley
currFreezerAlarm = HIGH_TEMP;
if (currFreezerAlarm != prevFreezerAlarm) {
freezerAlarmChanged = 1;
} else {
freezerAlarmChanged = 0;
}
prevFreezerAlarm = currFreezerAlarm;
return currFreezerAlarm;
}
if (currAvg < -30 || currAvg > -5) {
lcd.setCursor(2,3);
lcd.print("CRITICAL TEMP");
lcd.setCursor(0,3);
lcd.write(7); // critical smiley
currFreezerAlarm = CRITICAL_TEMP;
if (currFreezerAlarm != prevFreezerAlarm) {
freezerAlarmChanged = 1;
} else {
freezerAlarmChanged = 0;
}
prevFreezerAlarm = currFreezerAlarm;
}
return currFreezerAlarm;
}
}
// quite straight forward
void silenceAlarm() {
alarmAck = 1;
}
// function to sound the alarm, depending on its type. also checks if the piezo has been silenced
// and flashes the backlight.
void soundAlarm() {
if (currFridgeAlarm == LOW_TEMP || currFreezerAlarm == LOW_TEMP) {
if (alarmAck == 0) {
analogWrite(piezoPin, 100);
fadeLCD(4,0);
delay(100);
analogWrite(piezoPin, 0);
fadeLCD(4,0);
delay(50);
analogWrite(piezoPin, 100);
fadeLCD(4,0);
delay(100);
analogWrite(piezoPin, 0);
fadeLCD(4,0);
}
if (alarmAck == 1) {
fadeLCD(4,0);
delay(100);
fadeLCD(4,0);
delay(50);
fadeLCD(4,0);
delay(100);
fadeLCD(4,0);
}
}
if (currFridgeAlarm == HIGH_TEMP || currFreezerAlarm == HIGH_TEMP) {
if (alarmAck == 0) {
analogWrite(piezoPin, 100);
fadeLCD(4,0);
delay(100);
analogWrite(piezoPin, 0);
fadeLCD(4,0);
}
if (alarmAck == 1) {
fadeLCD(4,0);
delay(100);
fadeLCD(4,0);
}
}
if (currFridgeAlarm == CRITICAL_TEMP || currFreezerAlarm == CRITICAL_TEMP) {
if (alarmAck == 0) {
analogWrite(piezoPin, 10);
fadeLCD(3,0);
delay(100);
analogWrite(piezoPin, 0);
fadeLCD(4,0);
delay(50);
analogWrite(piezoPin, 100);
fadeLCD(3,0);
delay(100);
analogWrite(piezoPin, 0);
fadeLCD(4,0);
delay(50);
analogWrite(piezoPin, 1000);
fadeLCD(3,0);
delay(100);
analogWrite(piezoPin, 0);
fadeLCD(4,0);
}
if (alarmAck == 1) {
fadeLCD(3,0);
delay(100);
fadeLCD(4,0);
delay(50);
fadeLCD(3,0);
delay(100);
fadeLCD(4,0);
delay(50);
fadeLCD(3,0);
delay(100);
fadeLCD(4,0);
}
}
}
// calculates the LM335 output in ºC
float lm335(int sensorPin) {
int analogVal = analogRead(sensorPin);
float temp;
temp = analogVal / 1024.0 * 4.87; // 4.87V is what I mesured on the +5V pin as I'm getting
temp = (temp * 100) - 273.15; // power via the USB port.
Serial.println(analogVal);
return temp;
}
Fritzing schematics (note I am using a 20x4 LCD but Fritzing only has 16x2 LCD):