09-11-14, 01:10 PM | #251 |
Master EcoRenovator
Join Date: Mar 2014
Location: Florissant, Colorado
Posts: 599
Thanks: 814
Thanked 59 Times in 55 Posts
|
A somewhat easier method where you choose your heat loss rate:
Code:
// Choose your House Heat loss Rate #define insulation_level_1.00 1.00 //VERY Poor insulation #define insulation_level_0.95 0.95 //A bit better insulation #define insulation_level_0.90 0.90 //A bit better insulation #define insulation_level_0.85 0.85 //A bit better insulation #define insulation_level_0.80 0.80 //A bit better insulation #define insulation_level_0.75 0.75 //A bit better insulation #define insulation_level_0.70 0.70 //A bit better insulation #define insulation_level_0.65 0.65 //A bit better insulation #define insulation_level_0.60 0.60 //A bit better insulation #define insulation_level_0.55 0.55 //A bit better insulation #define insulation_level_0.50 0.50 //A bit better insulation #define insulation_level_0.45 0.45 //A bit better insulation #define insulation_level_0.40 0.40 //A bit better insulation #define insulation_level_0.35 0.35 //A bit better insulation #define insulation_level_0.30 0.30 //A bit better insulation #define insulation_level_0.25 0.25 //A bit better insulation #define insulation_level_0.20 0.20 //A bit better insulation #define insulation_level_0.15 0.15 //A bit better insulation #define insulation_level_0.10 0.10 //Excellent insulation //OutDoor Reset parameters #define OUTDOOR_hi_control_temp 62.0 //OD Temp. that House don't require heat #define BUFFER_tank_lo_limit 85.0 //Minimum BT temp, find through testing #define BUFFER_tank_delta 5.0 // find through testing float ODR_ratio; int OUTDOOR_temp; int BUFFER_tank_temp; int BUFFER_tank_target_temp; void setup() { // Choose your House Heat loss Rate ODR_ratio = define insulation_level_0.45; } void loop() { // OUTDOOR_temp = (readSensor_F (OUTDOOR_sensor)); // Calculate Buffer Tank Target Temp based on ODR parameters BUFFER_tank_target_temp = ( BUFFER_tank_lo_limit + (( OUTDOOR_hi_control_temp - OUTDOOR_temp ) * ODR_ratio )); // BUFFER_tank_temp = (readSensor_F (BUFFER_tank_sensor)); //Test if BT needs to start heating if ( BUFFER_tank_temp < ( BUFFER_tank_target_temp - BUFFER_tank_delta )) { do { // run HP //BUFFER_tank_temp = (readSensor_F (BUFFER_tank_sensor)); } while ( BUFFER_tank_temp < BUFFER_tank_target_temp ); } } Last edited by buffalobillpatrick; 10-25-14 at 11:08 AM.. |
The Following User Says Thank You to buffalobillpatrick For This Useful Post: | AC_Hacker (09-11-14) |
09-11-14, 02:18 PM | #252 |
Supreme EcoRenovator
Join Date: Mar 2009
Location: Portland, OR
Posts: 4,004
Thanks: 303
Thanked 724 Times in 534 Posts
|
Thanks BBP,
Good clear explanation & code sample. -AC
__________________
I'm not an HVAC technician. In fact, I'm barely even a hacker... |
The Following User Says Thank You to AC_Hacker For This Useful Post: | buffalobillpatrick (09-11-14) |
09-12-14, 08:20 PM | #253 |
Master EcoRenovator
Join Date: Mar 2014
Location: Florissant, Colorado
Posts: 599
Thanks: 814
Thanked 59 Times in 55 Posts
|
In my code above the
// run HP comment in the do while loop is where your start & run heat pump code would be inserted |
10-11-14, 10:43 AM | #254 | |
Supreme EcoRenovator
|
cheap limit switches
Quote:
Common female flare sensors hook straight up to access valves and most have a built-in Schraeder valve depressor: binary (go/no-go) trinary (low/operate/high) Other common male flare sensors may or may not have built-in Schraeder valve: EDIT: For clarification, these sensors are for measuring refrigerant pressures, not water pressures. BBP has identified the appropriate fuel pressure sensors that can be bought in the lower pressure ranges the water loops operate within. Last edited by jeff5may; 12-28-14 at 09:36 PM.. |
|
The Following User Says Thank You to jeff5may For This Useful Post: | buffalobillpatrick (10-22-14) |
10-22-14, 07:39 PM | #255 |
Master EcoRenovator
Join Date: Mar 2014
Location: Florissant, Colorado
Posts: 599
Thanks: 814
Thanked 59 Times in 55 Posts
|
Here is my Latest HP Slave code 2_0
Implemented Pressure sensors to verify Pump flows Implemented economic Balance Point COP: Electricity NG vs 85% Boiler Implemented Estimated running COP based on: ESWT & ELWT see: http://www.climatemaster.com/downloads/RP881.pdf p19 graph for model TMW036 W/W It runs on my Arduino Uno Code:
/******************************************************** * * ARDUINO SLAVE HP Controller. * * The MASTER Heating System controller powers this ARDUINO * ON or OFF as Heat Pump is needed. * * This code controls 3 Relays and reads/displays 9x 10K NTC Thermisters * and 1x MQ-2 GAS sensor * * IN SETUP: * * STEP #1 * Tells HEAT_SYS_MASTER Arduino that SLAVE "IS NOT HUNG" via ALIVE_RLY_R1 * * STEP #2 * The NG vs Electric cost Balance Point is calculated using input pots * * STEP #3 * The Source & Load pump OFF output pressure is read. * * STEP #4 * The Source & Load pumps are started * * STEP #5 * The Source & Load pump ON output pressure is read again. * Good flow is verified by correct pressure increase * * STEP #6 * HP COP is estimated see http://www.climatemaster.com/downloads/RP881.pdf * p19 graph for model TMW036 W/W * * STEP #7 * If the Estimated COP is less than the Cost Balance Point * then the pumps are turned off & code hangs * until the MASTER powers OFF this SLAVE Arduino * This indicate to Master Controller that the NG Boiler should be used. * * STEP #8 * The Compressor is started * * End Setup * * * * In the Main Loop, 9x temperature sensors * are read & displayed, continuously * * Each time through the main loop * the Source & Load pump ON output pressure is read. * Good flow is verified by correct pressure * * Each time through the main loop * HP COP is estimated * If the Estimated COP is less than the Cost Balance Point * then the pumps are turned off & code hangs * until the MASTER powers OFF this SLAVE Arduino * This indicate to Master Controller that the NG Boiler should be used. * * Main Loop takes about 70 Sec * * In the custom_delay function, * The Source OUT water tempereature and the MQ-2 GAS Sensor are checked. * If either are out of range, then code turns off all relays, * & hangs until the MASTER powers OFF this SLAVE Arduino * * * * NG Mcf = 1,000 ft3 * Therm = 100,000 BTU = 29.3Kwh * $Therms = $Mcf / 10.25 * * Over the past several winters my average delivered NG $8.00/Mcf = $.78/Therm * & delivered Electricity rate about $.16 / Kwh * * Easy to use online Heat Cost calculator: * Electric Heat vs. Gas/Oil Heat Cost Calculator/Comparator * * My Cost of heat (per 100,000 BTU) * $.16 / Kwh Electricity = $4.69 * $.78 / Therm with 85% Efficiency NG boiler = $0.92 * * Convert to Balance point: 4.69 / .92 = 5.0978 COP * * Change History: * 07/30/14 Changed POT Heater over to hardware control & * implemented new sample averaging method. * 08/02/14 Added Custom_delay & MQ-2 GAS sensor * 10/22/14 Complete rewrite * ********************************************************/ #include <Wire.h> #include <LCD.h> #include <LiquidCrystal_I2C.h> #define I2C_ADDR 0x3F // <<----- Add your address here. Find it from I2C Scanner #define BACKLIGHT_PIN 3 //define LCD digital pins #define En_pin 2 #define Rw_pin 1 //can't use D0 Tx & D1 Rx #define Rs_pin 0 #define D4_pin 4 #define D5_pin 5 //can use 2 -> 12 below in code #define D6_pin 6 #define D7_pin 7 LiquidCrystal_I2C lcd(I2C_ADDR,En_pin,Rw_pin,Rs_pin,D4_pin,D5_pin,D6_pin,D7_pin); #define SDA A4 //RESERVE I2C for LCD #define SCL A5 #define mux_analog_in A0 //multiplexer to Arduino analog in pin #define MQ2_GAS_sensor A1 #define SRC_pump_pressure_sensor A2 #define LOAD_pump_pressure_sensor A3 // D0 = RX, D1 = TX, reserved // relays Digital output pins #define ALIVE_RLY_R1 4 // D4 Songle 10A //Split R1 & R2 into seperate groups //as songle relay coil = 90ma //each group can source 150 mA. max //group 1 ends with D4 //group 2 starts with D5 #define HP_RLY_R2 5 // D5 Pumps In & Out OPTO 480D15-12 15A #define HP_RLY_R3 6 // D6 Compressor CRYDOM H12D4850 50A //define Digital output pins for MUX D7 -> D11 // multiplexer address select lines (A/B/C/D) const byte mux_address_A = 7; const byte mux_address_B = 8; const byte mux_address_C = 9; const byte mux_address_D = 10; const byte mux_enable = 13; // multiplexer enable #define ALARM 11 // D11 PWM OUTPUT to Audible Alarm //analog signals into MUX, these are NOT analog pins on Arduino #define Kwh_cost_pot 0 #define Mcf_cost_pot 1 #define SOLAR_tank_sensor 7 #define COMP_DISCHARGE_sensor 8 #define COND_OUT_sensor 9 #define EVAP_IN_sensor 10 #define EVAP_OUT_sensor 11 #define SOURCE_IN_sensor 12 #define SOURCE_OUT_sensor 13 #define LOAD_IN_sensor 14 #define LOAD_OUT_sensor 15 #define Boiler_Eff .85 #define SRC_pump 2 #define LOAD_pump 3 #define MIN_PSI_DELTA 1 int HP_Source_IN_temp; int HP_Source_OUT_temp; int HP_Load_IN_temp; int HP_Load_OUT_temp; int SRC_pump_on_pressure; int SRC_pump_off_pressure; int LOAD_pump_on_pressure; int LOAD_pump_off_pressure; int SRC_Delta_PSI; int LOAD_Delta_PSI; int ESWT; int ELWT; unsigned long T1; unsigned long T2; unsigned long TT; int i; int Sensor_Data; float BP; float Estimate_COP; float Kwh_cost; float Mcf_cost; Last edited by buffalobillpatrick; 10-22-14 at 07:47 PM.. |
10-22-14, 07:40 PM | #256 |
Master EcoRenovator
Join Date: Mar 2014
Location: Florissant, Colorado
Posts: 599
Thanks: 814
Thanked 59 Times in 55 Posts
|
Part#2 Setup
Code:
void setup(void) //Start Setup { pinMode (mux_analog_in, INPUT); //MUX DATA INPUT pinMode (mux_address_A, OUTPUT); // multiplexer address select lines (A/B/C/D) pinMode (mux_address_B, OUTPUT); pinMode (mux_address_C, OUTPUT); pinMode (mux_address_D, OUTPUT); pinMode (mux_enable, OUTPUT); // multiplexer enable pinMode( ALARM, OUTPUT); //digital output to relays pinMode( ALIVE_RLY_R1, OUTPUT); //digital output to relays pinMode( HP_RLY_R2, OUTPUT); //digital output to relays pinMode( HP_RLY_R3, OUTPUT); //digital output to relays digitalWrite ( ALIVE_RLY_R1, HIGH); //OFF digitalWrite ( HP_RLY_R2, HIGH); //OFF digitalWrite ( HP_RLY_R3, HIGH); //OFF // Serial.begin(9600); // start serial communication // delay(10000); //time to enable monitor window // Serial.println(F("........Hello world!.......")); // delay(100); lcd.begin (16,2); // <<----- My LCD is 16x2 lcd.clear(); //Switch on the backlight lcd.setBacklightPin(BACKLIGHT_PIN,POSITIVE); lcd.setBacklight(HIGH); // (IRQ1 is on Digital Pin 3) Pin 3 going high (+) sets Interrupt 1 // This is Master signal to STOP HP Compressor, by denergizing R3 // with a short power cycle to Solar pump, which picks a relay // N/O point connects Arduino +5v to Digital Pin 3 // This allows the water pumps to continue after Compressor is off // After a delay the master will power off this Slave Arduino attachInterrupt(1, Stop_Compressor_ISR, RISING);// Attach Interrupt // never detach digitalWrite (ALIVE_RLY_R1, LOW); //ON lcd.clear(); lcd.home (); // go home lcd.print(F("ALIVE SIGNAL TO")); lcd.setCursor(0,1); lcd.print(F("MASTER, R1 ON")); delay(5000); // Warer pumps not started yet, so can't use custom delay lcd.clear(); lcd.home (); // go home lcd.print(F("HP_SLAVE_2_0")); delay(5000); // Water pumps not started yet, so can't use custom delay beep(50); beep(50); beep(50); delay(1000); //read the Kwh & Mcf cost input pots. //Pots don't work well close to end thus the need for center of range values Kwh_cost = (Read_10K_NTC (Kwh_cost_pot)); Kwh_cost = 160; //debug Mcf_cost = (Read_10K_NTC (Mcf_cost_pot)); Mcf_cost = 800; //debug Kwh_cost /= 1000.0; Mcf_cost /= 100.0; lcd.clear(); lcd.home (); // go home lcd.print(F("Kwh Cost = ")); lcd.print(Kwh_cost); lcd.setCursor(0,1); lcd.print(F("Mcf Cost = ")); lcd.print(Mcf_cost); delay(5000); //Balance Point Formula: BP = ((Kwh_cost) / ((Mcf_cost / 10.25) * (1.0 / Boiler_Eff)) * 29.3); //BP = ( .16 / (( 8.00 / 10.25) * (1 / .85)) * 29.3); lcd.clear(); lcd.home (); // go home lcd.print(F("BALANCECOP=")); lcd.print(BP); delay(5000); SRC_pump_off_pressure = read_pump_PSI (SRC_pump); SRC_pump_off_pressure = 5; //debug LOAD_pump_off_pressure = read_pump_PSI (LOAD_pump); LOAD_pump_off_pressure = 6; //debug lcd.clear(); lcd.home (); // go home lcd.print(F("SRC_OFF_PSI= ")); lcd.print(SRC_pump_off_pressure); lcd.setCursor(0,1); lcd.print(F("LOAD_OFF_PSI= ")); lcd.print(LOAD_pump_off_pressure); delay(5000); digitalWrite (HP_RLY_R2, LOW); //Power Pumps lcd.clear(); lcd.home (); // go home lcd.print(F("HP H2O PUMPS ON")); delay(10000); SRC_pump_on_pressure = read_pump_PSI (SRC_pump); SRC_pump_on_pressure = 10; //debug LOAD_pump_on_pressure = read_pump_PSI (LOAD_pump); LOAD_pump_on_pressure = 11; //debug lcd.clear(); lcd.home (); // go home lcd.print(F("SRC_ON_PSI= ")); lcd.print(SRC_pump_on_pressure); lcd.setCursor(0,1); lcd.print(F("LOAD_ON_PSI= ")); lcd.print(LOAD_pump_on_pressure); delay(5000); SRC_Delta_PSI = SRC_pump_on_pressure - SRC_pump_off_pressure; LOAD_Delta_PSI = LOAD_pump_on_pressure - LOAD_pump_off_pressure; if ((SRC_Delta_PSI < MIN_PSI_DELTA) or (LOAD_Delta_PSI < MIN_PSI_DELTA)) { STOP(); } // delay(120000); Estimate_COP = estimate_COP(); //Estimate COP See Function lcd.clear(); lcd.home (); // go home lcd.print(F("ESTIMATECOP=")); lcd.print(Estimate_COP); delay(5000); if(Estimate_COP < BP) { STOP(); } //Quit digitalWrite (HP_RLY_R3, LOW); //Power Compressor lcd.clear(); lcd.home (); // go home lcd.print(F("HP COMPRESSOR ON")); lcd.setCursor(0,1); lcd.print(F("END SETUP")); custom_delay(); //Delay 5 sec. & Checks Water SRC OUT // FOR BEING TOO COLD, RESETS RLYS & HANGS FOREVER IF SO } //end setup Last edited by buffalobillpatrick; 10-23-14 at 11:34 AM.. |
10-22-14, 07:42 PM | #257 |
Master EcoRenovator
Join Date: Mar 2014
Location: Florissant, Colorado
Posts: 599
Thanks: 814
Thanked 59 Times in 55 Posts
|
Part #3 Main Loop
Code:
void loop () { // T1 = millis(); Sensor_Data = (Read_10K_NTC (SOLAR_tank_sensor)); lcd.clear(); lcd.home (); // go home lcd.print(F("SOLAR TANK= ")); lcd.print(Sensor_Data); custom_delay(); //Delay 5 sec. & Checks Water SRC OUT Sensor_Data = (Read_10K_NTC (COMP_DISCHARGE_sensor)); lcd.clear(); lcd.home (); // go home lcd.print(F("COMP_DISCHAR=")); lcd.print(Sensor_Data); custom_delay(); //Delay 5 sec. & Checks Water SRC OUT Sensor_Data = (Read_10K_NTC (COND_OUT_sensor)); lcd.clear(); lcd.home (); // go home lcd.print(F("COND_OUT=")); lcd.print(Sensor_Data); custom_delay(); //Delay 5 sec. & Checks Water SRC OUT Sensor_Data = (Read_10K_NTC (EVAP_IN_sensor)); lcd.clear(); lcd.home (); // go home lcd.print(F("EVAP_IN=")); lcd.print(Sensor_Data); custom_delay(); //Delay 5 sec. & Checks Water SRC OUT Sensor_Data = (Read_10K_NTC (EVAP_OUT_sensor)); lcd.clear(); lcd.home (); // go home lcd.print(F("EVAP_OUT=")); lcd.print(Sensor_Data); custom_delay(); //Delay 5 sec. & Checks Water SRC OUT Sensor_Data = (Read_10K_NTC (SOURCE_IN_sensor)); lcd.clear(); lcd.home (); // go home lcd.print(F("SRC_IN=")); lcd.print(Sensor_Data); custom_delay(); //Delay 5 sec. & Checks Water SRC OUT Sensor_Data = (Read_10K_NTC (SOURCE_OUT_sensor)); lcd.clear(); lcd.home (); // go home lcd.print(F("SRC_OUT=")); lcd.print(Sensor_Data); custom_delay(); //Delay 5 sec. & Checks Water SRC OUT Sensor_Data = (Read_10K_NTC (LOAD_IN_sensor)); lcd.clear(); lcd.home (); // go home lcd.print(F("LOAD_IN=")); lcd.print(Sensor_Data); custom_delay(); //Delay 5 sec. & Checks Water SRC OUT Sensor_Data = (Read_10K_NTC (LOAD_OUT_sensor)); lcd.clear(); lcd.home (); // go home lcd.print(F("LOAD_OUT=")); lcd.print(Sensor_Data); custom_delay(); //Delay 5 sec. & Checks Water SRC OUT Estimate_COP = estimate_COP(); //Estimate COP see function lcd.clear(); lcd.home (); // go home lcd.print(F("ESTIMATECOP=")); lcd.print(Estimate_COP); delay(5000); if(Estimate_COP < BP) { STOP(); } //Quit if under Balance Point //Verify pump pressures SRC_pump_on_pressure = read_pump_PSI (SRC_pump); SRC_pump_on_pressure = 10; //debug LOAD_pump_on_pressure = read_pump_PSI (LOAD_pump); LOAD_pump_on_pressure = 11; //debug lcd.clear(); lcd.home (); // go home lcd.print(F("SRC_ON_PSI= ")); lcd.print(SRC_pump_on_pressure); lcd.setCursor(0,1); lcd.print(F("LOAD_ON_PSI= ")); lcd.print(LOAD_pump_on_pressure); delay(5000); SRC_Delta_PSI = SRC_pump_on_pressure - SRC_pump_off_pressure; LOAD_Delta_PSI = LOAD_pump_on_pressure - LOAD_pump_off_pressure; if ((SRC_Delta_PSI < MIN_PSI_DELTA) or (LOAD_Delta_PSI < MIN_PSI_DELTA)) { STOP(); } //Quit if under pressure /* T2 = millis(); TT = T2 - T1; lcd.clear(); lcd.home (); // go home lcd.print(TT); //about 69 sec. per loop custom_delay(); //Delay 5 sec. & Checks Water SRC OUT // FOR BEING TOO COLD, RESETS RLYS & HANGS FOREVER IF SO */ } //end forever loop |
10-22-14, 07:43 PM | #258 |
Master EcoRenovator
Join Date: Mar 2014
Location: Florissant, Colorado
Posts: 599
Thanks: 814
Thanked 59 Times in 55 Posts
|
Part #4 functions
Code:
// (IRQ1 is on Digital Pin 3) Pin 3 going high (+) sets Interrupt 1 // This is Master signal to STOP HP Compressor, by denergizing R3 // with a short power cycle to Solar pump, which picks a relay // N/O point connects Arduino +5v to Digital Pin 3 // Digital Pin 3 has a 10K pulldown resistor to Gnd. // This allows the water pumps to continue after Compressor is off // After a delay the master will power off this Slave Arduino // This would be a normal ending sequence for HP satisfying Load void Stop_Compressor_ISR() { digitalWrite (HP_RLY_R3, HIGH); //Compressor OFF } // COP estimation // http://www.climatemaster.com/downloads/RP881.pdf // p19 graph for model TMW036 W/W float estimate_COP (void) { int Dt; int ESWT; int ELWT; float COP; float DELTA; ESWT = (Read_10K_NTC (SOURCE_IN_sensor)); lcd.clear(); lcd.home (); // go home lcd.print(F("ESWT=")); lcd.print(ESWT); custom_delay(); //Delay 5 sec. & Checks Water SRC OUT ELWT = (Read_10K_NTC (LOAD_IN_sensor)); lcd.clear(); lcd.home (); // go home lcd.print(F("ELWT=")); lcd.print(ELWT); custom_delay(); //Delay 5 sec. & Checks Water SRC OUT Dt = ELWT - ESWT; if (ELWT <= 80) { Dt = map(Dt, 20, 60, 65, 38); } else if (ELWT <= 85) { Dt = map(Dt, 25, 65, 61, 36); } else if (ELWT <= 90) { Dt = map(Dt, 30, 70, 57, 33); } else if (ELWT <= 95) { Dt = map(Dt, 35, 75, 53, 30); } else if (ELWT <= 100) { Dt = map(Dt, 40, 80, 49, 28); } else if (ELWT <= 105) { Dt = map(Dt, 45, 85, 46, 26); } else if (ELWT <= 110) { Dt = map(Dt, 50, 90, 43, 25); } else if (ELWT <= 115) { Dt = map(Dt, 55, 95, 40, 23); } else if (ELWT <= 120) { Dt = map(Dt, 60, 100, 37, 22); } else if (ELWT <= 125) { Dt = map(Dt, 65, 105, 34, 21); } else {STOP();} COP = Dt / 10,0; return (COP); } int read_pump_PSI (int which_pump) { #define sample_cnt 23 //takes 254 MS int Sensor_Data; int I; float alpha = 0.9; // factor to tune float average = 0.0; for (I=0; I< sample_cnt; I++) { average = alpha * analogRead(which_pump) + (1-alpha) * average; delay(10); } Sensor_Data = average; //convert float to int for map // pressure transducer .5v = 0PSI & 4.5v = 30PSI Sensor_Data = map(Sensor_Data, 102, 921, 0, 30); return (Sensor_Data); } void custom_delay (void) //Delay 5 sec. & Checks Water SRC OUT & GAS { #define GAS_LIMIT 100 //TBD To Be Determined with testing #define SOURCE_OUT_LOW_LIMIT 15 //with 30% PG #define sample_cnt 23 //takes 254 MS int I; float alpha = 0.9; // factor to tune float average = 0.0; // T1 = millis(); delay(4513); for (I=0; I< sample_cnt; I++) { average = alpha * analogRead(MQ2_GAS_sensor) + (1-alpha) * average; delay(10); } //Test if GAS LIMIT EXCEEDED Sensor_Data = average; //convert float to int Sensor_Data = map(Sensor_Data, 0, 1023, 0, 100); /* lcd.clear(); lcd.home (); // go home lcd.print(F("GAS SENSOR=")); lcd.print(Sensor_Data); delay(10000); */ if (Sensor_Data > GAS_LIMIT) { lcd.clear(); lcd.home (); // go home lcd.print(F("GAS LIMIT MET")); lcd.setCursor(0,1); lcd.print(F("TurnOff all Rlys")); digitalWrite (HP_RLY_R3, HIGH); //Compressor OFF delay(120000); digitalWrite (HP_RLY_R2, HIGH); //Pumps OFF digitalWrite (ALIVE_RLY_R1, HIGH); //Alive OFF lcd.clear(); lcd.home (); // go home lcd.print(F("HANG FOREVER 1")); do{ beep(200);} while (I == I); //hang } //end if GAS LIMIT //Test if Source out is too cold to run HP if ((Read_10K_NTC (SOURCE_OUT_sensor) <= SOURCE_OUT_LOW_LIMIT)) { lcd.clear(); lcd.home (); // go home lcd.print(F("HP SRC OUT COLD")); lcd.setCursor(0,1); lcd.print(F("RESET ALL RELAYS")); delay(5000); digitalWrite (HP_RLY_R3, HIGH); //Compressor OFF delay(120000); digitalWrite (HP_RLY_R2, HIGH); //Pumps OFF digitalWrite (ALIVE_RLY_R1, HIGH); //Alive OFF do{I = I;} while (I == I); //hang } //end if SOURCE_OUT is too cold /* T2 = millis(); TT = T2 - T1; lcd.clear(); lcd.home (); // go home lcd.print(TT); // 5 sec delay(10000); */ } //end custom_delay function void beep(unsigned char delayms) { analogWrite(ALARM, 255); // Almost any value can be used except 0 // experiment to get the best tone delay(delayms); // wait for a delayms ms analogWrite(ALARM, 0); // 0 turns it off delay(delayms); // wait for a delayms ms } int Read_10K_NTC (const byte which_sensor) { #define sample_cnt 23 //takes 254 MS float alpha = 0.9; // factor to tune float average = 0.0; int I; float steinhart; // resistance at 25 degrees C #define THERMISTORNOMINAL 10000 // temp. for nominal resistance (almost always 25 C) #define TEMPERATURENOMINAL 25 // The beta coefficient of the thermistor (usually 3000-4000) #define BCOEFFICIENT 3892 // the value of the series resistor #define SERIESRESISTOR 10000 // T1 = millis(); digitalWrite (mux_enable, HIGH); //disable delay(10); // select correct MUX channel digitalWrite (mux_address_A, (which_sensor & 1) ? HIGH : LOW); digitalWrite (mux_address_B, (which_sensor & 2) ? HIGH : LOW); digitalWrite (mux_address_C, (which_sensor & 4) ? HIGH : LOW); digitalWrite (mux_address_D, (which_sensor & 8) ? HIGH : LOW); digitalWrite (mux_enable, LOW); //enable delay(10); for (I=0; I< sample_cnt; I++) { average = alpha * analogRead(mux_analog_in) + (1-alpha) * average; delay(10); } // convert the value to resistance average = 1023 / average - 1; average = SERIESRESISTOR / average; steinhart = average / THERMISTORNOMINAL; // (R/Ro) steinhart = log(steinhart); // ln(R/Ro) steinhart /= BCOEFFICIENT; // 1/B * ln(R/Ro) steinhart += 1.0 / (TEMPERATURENOMINAL + 273.15); // + (1/To) steinhart = 1.0 / steinhart; // Invert steinhart -= 273.15; // convert to C return (round(steinhart * 1.8) + 32); // round to whole number // & convert to F /* T2 = millis(); TT = T2 - T1; lcd.clear(); lcd.home (); // go home lcd.print(TT); // 5 sec delay(10000); */ } // end of Read_10K_NTC void STOP (void) { int I; lcd.clear(); lcd.home (); // go home lcd.print(F("STOP")); lcd.setCursor(0,1); lcd.print(F("RESET ALL RELAYS")); delay(5000); digitalWrite (HP_RLY_R3, HIGH); //Compressor OFF delay(120000); digitalWrite (HP_RLY_R2, HIGH); //Pumps OFF digitalWrite (ALIVE_RLY_R1, HIGH); //Alive OFF lcd.clear(); lcd.home (); // go home lcd.print(F("HANG FOREVER 2")); do{I = I;} while (I == I); //hang } //end STOP Last edited by buffalobillpatrick; 10-23-14 at 01:59 PM.. |
The Following User Says Thank You to buffalobillpatrick For This Useful Post: | AC_Hacker (10-23-14) |
10-23-14, 12:35 PM | #259 |
Supreme EcoRenovator
Join Date: Mar 2009
Location: Portland, OR
Posts: 4,004
Thanks: 303
Thanked 724 Times in 534 Posts
|
BBP,
Nice job. I noticed that you did an edit after you first posted this code. It could be useful to put some kind of revision statement in the header to simplify and clarify communication, so that we are literally 'on the same page'. (* NOTE: Never mind, I just saw your "Change History" section. *) It's interesting that you are using pots for NG vs Electric cost. I suppose that for simplicity and cost of implementation for this early unit, it makes perfect sense. Maybe once you get the whole beast working, and you are whiling away your snug winter months, you might be able to develop a routine that could reach out through the Internet and automatically gather that information for your Balance Point calculation. Code:
. . . #define MQ2_GAS_sensor A1 #define SRC_pump_pressure_sensor A2 #define LOAD_pump_pressure_sensor A3 . . . What pressure measuring devices have you settled on? I looked at the wrecking yard sensors (great idea) that jeff5may suggested, but I think that their range is way too high for flow verification. Great job! -AC
__________________
I'm not an HVAC technician. In fact, I'm barely even a hacker... |
The Following User Says Thank You to AC_Hacker For This Useful Post: | buffalobillpatrick (10-23-14) |
10-23-14, 01:54 PM | #260 |
Master EcoRenovator
Join Date: Mar 2014
Location: Florissant, Colorado
Posts: 599
Thanks: 814
Thanked 59 Times in 55 Posts
|
Thanks A/C
30PSI Pressure Transducer or Sender for Oil Fuel Diesel Gas Water Air | eBay Having trouble with ISR, When I force an Interrupt 1 by jumpering D3 to +5v Arduino hangs ? I tried detaching interrupt right away but still hangs? Possibly lcd.print don't work in ISR? Code:
// (IRQ1 is on Digital Pin 3) Pin 3 going high (+) sets Interrupt 1 // This is Master signal to STOP HP Compressor, by denergizing R3 // with a short power cycle to Solar pump, which picks a relay // N/O point connects Arduino +5v to Digital Pin 3 // Digital Pin 3 has a 10K pulldown resistor to Gnd. // This allows the water pumps to continue after Compressor is off // After a delay the master will power off this Slave Arduino // This would be a normal ending sequence for HP satisfying Load void Stop_Compressor_ISR() { int I; detachInterrupt(1); digitalWrite (HP_RLY_R3, HIGH); //Compressor OFF lcd.print(F("COMPRESSOR OFF")); delay(30000); digitalWrite (HP_RLY_R2, HIGH); //Pumps OFF digitalWrite (ALIVE_RLY_R1, HIGH); //Alive OFF lcd.clear(); lcd.home (); // go home lcd.print(F("HANG FOREVER")); do{I = I;} while (I == I); //hang } "There are a few final things to keep in mind when implementing interrupts. First, keep in mind that whatever you use your ISR for, it’s good practice to keep it short, because while the ISR is executing, it’s holding up the rest of your program. If you have lots of interrupts, this can slow things to a crawl. Also, by “the rest of your program”, we do mean everything: Arduino functions like millis() won’t increment, and delay() won’t work within an ISR. Next, if you want to modify any variables within your ISR, you’ll need to make them global variables and mark them as volatile to ensure that your ISR has proper access to them. For example, instead of globally declaring 1 int myInterruptVar; you would declare 1 volatile int myInterruptVar; Finally, interrupts are normally globally disabled inside of any ISR (this is why delay() and millis() don’t work). This means that if more interrupt events occur before your ISR has completed, your program won’t catch them. This is another reason to keep ISRs short." Last edited by buffalobillpatrick; 10-23-14 at 02:36 PM.. |
|
|