Hi Mikal,
The min temp is actually OK - the grabs I've shown are when the program is displaying output every second, and the Min Temp is calculated over the past 60 seconds.
Well, in the hope that it helps, here's the code...
#include <EEPROM.h>
#include <Wire.h>
#include <math.h>
#include <DateTime.h>
int potPin = 0; // input read pin for LM35 is Analog Pin 0
float temperature = 0; // variable which will be calculated in process
long val=0; // variable to store the value coming from the sensor
#define TRIGGER_INACTIVE 0xffffffff // a special value that indicates that no trigger is active.
unsigned long endTrigger = TRIGGER_INACTIVE;
#define ThermistorPIN 0 // Analog Pin 0
double temp;
int MinTemp = 40; // setting a high initial value makes for easy comparison in the loop,
int MaxTemp = 0; // and vice versa for a low initial MaxTemp.
int WriteAddress = 0; // initial address for EEPROM writes.
int ReadAddress = 0;
byte value; // will be used
int incomingByte = 0; // for incoming serial data
int hour;
int minute;
int second;
int month;
int day_of_week;
int day;
int year;
char* dow[7] = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"};
double Thermistor(int RawADC) {
// Inputs ADC Value from Thermistor and outputs Temperature in Celsius
// requires: include <math.h>
// Utilizes the Steinhart-Hart Thermistor Equation:
// Temperature in Kelvin = 1 / {A + B[ln(R)] + C[ln(R)]^3}
// where A = 0.001129148, B = 0.000234125 and C = 8.76741E-08
long Resistance; double Temp; // Dual-Purpose variable to save space.
Resistance=((10240000/RawADC) - 10000); // Assuming a 10k Thermistor. Calculation is actually: Resistance = (1024/ADC)
Temp = log(Resistance); // Saving the Log(resistance) so not to calculate it 4 times later. // "Temp" means "Temporary" on this line.
Temp = 1 / (0.001129148 + (0.000234125 * Temp) + (0.0000000876741 * Temp * Temp * Temp)); // Now it means both "Temporary" and "Temperature"
Temp = Temp - 273.15; // Convert Kelvin to Celsius // Now it only means "Temperature"
return Temp; // Return the Temperature
}
void printDouble(double val, byte precision) {
// prints val with number of decimal places determine by precision
// precision is a number from 0 to 6 indicating the desired decimal places
// example: printDouble(3.1415, 2); // prints 3.14 (two decimal places)
Serial.print (int(val)); //prints the int part
if( precision > 0) {
Serial.print("."); // print the decimal point
unsigned long frac, mult = 1;
byte padding = precision -1;
while(precision--) mult *=10;
if(val >= 0) frac = (val - int(val)) * mult; else frac = (int(val) - val) * mult;
unsigned long frac1 = frac;
while(frac1 /= 10) padding--;
while(padding--) Serial.print("0");
Serial.print(frac,DEC) ;
}
}
void TakePhoto() {
int FanStatus = digitalRead(3);
digitalWrite(3,LOW); // first, switch off the fans
Serial.print(" Fans switched off - status stored as ");
if (FanStatus == 0) Serial.println("OFF");
else Serial.println("ON");
digitalWrite(9,HIGH); // then send power to the camera
Serial.println(" Power to Camera");
// delay(500); // time for current to get to camera - not sure if this is needed...
digitalWrite(6,HIGH); // trigger the solenoid for 100 msec
Serial.println(" Solenoid triggered");
delay(100);
digitalWrite(6,LOW);
delay(15000); // wait 15 seconds for the camera to take a photo then shutdown
digitalWrite(9,LOW);
Serial.println(" Camera power switched off");
digitalWrite(3,FanStatus); // return fans to initial status
Serial.print(" Fans returned to ");
if (FanStatus == 0) Serial.print("OFF");
else Serial.print("ON");
Serial.println(" status");
}
void setup()
{
pinMode(3,OUTPUT); // FANS control - YELLOW
digitalWrite(3,LOW);
pinMode(6,OUTPUT); // SOLENOID power control - WHITE
digitalWrite(6,LOW);
pinMode(9,OUTPUT); // CAMERA control - BLUE
digitalWrite(9,HIGH);
pinMode(13,OUTPUT);
Serial.begin(115200);
Wire.begin();
}
void loop() {
// Below required to reset the register address to 0.
Wire.beginTransmission(104); // transmit to device #104, the ds 1307
Wire.send(0x00);
Wire.endTransmission(); // stop transmitting
Wire.requestFrom(104, 7); // request 7 bytes from slave ds1307, we'll assume it'll send them all even though it doesn't have to
second = Wire.receive();
minute = Wire.receive();
hour = Wire.receive();
day_of_week=Wire.receive();
day = Wire.receive();
month = Wire.receive();
year = Wire.receive();
// Convert all the BCD values that might have "tens" to decimal.
hour=hour/16 * 10 + hour % 16;
minute=minute/16 * 10 + minute % 16;
second=second/16 * 10 + second % 16;
day=day/16 * 10 + day % 16;
month=month/16 * 10 + month % 16;
year=2000 + year/16 * 10 + year % 16;
// Change times below to desired photo times. Copy & paste to add more photos per day.
// NOTE: for some reason, 8's & 9's cause an error, so don't use them on their own below;
// 18 & 19 work fine, but 08 & 09 do not.
if (hour == 9) { if (minute == 00) { if (second == 00) { TakePhoto();}}}
if (hour == 10) { if (minute == 00) { if (second == 00) { TakePhoto();}}}
if (hour == 11) { if (minute == 00) { if (second == 00) { TakePhoto();}}}
if (hour == 12) { if (minute == 00) { if (second == 00) { TakePhoto();}}}
if (hour == 13) { if (minute == 00) { if (second == 00) { TakePhoto();}}}
if (hour == 14) { if (minute == 00) { if (second == 00) { TakePhoto();}}}
if (hour == 15) { if (minute == 00) { if (second == 00) { TakePhoto();}}}
if (hour == 16) { if (minute == 00) { if (second == 00) { TakePhoto();}}}
if (hour == 17) { if (minute == 00) { if (second == 00) { TakePhoto();}}}
if (hour == 18) { if (minute == 00) { if (second == 00) { TakePhoto();}}}
Serial.print(hour);
Serial.print(":");
if (minute < 10) { Serial.print("0"); }
Serial.print(minute);
Serial.print(":");
if (second < 10) { Serial.print("0"); }
Serial.print(second);
Serial.print(" on ");
Serial.print(dow[day_of_week]);
Serial.print(", ");
Serial.print(day);
Serial.print("/");
Serial.print(month);
Serial.print("/");
Serial.print(year);
int span = 20; int aRead = 0;
for (int i = 0; i < span; i++) { //loop to get average of 20 readings
aRead = aRead + analogRead(ThermistorPIN);
}
aRead = aRead / span;
temperature = Thermistor(aRead);
Serial.print(" - Current temperature is: "); printDouble(temperature,1); // display Celsius
Serial.print("; Max - "); printDouble(MaxTemp,1); // display current MaxTemp
Serial.print(", Min - "); printDouble(MinTemp,1); // display current MinTemp
Serial.println("");
if( temperature > 35 ){ // is the Temp above 35 degrees Celcius?
if( endTrigger == TRIGGER_INACTIVE){ // only proceed if no trigger is active.
// trigger the fans and store the time to turn off the LED
digitalWrite(3, HIGH);
Serial.println(" Threshold Temperature EXCEEDED, switching fans on.");
endTrigger = DateTime.now() + (1 * 60); // set trigger for 1 minute(s) from now
// note that DateTime.now() returns seconds since Arduino started
}
}
if( DateTime.now() >= endTrigger ){ // only process this if endTrigger has been set
if( temperature > 33 ){ // if temp has dropped below 33 degrees Celcius, turn fans off
Serial.println(" Temperature still above threshold, fans remaining on.");
endTrigger = DateTime.now() + (1 * 60);
} // or, if temp is still above threshold, leave fans on for another minute
else if( temperature <= 33 ) {Serial.println(" Temperature has dropped below threshold, fans switched OFF.");
digitalWrite(3,LOW);
endTrigger = TRIGGER_INACTIVE;
}
}
// Now need a loop to read the temperature in the box, work out a daily MinTemp & MaxTemp, and record to EEPROM memory.
// This needs to repeat every day.
if( temperature > MaxTemp) {MaxTemp = temperature;}
if( temperature < MinTemp) {MinTemp = temperature;}
// if (second == 0){
// if (hour == 23) { if (minute == 59) { if (second == 50) {}} // just before midnight to avoid possible date confusion
if (minute == 0){ if (second == 0){
EEPROM.write(WriteAddress,(day));
++WriteAddress;
EEPROM.write(WriteAddress,month);
++WriteAddress;
EEPROM.write(WriteAddress,(year-2000));
++WriteAddress;
EEPROM.write(WriteAddress,MaxTemp);
++WriteAddress;
Serial.println(" MaxTemp recorded");
MaxTemp = 0;
}
}
... code continued next post ...