View Single Post
Old 11-25-14, 10:38 PM   #298
jeff5may
Supreme EcoRenovator
 
Join Date: Jan 2010
Location: elizabethtown, ky, USA
Posts: 2,428
Thanks: 431
Thanked 619 Times in 517 Posts
Send a message via Yahoo to jeff5may
Default Here she comes

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.
jeff5may is offline   Reply With Quote