OK, since nobody is doing any interaction with the code I put up on github, I'll just post it in here. This rough alpha version is basically a wall thermostat with auto-change-over. There have been a few pieces chopped out of it that are giving me problems, but what is here will compile with the libraries off hacktronics and run like magic.
Come get some:
Code:
// include the library code:
#include <LiquidCrystal.h>
#include <OneWire.h>
#include <DallasTemperature.h>
// define pin configuration:
#define defrostSensor A2
#define lcdBacklightPin 10
#define reversingValve 11
#define indoorPump 12
#define compressor 3
OneWire ds(13); // Temperature sensors on pin 13
DallasTemperature sensors(&ds);
int x = 1;
// initialize the LCD library with the numbers of the interface pins
LiquidCrystal lcd(8, 9, 4, 5, 6, 7);
boolean fan = false, thermostat = false, heatingCall = false, coolingCall = false, compressorLockout = true ;
float temp_c, temp_f;
int y, heat_sp, cool_sp, defrost_t, settemp = 25;
int state = 0, right = 0, left = 0, up = 0, down = 0, last_st = 0, st = 0;
byte sel = 0, mode = 0;
unsigned long up_time_1 ,up_time_2, up_time, last_request, lastLockout;
double time_1, time_2, time;
void process_io();
void process_display();
void setup() {
// set up the LCD's number of columns and rows:
lcd.begin(16, 2);
sensors.begin();
pinMode( lcdBacklightPin, INPUT );
pinMode( defrostSensor, INPUT);
pinMode( reversingValve, OUTPUT );
pinMode( indoorPump, OUTPUT );
pinMode( compressor, OUTPUT );
last_request = millis();
digitalWrite(lcdBacklightPin, LOW); //Turn on the backlight
// Print a message to the LCD.
lcd.setCursor(0,0);
lcd.print("Control center");
lcd.setCursor(0,1);
lcd.print("Startup Delay");
delay(12000);
up_time_1 = millis();
time_1 = millis();
compressorLockout = false;
}
void process_io() {
if ((millis()-last_request) > 15000) {
get_temp();
last_request = millis();
}
switch(mode) {
case 0: //mode is off
heatingCall = false;
coolingCall = false;
lastLockout = millis();
break;
case 1: //mode is heat
digitalWrite(reversingValve,false);
if (temp_c < (settemp - 1))
heatingCall = true;
if (settemp < temp_c) {
heatingCall = false;
compressorLockout = true;
lastLockout = millis();
}
break;
case 2: //mode is cool
digitalWrite(reversingValve,true);
if (temp_c < (settemp + 1))
coolingCall = true;
if (settemp > temp_c) {
coolingCall = false;
compressorLockout = true;
lastLockout = millis();
}
break;
case 3: //mode is auto
if (abs(temp_c - settemp)>2) { //auto-changeover territory
if (temp_c < settemp){
digitalWrite(reversingValve, false); //changeover to heating
heatingCall = true;
}
else {
digitalWrite(reversingValve, true); // changeover to cooling
coolingCall = true;
}
}
if ((temp_c - settemp) > 1)
coolingCall = true;
if ((settemp - temp_c) > 1)
heatingCall = true;
if (abs(temp_c - settemp)<.05) {
heatingCall = false;
coolingCall = false;
compressorLockout = true;
lastLockout = millis();
}
break;
}
if (heatingCall || coolingCall && (millis() - lastLockout < 120000)&& compressorLockout) { //2 minute lockout
digitalWrite(compressor,true);
digitalWrite(indoorPump,true);
compressorLockout = false;
}
else {
digitalWrite(compressor, false);
digitalWrite(indoorPump,false);
}
}
void process_display() {
switch (right) {
case 0:
lcd.clear();
lcd.setCursor(0,0);
lcd.print("Current ");
lcd.print(temp_c);
if (up>0){
settemp=settemp+1;
up=0;
}
if (up<0) {
settemp=settemp-1;
up=0;
}
lcd.setCursor(0,1);
lcd.print("Setpnt ");
lcd.print(settemp);
break;
case 1:
lcd.clear();
lcd.setCursor(0,0);
lcd.print("Mode ^ ");
switch(up) {
case 0:
lcd.print("OFF v");
mode=0;
break;
case 1:
lcd.print("HEAT v");
mode=1;
break;
case 2:
lcd.print("COOL v");
mode=2;
break;
case 3:
lcd.print("AUTO v");
mode=3;
break;
case 4:
up=0;
break;
case -1:
up=3;
break;
}
lcd.setCursor(0,1);
lcd.print("Press select to set");
if(sel == 1){
mode=up;
sel = 0;
lcd.clear();
lcd.setCursor(0,0);
lcd.print("Mode set.");
lcd.setCursor(0,1);
lcd.print(temp_c);
lcd.print("C//");
lcd.print(temp_f);
lcd.print("F");
delay(3000);
}
break;
case 2:
lcd.clear();
lcd.setCursor(0,0);
lcd.print("Get up time");
lcd.setCursor(0,1);
lcd.print("Press select");
if(sel == 1){
get_up_time();
sel = 0;
lcd.clear();
lcd.setCursor(0,0);
lcd.print("Up time");
lcd.setCursor(0,1);
lcd.print(up_time);
lcd.print(" sec");
delay(3000);
}
break;
case 3:
lcd.clear();
lcd.setCursor(0,0);
lcd.print("RxBuffer up");
lcd.setCursor(0,1);
lcd.print("Press select");
if(sel == 1){
sel = 0;
lcd.setCursor(0,0);
lcd.print("VALUE ");
lcd.print(up);
}
break;
case 4:
lcd.clear();
lcd.setCursor(0,0);
lcd.print("Thermostat?");
lcd.setCursor(0,1);
if (thermostat) {
lcd.print("YES");
}
else {
lcd.print("NO");
}
if (up>0){
thermostat=true;
up=0;
}
if (up<0) {
thermostat=false;
up=0;
}
break;
}
}
void process_state(){
switch (state) {
case 1: //right
right = right + 1;
if(right > 4) {
right = 0;
}
break;
case 2: //up
up = up + 1;
break;
case 3: //down
up = up - 1;
break;
case 4: //left
right = right - 1;
if(right < 0) {
right = 4;
}
break;
case 5:
break;
}
}
void read_state(){
state = 0;
y = analogRead (0);
//lcd.setCursor(10,1);
if (y < 100) {
//lcd.print ("Right ");
state = 1;
}
else if (y < 200) {
//lcd.print ("Up ");
state = 2;
}
else if (y < 400){
//lcd.print ("Down ");
state = 3;
}
else if (y < 600){
//lcd.print ("Left ");
state = 4;
}
else if (y < 800){
//lcd.print ("Select");
state = 5;
sel = 1;
}
}
void get_up_time(){
up_time_2 = millis();
up_time = up_time_2 - up_time_1;
up_time = up_time/1000; //time in seconds
}
void get_temp() {
if ((millis() - last_request)>5000) {
sensors.requestTemperatures();
last_request = millis();
temp_c = (sensors.getTempCByIndex(0));
temp_f = (sensors.getTempFByIndex(0));
}
}
void loop() {
time_2 = millis();
last_st = state;
read_state();
st = state;
if(st != last_st){
process_state();
//delay(45);
time_1 = millis();
}
time = time_2 - time_1;
time = time/1000;
if(time <=10){
pinMode( lcdBacklightPin, INPUT); //deals with possible hardware bug, turns backlight on.
}
else{
pinMode( lcdBacklightPin, OUTPUT ); //deals with possible hardware bug, lets pin float, backlight shuts off via shield pullup resistor.
right = 0;
up = 0;
}
delay(190);
process_display();
process_io();
This works with the LCD keypad shield I bought and a single 1-wire sensor as it sits. If you look at the code, there are probably a dozen loose ends which do nothing yet. Feel free to play with this and help me optimize what's here already.
I am dealing with a defrost function now that will work with an air-source unit. I'm doing n adaptive defrost algorithm based on a carrier board that has been around for a long time.