Well, I've gotten a little more brave, and a little more (very little) skill in my hands, so i decided to dive in.
Mission:
Thermostat that has predetermined set points, high and low
Limits adjusted by pots not easily accessible (later to be replaced by wireless communication reprogram)
Minimum time above/below set points before activating HVAC
Minimum time for HVAC to run, but run until setpoint is passed for minimum amount of time
Reporting of current, max set, min set, and whichever of the following are relevant:
Time till activate heat (starts counting on overtemp)
time till activate cool (starts counting on undertemp)
time hvac running (obvious)
time till hvac shutdown (starts counting when between limits if hvac is on)
Current state:
Reporting current temp by ds18b20
Reporting min/max sets from pots
sending info to 20x4 LCD by serial+TTL inverter(PITA)
Current problem: (NEED HELP)
can't get LED's to turn on/off to simulate heat or cool state
Learning needed:
Don't know where to start to do the counting down stuff.
Please accept my apology for sloppy code with unnecessary pieces and commented out stuff, bad formatting, etc. it DOES compile and run up to this point, (except the LED simulators)
I welcome any and all help. I am very much a beginner, cobble hack and duct-tape kinda person. I want to learn, but i kinda need some of it in crayon.
Thanks everyone for all the help, on this and all the other stuff I've gotten help for.
Code that has gotten me this far: (scrounged from around the net and stitched/taped/wired/glued together)
#include <OneWire.h>
// DS18S20 Temperature chip i/o
OneWire ds(10); // on pin 10
int heating = 7;
int cooling = 6;
void setup(void) {
// initialize inputs/outputs
// start serial port
Serial.begin(9600);
Serial.print(254, BYTE);
Serial.print(1, BYTE);
pinMode(heating, OUTPUT);
pinMode(cooling, OUTPUT);
}
void loop(void) {
byte i;
byte present = 0;
byte data[12];
byte addr[8];
int lowPin = 0; // select the input pin for the low limit potentiometer
int highPin = 1; // select the input pin for the high limit potentiometer
int HighByte, LowByte, TReading, SignBit, Tc_100, Whole, Fract, nowtemp, maxtemp, mintemp, heatontime, heatwaittime, coolwaittime, coolontime, heating, cooling;
maxtemp = analogRead(lowPin);
mintemp = analogRead(highPin);
//Standard read/report setup for Dallas 18B20
if ( !ds.search(addr)) {
// Serial.print("No more addresses.\n");
ds.reset_search();
return;
}
// Serial.print("R=");
for( i = 0; i < 8; i++) {
// Serial.print(addr[i], HEX);
// Serial.print(" ");
}
if ( OneWire::crc8( addr, 7) != addr[7]) {
Serial.print("CRC is not valid!\n");
return;
}
if ( addr[0] != 0x28) {
Serial.print("Device is not a DS18S20 family device.\n");
return;
}
ds.reset();
ds.select(addr);
ds.write(0x44,1); // start conversion, with parasite power on at the end
delay(1000); // maybe 750ms is enough, maybe not
// we might do a ds.depower() here, but the reset will take care of it.
present = ds.reset();
ds.select(addr);
ds.write(0xBE); // Read Scratchpad
// Serial.print("P=");
// Serial.print(present,HEX);
// Serial.print(" ");
for ( i = 0; i < 9; i++) { // we need 9 bytes
data[i] = ds.read();
// Serial.print(data[i], HEX);
// Serial.print(" ");
}
// Serial.print(" CRC=");
// Serial.print( OneWire::crc8( data, 8), HEX);
// Serial.println();
LowByte = data[0];
HighByte = data[1];
TReading = (HighByte << 8) + LowByte;
SignBit = TReading & 0x8000; // test most sig bit
if (SignBit) // negative
{
TReading = (TReading ^ 0xffff) + 1; // 2's comp
}
Tc_100 = (6 * TReading) + TReading / 4; // multiply by (100 * 0.0625) or 6.25
Whole = Tc_100 / 100; // separate off the whole and fractional portions
Fract = Tc_100 % 100;
//reporting done to LCD screen, 20x4
line1();
Serial.print("Temp Now= ");
nowtemp = Tc_100 / 100;
nowtemp = nowtemp*1.8+32;
Serial.print(nowtemp);
if (SignBit) // If its negative
{
Serial.print("-");
}
//Serial.print(Whole);
//Serial.print(".");
//if (Fract < 10)
//{
// Serial.print("0");
//}
//Serial.print(Fract);
// Serial.print("\n");
Serial.print(" degrees");
// end temp reporting
// display the thermostat limits. note not editable at the report panel, only in code. LCD is for convenience sake at the controller box.
//set temperature trigger points for household heating/cooling kick on
heatwaittime=300000; //time to wait after nowtemp < mintemp till heaton, if nowtemp remains < mintemp
coolwaittime=300000; //time to wait after nowtemp > maxtemp till coolon, if nowtemp remains > maxtemp
heatontime=300000; // min time to run heater.
coolontime=300000; // min time to run AC.
maxtemp = maxtemp / 80 + 70; // convert to degF and set to acceptable range
line3(); // report max limit set range
Serial.print("Max Temp= ");
Serial.print(maxtemp);
Serial.print(" degrees");
mintemp = mintemp / 80 + 60; // convert to degF and set to acceptable range
line4(); // report min limit set range
Serial.print("Min Temp= ");
Serial.print(mintemp);
Serial.print(" degrees");
// compare the temperature reported to the set points
// Notes on things to learn to do here:
// EVERYTHING :(
// Notes on visualized steps
// plain english description:
//when temp goes 1° below minimum and stays for 10 minutes, heater comes on, and must stay on for at least 10 minutes and until the temp stays above minimum for 10 minutes
//when temp goes 1° above maximum and stays for 10 minutes, AC comes on and must stay on for at least 10 minutes and until the temp stays above minimum for 10 minutes
//Display will show current temp, minimum and maximum setpoints, and either the time till activation of heat/cool ( "Heat begins in 5:00" )
//report the time remaining on the countdown till activating the heat/cool. when it is exhausted and the unit is running, Show how long the unit has been running.
//when the temp has held in the acceptable range for 10 minutes, display time to shutdown ( " 5:00 until AC Off " )
// relay activation section to turn on/off HVAC according to parameters.
{
if ( nowtemp > maxtemp );
digitalWrite(heating, HIGH);
}
{
if ( nowtemp < maxtemp );
digitalWrite(heating, LOW);
}
{
if (nowtemp < mintemp);
digitalWrite(cooling, HIGH);
}
{
if (nowtemp > mintemp);
digitalWrite(cooling, LOW);
}
//line4();
// Serial.print("Heat in: ");
// Serial.print(heatwaittime);
// Serial.print(heatontime);
// line4(); //report the time remaining on the countdowns till activating the AC unit for overtemp
// Serial.print("Cool in: ");
// Serial.print(coolwaittime);
// Serial.print(coolontime);
}
// LCD FUNCTIONS-- keep/edit the ones you need.
// clear the LCD
void clearLCD(){
Serial.print(254, BYTE);
Serial.print(1, BYTE);
}
// go to line 1 start
void line1() {
Serial.print(254, BYTE);
Serial.print(128, BYTE);
}
// go to line 2 start
void line2() {
Serial.print(254, BYTE);
Serial.print(192, BYTE);
}
// go to line 3 start
void line3() {
Serial.print(254, BYTE);
Serial.print(148, BYTE);
}
// go to line 4 start
void line4() {
Serial.print(254, BYTE);
Serial.print(212, BYTE);
}
// move the cursor to the home position
void cursorHome(){
Serial.print(254, BYTE);
Serial.print(2, BYTE);
}
// move the cursor to a specific place
// e.g.: cursorSet(3,2) sets the cursor to x = 3 and y = 2
void cursorSet(int xpos, int ypos){
Serial.print(254, BYTE);
Serial.print(71, BYTE);
Serial.print(xpos); //Column position
Serial.print(ypos); //Row position
}
// backspace and erase previous character
void backSpace() {
Serial.print(8, BYTE);
}
// move cursor left
void cursorLeft(){
Serial.print(254, BYTE);
Serial.print(76, BYTE);
}
// move cursor right
void cursorRight(){
Serial.print(254, BYTE);
Serial.print(77, BYTE);
}
// set LCD contrast
void setContrast(int contrast){
Serial.print(254, BYTE);
Serial.print(80, BYTE);
Serial.print(contrast);
}
// turn on backlight
void backlightOn(int minutes){
Serial.print(254, BYTE);
Serial.print(66, BYTE);
Serial.print(minutes); // use 0 minutes to turn the backlight on indefinitely
}
// turn off backlight
void backlightOff(){
Serial.print(254, BYTE);
Serial.print(70, BYTE);
}