View Single Post
Old 01-03-16, 02:19 PM   #15
Acuario
Apprentice EcoRenovator
 
Join Date: May 2011
Location: Tortosa, Spain
Posts: 221
Thanks: 2
Thanked 81 Times in 46 Posts
Default

2. Main code file HeatpumpController.ino
/*
ROCA heat pump pins:
1 - Live
2 - Neutral (Common)
3 - Earth
4 - Valve
5 -
6 - Fan HIGH
7 - Fan LOW
8 -

Sensors:
#1 - pipe sensor (bottom of evaporator)
#5 - Environment

*/
#define DEBUG
#include <DallasTemperature.h>
#include <NilRTOS.h>
#include <Arduino.h>
#include <avr/wdt.h>
#include <NilSerial.h>
#include <NilAnalog.h>

#include <Wire.h>

#include "HeatpumpController.h"
#include "BAC1000.h"

// Macro to redefine Serial as NilSerial to save RAM.
// Remove definition to use standard Arduino Serial.
#define Serial NilSerial
#define analogRead(pin) nilAnalogRead(pin)
//#define delay(ms) nilThdSleep(ms)


void setup(void) {
byte data[1];

//Disable watchdog while setting up everything
wdt_disable();

// Open serial communications
Serial.begin(115200);

setupEthernet(); // start the Ethernet connection and the server:
readTime(); //Get the time from the DS1307
setupRS485(); //Setup RS485 (BAC1000)

EEPROM_read_byte(DEFROSTTEMP, data); //Temperature to run defrost cycle
defTemp = data[0] - DEFROST_OFFSET;
if (defTemp > 10) {
defTemp = 2;
EEPROM_write_byte(DEFROSTTEMP, defTemp + DEFROST_OFFSET);
}

EEPROM_read_byte(DEFROSTTIME, data); //Defrost cycle time (minutes)
defTime = data[0];
if (defTime > 10) {
defTime = 2;
EEPROM_write_byte(DEFROSTTIME, defTime);
}

EEPROM_read_byte(DEFROSTMAXTEMP, data); //Defrost Maximum temperature (temperature to stop defrost, overrides timer)
defUpperTemp = data[0];
if (defUpperTemp > 20) {
defUpperTemp = 10;
EEPROM_write_byte(DEFROSTMAXTEMP, defUpperTemp);
}

EEPROM_read_byte(TIMEBETWEENDEFROST, data); //Minimum time between defrost cycles
timeBetweenDefrost = data[0];
if ((timeBetweenDefrost > 60) || (timeBetweenDefrost < 15)) {
timeBetweenDefrost = 30;
EEPROM_write_byte(TIMEBETWEENDEFROST, timeBetweenDefrost);
}

EEPROM_read_byte(DESIREDROOMTEMP, data); //Desired room temperature
desiredRoomTemp = data[0];
if ((desiredRoomTemp > 35) || (desiredRoomTemp < 10)) {
desiredRoomTemp = 21;
EEPROM_write_byte(DESIREDROOMTEMP, desiredRoomTemp);
}

EEPROM_read_byte(MAXWATERTEMP, data); //Max water temperature
maxWaterTemp = data[0];
if ((maxWaterTemp > 35) || (maxWaterTemp < 10)) {
maxWaterTemp = 21;
EEPROM_write_byte(MAXWATERTEMP, maxWaterTemp);
}

EEPROM_read_byte(HYSTERISIS, data); //Hysterisis
hysterisis = data[0];
if ((hysterisis > 15) || (hysterisis < 2)) {
hysterisis = 5;
EEPROM_write_byte(HYSTERISIS, hysterisis);
}

EEPROM_read_byte(LASTSYSTEMSTATE, data); //Last system state (on/off)
operatingState = data[0];

//If the system was on then start the circulating pump before waiting for everything else
if (operatingState == TRUE) {
setRelay(PUMP, ON);
}
sendBAC1000Command(POWERONOFF, 0, 1, (operatingState << 4), 0, 0, 0);

EEPROM_read_byte(LASTSYSTEMMODE, data); //Last system operating mode (heat/cool)
operatingMode = data[0];
if (operatingMode > 1) {
operatingMode = 1;
EEPROM_write_byte(LASTSYSTEMMODE, operatingMode);
}

DEBUG_PRINTLN(F("STARTUP - STARTUP - STARTUP"));
debugStateOutput();
DEBUG_PRINTLN(F("END STARTUP - END STARTUP"));

//For testing defrost
//defrostUpperTemperature = 40;
//defrostFlag = TRUE;

//Set BAC1000 time and then read its settings so we can synchronise operations
sendBAC1000Command(SETTIME, 0, 1, tm.Second, tm.Minute, tm.Hour, 1);
do {
delay(2000);
sendBAC1000Command(READALL, 0, 1, 0, 0, 0, 0);
} while (BACRead == FALSE);

//Set outputs to off before enabling pinMode so relays don't turn on at startup
setRelay(PUMP, OFF);
setRelay(VALVE, OFF);
setRelay(FANLOW, OFF);
setRelay(FANHIGH, OFF);
setRelay(COMPRESSOR, OFF);
pinMode(PUMP, OUTPUT); // sets the digital pin as output
pinMode(VALVE, OUTPUT); // sets the digital pin as output
pinMode(FANLOW, OUTPUT); // sets the digital pin as output
pinMode(FANHIGH, OUTPUT); // sets the digital pin as output
pinMode(COMPRESSOR, OUTPUT); // sets the digital pin as output

wdt_enable(WDTO_8S); //Start watchdog timer - watchdog reset is in oled code as no delays
nilSysBegin(); // Start Nil RTOS.
rtosStarted = TRUE; //Flag the RTOS has started (needed for change from delay to nilDelay...)
}

void loop(void) {
//int keyValue = 0;

//keyValue = readKeys();
//if (keyValue == 1) {
// lcd_page = lcd_page++ >= LCD_PAGES ? 0 : lcd_page; //Cycle the lcd page count
//}
}

//Main running loop
NIL_THREAD(threadMain, arg) {
unsigned long lastCompressorRun;
char buf[10];

while (TRUE) {
debugStateOutput();

//See if the machine is on or off
if ((operatingMode == HEAT)&&(operatingState == TRUE)) {
//Operational modes for heating
DEBUG_PRINTLN(F("Mode:HEAT, operatingState:ON"));
if ((defrostFlag == FALSE)&&((flowTemp >= maxWaterTemp)||(bacRoomTemp >= desiredRoomTemp))) {
//If we have achieved the target temperature then turn everything but the circulating pump off
saveSystemState("Circulate");
setRelay(PUMP, ON);
setRelay(VALVE, OFF);
setRelay(FANLOW, OFF);
setRelay(FANHIGH, OFF);
setRelay(COMPRESSOR, OFF);
machineRunningState = FALSE;
}

//Machine startup
else if ((flowTemp <= maxWaterTemp - hysterisis)&&(machineRunningState == FALSE)){
//See if the compressor ran recently if so delay startup
lastCompressorRun = EEPROM_readlong(LASTCOMPRUN);
//DEBUG_PRINTST("Last run=%lu\n", lastCompressorRun);
unsigned long currentTimeMs = makeTimeMilli(tm);
//DEBUG_PRINTST("Current=%lu\n", currentTimeMs);
setRelay(PUMP, ON);
if ((lastCompressorRun + COMPSTARTDELAY) < currentTimeMs) {
saveSystemState("Startup");
setRelay(FANLOW, ON);
setRelay(FANHIGH, ON);
setRelay(VALVE, ON);
nilThdSleepSeconds(5);
setRelay(COMPRESSOR, ON);
machineRunningState = TRUE;
}
else
{
saveSystemState("Wait for startup");
}
}

//Check to see if we need to do a defrost.
else if (tempEvaporator == defTemp) {
if(millis() - lastDefrost >= timeBetweenDefrost)
defrostFlag = TRUE;
}
else if (machineRunningState == TRUE)
{
saveSystemState("Running");
}
}

//Else if it is running turn everything off
else if(operatingState == FALSE)
{
saveSystemState("Off");
setRelay(FANLOW, OFF);
setRelay(FANHIGH, OFF);
setRelay(COMPRESSOR, OFF);
setRelay(VALVE, OFF);
setRelay(PUMP, OFF);
defrostFlag = FALSE;
machineRunningState = FALSE;
}

//If the compressor is running save the current time for startup delay
if (compStat == ON) {
EEPROM_writelong(LASTCOMPRUN, makeTimeMilli(tm));
}

// Sleep for 5S.
nilThdSleepSeconds(5);
}
}

//Debug out system status
void debugStateOutput(void) {
DEBUG_PRINTST("Operating mode=%s\n", mode[operatingMode]);
DEBUG_PRINTST("operatingState=%s\n", operatingState == TRUE ? sTrue : sFalse);
DEBUG_PRINTST("machineRunningState=%s\n", machineRunningState == TRUE ? sTrue : sFalse);
DEBUG_PRINTST("flowTemp=%d\n", flowTemp);
DEBUG_PRINTST("maxWaterTemp=%d\n", maxWaterTemp);
DEBUG_PRINTST("bacRoomTemp=%d\n", bacRoomTemp);
DEBUG_PRINTST("desiredRoomTemp=%d\n", desiredRoomTemp);
}

//Save string for system state and output the state on debugger
void saveSystemState(char *state)
{
sprintf(systemState, state);
DEBUG_PRINTLN(systemState);
}

// Turn on/off relays and preserve state flag
void setRelay(int relay, bool state)
{
switch (relay) {
case COMPRESSOR:
if (compStat != state) {
digitalWrite(COMPRESSOR, state);
compStat = state;
}
break;
case FANLOW:
if (fanLow != state) {
digitalWrite(FANLOW, state);
fanLow = state;
}
break;
case FANHIGH:
if (fanHigh != state) {
digitalWrite(FANHIGH, state);
fanHigh = state;
}
break;
case VALVE:
if (valve != state) {
digitalWrite(VALVE, state);
valve = state;
}
break;
case PUMP:
//DEBUG_PRINTST("Pump = %d, set = %d\n", pump, state);
if (pump != state) {
digitalWrite(PUMP, state);
pump = state;
}
break;
}
}

//Thread to control derfost cycle
NIL_THREAD(threadDefrost, arg) {
while (TRUE) {
const char defStepS[] = "Defrost step";

if (defrostFlag == TRUE) {
sprintf(systemState, "%s 1", defStepS);
DEBUG_PRINTLN(systemState);
defStep = 1;
defrostStartTime = millis();
setRelay(FANLOW, OFF);
setRelay(FANHIGH, OFF);
setRelay(COMPRESSOR, OFF);
nilThdSleepSeconds(10);
defStep = 2;
sprintf(systemState, "%s 2", defStepS);
setRelay(VALVE, OFF);
nilThdSleepSeconds(10);
defStep = 3;
sprintf(systemState, "%s 3", defStepS);
setRelay(COMPRESSOR, ON);

while (defrostFlag == TRUE) {
if (tempEvaporator >= defUpperTemp)
defrostFlag = FALSE; //Cancel defrost if we have reached the programmed upper temperature
defrostRunTime = millis() - defrostStartTime;
if(defrostRunTime >= (defTime * 60000))
defrostFlag = FALSE; //Cancel defrost if we have reached the timeout for the defrost cycle
nilThdSleepMilliseconds(500);
}
defStep = 4;
sprintf(systemState, "%s 4", defStepS);
setRelay(COMPRESSOR, OFF);
nilThdSleepSeconds(10);
defStep = 5;
sprintf(systemState, "%s 5", defStepS);
setRelay(FANHIGH, ON);
nilThdSleepSeconds(5);
defStep = 6;
sprintf(systemState, "%s 6", defStepS);
setRelay(VALVE, ON);
nilThdSleepSeconds(10);
setRelay(COMPRESSOR, ON);
defStep = 0;
defrostFlag = FALSE;
lastDefrost = millis(); //Save the last defrost end time
}
// Sleep for 30S.
nilThdSleepSeconds(30);
}
}
Acuario is offline   Reply With Quote