Rat_Patrol:
Needs refining yet, but thoughts?
yes if you actually drive the ON/OFF cycle of your furnace from the Arduino, then you can capture the time spent on and off right there.
I noticed you rightly implemented an hysteresis
if (sensors.getTempC(ambient) <= (set - .2))
to trigger the furnace if the temperature is 0.2° below the target temperature, but in the else you did not test against set
and so your hysteresis is not really working. The else should be an
else if (sensors.getTempC(ambient) >= set) {...
this way in the interval ]set - 0.2°, set[
you just don't do anything.
(and to not read the temperature twice in the if and the else, you could first read the temperature into a variable and use that variable in the if and in the else.
also instead of using delay() to pause the loop(), you could use the millis() technique to check the temperature only every x seconds so that your Arduino keeps running and being reactive if you want to add features over time.
Also, integers don't store decimal numbers, so this will just initialize set with 22const int set = 22.22;
I'm also unsure you are using the library correctly (based on the examples)
I would recommend you start from the WaitForConversion example and modify it to suit your needs.
that would become something like this
// based on https://github.com/milesburton/Arduino-Temperature-Control-Library/blob/99db3898322c55b5b52febf6468625763d2acc6a/examples/WaitForConversion2/WaitForConversion2.pde
#include <OneWire.h>
#include <DallasTemperature.h>
// Data wire is plugged into port 2 on the Arduino
#define ONE_WIRE_BUS 2
// Setup a oneWire instance to communicate with any OneWire devices (not just Maxim/Dallas temperature ICs)
OneWire oneWire(ONE_WIRE_BUS);
// Pass our oneWire reference to Dallas Temperature.
DallasTemperature sensors(&oneWire);
DeviceAddress tempDeviceAddress;
const int resolution = 12;
unsigned long lastTempRequest = 0;
unsigned long delayInMillis = 750.0 / (1 << (12 - resolution)); // according to the spec
float tempC = 0.0;
const byte heaterPin = 13;
const float targetTemp = 22.22;
unsigned long chronoMS, totalTimeMS;
//
// SETUP
//
void setup(void)
{
Serial.begin(115200);
pinMode(heaterPin, OUTPUT);
sensors.begin();
sensors.getAddress(tempDeviceAddress, 0);
sensors.setResolution(tempDeviceAddress, resolution);
sensors.setWaitForConversion(false);
sensors.requestTemperatures();
totalTimeMS = 0;
lastTempRequest = millis();
}
void loop(void)
{
if (millis() - lastTempRequest >= delayInMillis) { // waited long enough to get a temperature read??
tempC = sensors.getTempCByIndex(0);
// immediately after fetching the temperature we request a new sample in async mode
sensors.requestTemperatures();
if (tempC != DEVICE_DISCONNECTED_C) { // if the read worked
Serial.print(" Temperature: ");
Serial.println(tempC, resolution - 8); // display with variable number of decimal digits based on resolution
if (tempC <= (targetTemp - .2)) {
digitalWrite(heaterPin, HIGH);
chronoMS = millis(); // note the current time
} else if (tempC > targetTemp) {
digitalWrite(heaterPin, LOW);
totalTimeMS += millis() - chronoMS;
Serial.print("Minutes out of 3060 used is ");
Serial.println(totalTimeMS / (60000ul)); // 60000 ms in 1 minute
Serial.print("Room Temp Is ");
Serial.println((tempC * 9.0 / 5 + 32)); // why do you read the temp in °C if you are used to °F ?
}
}
lastTempRequest += delayInMillis;
}
// here you can do other stuff
}
In this code I dropped the use of the Chrono
class you had to just use the plain millis() function. I note the time when you turn on the furnace and then when the furnace is turned off, I calculate the difference between the time it is and when you activated it last and add that into a total time variable. This is a running count of the number of ms your furnace was ON.
As it seems you think in terms of °F instead of °C, you could use the function getTempFByIndex()
to directly get the temperature in Fahrenheit and of course adjust targetTemp accordingly