EcoRenovator  

Go Back   EcoRenovator > Improvements > Geothermal & Heat Pumps
Advanced Search
 


Blog 60+ Home Energy Saving Tips Recent Posts Search Today's Posts Mark Forums Read


Reply
 
Thread Tools Display Modes
Old 02-16-15, 09:52 AM   #11
Mikesolar
Master EcoRenovator
 
Mikesolar's Avatar
 
Join Date: Aug 2012
Location: Toronto
Posts: 958
Thanks: 40
Thanked 158 Times in 150 Posts
Default

here is a very interesting article about PID and using Pressure as well as temp

Attached Files
File Type: pdf EEV control with T and P.pdf (167.5 KB, 925 views)
Mikesolar is offline   Reply With Quote
Old 02-16-15, 02:24 PM   #12
NiHaoMike
Supreme EcoRenovator
 
NiHaoMike's Avatar
 
Join Date: Oct 2008
Location: Austin, TX
Posts: 1,154
Thanks: 14
Thanked 257 Times in 241 Posts
Default

Quote:
Originally Posted by buffalobillpatrick View Post
NiHaoMike, I don't see how that can work?

That seems to assume that the refrigerant temperature going into the evaporator is exactly the temperature that ALL of the evaporation takes place?

Could't there be some sensible warming of the refrigerant in the input area of evaporator prior to the latient boiling?

Especially with a lot of Subcooling prior to TXV.
Right after the TXV is the coldest the refrigerant will ever get. Entering the TXV is liquid at high pressure. Right after the TXV, the pressure is then low enough to cause the refrigerant to boil, dropping the temperature until it becomes equal to the boiling point at that pressure.
__________________
To my surprise, shortly after Naomi Wu gave me a bit of fame for making good use of solar power, Allie Moore got really jealous of her...
NiHaoMike is offline   Reply With Quote
The Following User Says Thank You to NiHaoMike For This Useful Post:
buffalobillpatrick (02-17-15)
Old 02-16-15, 02:36 PM   #13
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 Just a simple wave of the wand...

Quote:
Originally Posted by Mikesolar View Post
I wish i had the knowledge to write code but I don't.... yet. I am a programming luddite so it is really hard for me.

BBP, could you write one with 1 thermister instead of the pressure sensor and the thermister? If you want to replicate a standard TXV, one would be enough, no?

I looked on the Fujitsu circuit diagrams and do not see a pressure sensor anywhere, just numerous thermisters. As they are just plug in to the board, I don't know if one or two (or three) are used to control the EEV
Here's the catch: the OEM's run their units in test labs for hours and hours with pressure and temperature sensors wired into every part of everywhere and collect volumes of ultra-precise data logs. Even the "basic" capillary tube regulated models are treated this way. These plethora of sensors have no control over the events that transpire in the (torture) testing chamber: they are there as witnesses. The units are put through their paces with eyes on every variable that can be measured.

After a certain amount of testing has transpired, the log data is analyzed. What happens next depends on what type of control system the unit employs.

With a primarily mechanical control system, not a whole lot can be changed beyond tweaking offset adjustments or system component configuration. Due to the static, predictable nature of cap tubes and txv's, they are a "set-it-and-forget-it" type of device.

With the new, variable speed compressor and electronic expansion valve driven systems, this is no longer the case. The control board on these devices has been put through countless hours, months, and years of torture testing, both simulated and real, before a single production unit is released.

The mechanical and refrigeration engineers have had their way with the entire control system many times over. Just because there are only a few thermistors included in the final production model (to save money) does not mean that there aren't secret routines lurking in the abyss that is the control program. When a dog pees on the outdoor unit while it is running, some engineer somewhere has thought about it already and included a countermeasure. When you mismatch the indoor and outdoor units, the brain can tell. Many real-time variables are calculated in the background, based on the model developed in the torture lab. To the average user, the unit just runs like it should until it won't.

A txv uses pressure to regulate superheat. The suction line bulb is charged with very close to the same gas as the refrigeration circuit. The pressure in the bulb follows the saturated suction line pressure as the temperature changes. This pressure acts against one side of the diaphragm that opens or closes the needle valve. The other side of the diaphragm sees either valve discharge pressure (internally equalized) or suction pressure (externally equalized). The adjustment on the valve adds a little closing pressure to the valve to ensure some superheat exists. A subcooling valve works in much the same manner, only the bulb follows saturated condenser pressure and the diaphragm is externally equalized to condenser pressure.

Most of the new EEV units use indoor tube temp, outdoor tube temp, and compressor discharge tube temp thermistors at the least to figure out a partial picture of what's going on with the unit. A great many of them also have indoor and outdoor ambient thermometers also. The inverter units have a startup ritual they go through when the unit is powered up or a mode change occurs. This initialization routine tells the unit how to act. Who knows how much magic is packed in there?
jeff5may is offline   Reply With Quote
The Following User Says Thank You to jeff5may For This Useful Post:
buffalobillpatrick (02-17-15)
Old 02-17-15, 01:27 PM   #14
buffalobillpatrick
Master EcoRenovator
 
Join Date: Mar 2014
Location: Florissant, Colorado
Posts: 599
Thanks: 814
Thanked 59 Times in 55 Posts
Default

Added Subcooling

Hi Side Pressure Transducer:

1 8

Code:
/********************************************************
 *
 * ARDUINO R290 Calculate Subcooling & Suction Line Superheat.
 *
 * Note: REQUIRED SENSOR
 *       Suction Pressure Sensor:  0-150PSI with output of .5 -> 4.5vdc
 *       High Pressure Sensor:     0-300PSI with output of .5 -> 4.5vdc
 *
 * If in DEBUG mode, values are forced to test code function
 *
 * In Void Loop:
 *
 *     , read Hi Side Pressure Transducer
 *     , convert_raw_sensor_to_PSI 
 *     , if input parameter Raw_ADC is not in bounds (between 266 -> 921) 
 *     , hang forever1
 *
 *     , calc_R290_Saturated_Temp
 *     , if input parameter PSI is not in bounds (between 60 -> 300PSI)
 *     , hang forever2
 *
 *     , read Subcooling_Temp_sensor (analog NTC thermistor just prior to TXV)
 *
 *     , calc Suction Subcooling
 *
 *
 *     , read Lo_Side_Pressure_Transducer
 *     , convert_raw_sensor_to_PSI 
 *     , if input parameter Raw_ADC is not in bounds (between 266 -> 921) 
 *     , hang forever3
 *
 *     , calc_R290_Saturated_Temp
 *     , if input parameter PSI is not in bounds (between 30 -> 150PSI)
 *     , hang forever4
 *
 *     , read Suction Temp sensor (analog NTC thermistor)
 *
 *     , calc Suction Superheat
 *
 * Repeat Void loop
 *
 *
 * Change History: 
 * 02/17/15 Coded, BBP
 *
 *
 *
 ********************************************************/

#if defined(ARDUINO) && ARDUINO >= 100
  #include "Arduino.h"
  #else
  #include "WProgram.h"
  #endif

#include <Wire.h>
#include <LCD.h>
#include <LiquidCrystal_I2C.h>


#define DEBUG 1
//#define DEBUG 0


#define I2C_ADDR    0x3F // <<----- Add your address here.  Find it from I2C Scanner
                       //D3
#define BACKLIGHT_PIN     3  //define LCD digital pins
#define En_pin  2
#define Rw_pin  1             //can't use D0 & D1 Tx, Rx
#define Rs_pin  0
#define D4_pin  4
#define D5_pin  5              //can use D2 -> D12 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  

//  pinMode(A0, OUTPUT);     //This works acording 
                             //  http://arduino.cc/en/Tutorial/AnalogInputPins
//  digitalWrite(A0, HIGH);  //


#define Subcooling_Temp_sensor_pin        A0 
#define Hi_Side_Pressure_Transducer_pin   A1
#define Suct_Temp_sensor_pin              A2 
#define Lo_Side_Pressure_Transducer_pin   A3
 
float  Raw_ADC, Hi_Side_PSI, Subcooling_T, Subcooling;
float  Suct_PSI, Suct_T, Saturated_Temp, Suct_Superheat;

int Y;

int Which_Sensor;
#define Sensor_150   1
#define Sensor_300   2
 

void setup(void)       //Start Setup
  {
        
  pinMode (Subcooling_Temp_sensor_pin,      INPUT);
  pinMode (Hi_Side_Pressure_Transducer_pin, INPUT);
  pinMode (Suct_Temp_sensor_pin,            INPUT);
  pinMode (Lo_Side_Pressure_Transducer_pin, INPUT); 
 
 
 // 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);


  lcd.clear();
  lcd.home (); // go home
  lcd.print(F("LP_SUPERH_SUBCOL"));
  delay(10000);


  if(DEBUG)
  {       
  lcd.clear();
  lcd.home (); // go home
  lcd.print(F("DEBUG = ON"));
  delay(10000);
  }
  else 
  {       
  lcd.clear();
  lcd.home (); // go home
  lcd.print(F("DEBUG = OFF"));
  delay(10000);
  }

  }    //end setup




  void loop ()
{ 
 
  Raw_ADC = analogRead(Hi_Side_Pressure_Transducer_pin);  //read Hi Side pressure
 
if(DEBUG){  Raw_ADC = 400;}

  Hi_Side_PSI =  convert_raw_sensor_to_PSI( Raw_ADC, Sensor_300);
 
  lcd.clear();
  lcd.home (); // go home
  lcd.print(F("SUBCOL_PSI="));
  lcd.print(Hi_Side_PSI);  
  delay(10000);  

 if (Hi_Side_PSI == -1)  //is Hi_Side_PSI out of bounds
  {
  lcd.clear();
  lcd.home (); // go home
  lcd.print(F("RAW_PSI_NG"));   
  lcd.setCursor(0,1);
  lcd.print(F("HANG_FOREVER_1"));   
  do{Y = Y;} while (Y == Y);  //hang forever
  }      
  
  else
  {  //else in bounds  
  Saturated_Temp = calc_R290_Saturated_Temp(Hi_Side_PSI, Sensor_300); 

  lcd.clear();
  lcd.home (); // go home
  lcd.print(F("SAT_T="));
  lcd.print(Saturated_Temp);  
  lcd.print(F("*F"));
  delay(10000);
  
  if (Saturated_Temp == -1)  //is Hi_Side_PSI out of bounds
  {
  lcd.clear();
  lcd.home (); // go home
  lcd.print(F("SUBCOOL_PSI_NG"));   
  lcd.setCursor(0,1);
  lcd.print(F("HANG_FOREVER_2"));   
  do{Y = Y;} while (Y == Y);  //hang forever
  }      
  
  else
  {
    
//read Subcooling Temp sensor
  Subcooling_T = (Read_10K_NTC (Subcooling_Temp_sensor_pin)); 
  
if(DEBUG){ Subcooling_T = 100;}
      
  lcd.clear();
  lcd.home (); // go home
  lcd.print(F("SUBCOL_T="));
  lcd.print(Subcooling_T);  
  lcd.print(F("*F"));
  delay(10000); 
    
  Subcooling = Subcooling_T - Saturated_Temp;  //calc Subcooling
  
  lcd.clear();
  lcd.home (); // go home
  lcd.print(F("SUBCOOL="));
  lcd.print(Subcooling);  
  lcd.print(F("*F"));
  delay(10000);
  }
  
  }  //end else in bounds
  
 
 
 //To be continued
buffalobillpatrick is offline   Reply With Quote
Old 02-17-15, 01:27 PM   #15
buffalobillpatrick
Master EcoRenovator
 
Join Date: Mar 2014
Location: Florissant, Colorado
Posts: 599
Thanks: 814
Thanked 59 Times in 55 Posts
Default

Code:
////////////////////////////////////////////////////////////  
 
 
   Raw_ADC = analogRead(Lo_Side_Pressure_Transducer_pin);//read Suction pressure
 
if(DEBUG){  Raw_ADC = 400;}

  Suct_PSI =  convert_raw_sensor_to_PSI( Raw_ADC, Sensor_150);
 
  lcd.clear();
  lcd.home (); // go home
  lcd.print(F("SUCT_PSI="));
  lcd.print(Suct_PSI);  
  delay(10000);  

 if (Suct_PSI == -1)  //is Suct_PSI out of bounds
  {
  lcd.clear();
  lcd.home (); // go home
  lcd.print(F("RAW_PSI_NG"));   
  lcd.setCursor(0,1);
  lcd.print(F("HANG_FOREVER_3"));   
  do{Y = Y;} while (Y == Y);  //hang forever
  }      
  
  else
  {  //else in bounds  
  Saturated_Temp = calc_R290_Saturated_Temp(Suct_PSI, Sensor_150); 

  lcd.clear();
  lcd.home (); // go home
  lcd.print(F("SAT_T="));
  lcd.print(Saturated_Temp);  
  lcd.print(F("*F"));
  delay(10000);
  
  if (Saturated_Temp == -1)  //is Suct_PSI out of bounds
  {
  lcd.clear();
  lcd.home (); // go home
  lcd.print(F("SUCT_PSI_NG"));   
  lcd.setCursor(0,1);
  lcd.print(F("HANG_FOREVER_4"));   
  do{Y = Y;} while (Y == Y);  //hang forever
  }      
  
  else
  { 

  Suct_T = (Read_10K_NTC (Suct_Temp_sensor_pin)); //read Suction Temp sensor
  
  
if(DEBUG){ Suct_T = 50;}
      
  lcd.clear();
  lcd.home (); // go home
  lcd.print(F("SUCT_T="));
  lcd.print(Suct_T);  
  lcd.print(F("*F"));
  delay(10000);
     
    
  Suct_Superheat = Suct_T - Saturated_Temp;  //calc Suction Superheat
  
  lcd.clear();
  lcd.home (); // go home
  lcd.print(F("SUPRHEAT="));
  lcd.print(Suct_Superheat);  
  lcd.print(F("*F"));
  delay(10000);
  }
  
  }  //end else in bounds
  
  
  
}  //end forever loop





  
float mapfloat(float x, float in_min, float in_max, float out_min, float out_max)
{
  return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
}



float  convert_raw_sensor_to_PSI(float Raw_ADC, int Which_sensor)
{
  //analogRead results     .5v = 102,  1.3v = 266,   4.5v = 921
  
#define Low_Limit                266.0    //ADC of 1.3v
#define Hi_Limit                 921.0    //ADC of 4.5v
#define PSI_150_min               30.0
#define PSI_300_min               60.0
#define PSI_150_max              150.0
#define PSI_300_max              300.0

float PSI, min, max;

 
  if ((Raw_ADC >= Low_Limit) && (Raw_ADC <= Hi_Limit)) //Raw_ADC Bounds check
  {
  // in bounds, continue
 
  if (Which_sensor == Sensor_150)
  {
  min = PSI_150_min; max = PSI_150_max;
  }  
  else  //else it's Sensor_300
  {
   min = PSI_300_min; max = PSI_300_max;
  }
   
   PSI = mapfloat(Raw_ADC, Low_Limit, Hi_Limit, min, max); 
 
   return (PSI);
  
  }  //end if in bounds
  
  else {return (-1);}       // error return, out of bounds  
  
}  //end of  convert_raw_sensor_to_PSI





float calc_R290_Saturated_Temp(float PSI, int Which_sensor)
{ 

//Array element [0]  contains Saturation_Temp *F for 30PSI,
//Array element [1]  contains Saturation_Temp *F for 40PSI,...................>
//Array element [27] contains Saturation_Temp *F for 300PSI,
//Array element [28] contains Saturation_Temp *F for 310PSI


float R290_Saturation_Temp[] = 
     {7.93, 18.80, 28.42, 36.91, 44.59, 51.63, 58.13, 64.21, 69.90, 75.27, 
      80.35, 85.18, 89.78, 94.19, 98.41, 102.50, 106.40, 110.20, 113.80, 
      117.30, 120.80, 124.10, 127.30, 130.40, 133.50, 136.50, 139.40, 142.20, 
      145.00};


float Val, Next_val, Span, Saturation_Temp, decimals, work, low, hi; 

int I;

  if (Which_sensor == Sensor_150){ low = 30.0; hi = 150.0; }
  else{ /*Sensor_300*/             low = 60.0; hi = 300.0; }
  
  if ((PSI >= low) && (PSI <= hi)) //Bounds check
  {
  // in bounds, continue
  
  //convert PSI to array index
  work = ((PSI - 30.0) / 10.0);
  
  I = work;                                //drop decimals to get array index

  decimals = work - I; //restore decimals for interpolation between array points  
  
  Val = R290_Saturation_Temp[I];           //get array value
  Next_val = R290_Saturation_Temp[I+1];    //get Next array value
  
  Span = Next_val - Val;                   //Calc Span

  Saturation_Temp = Val + (Span * decimals);//interpolate between array points

  return (Saturation_Temp);        

  }  //end if in bounds
  
  else {return (-1);}       // error return, out of bounds 

}  // end calc_R290_Saturated_Temp





int Read_10K_NTC (int which_sensor)
{   
  #define sample_cnt 30
  
  float alpha =   0.9;     // factor to tune
  float average = 0.0;
  float steinhart;
  
  int I;
 
// 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

  
  for (I=0; I< sample_cnt; I++) 
  {  
  average =  alpha * analogRead(which_sensor) + (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            
}  // end of Read_10K_NTC
buffalobillpatrick is offline   Reply With Quote
Old 02-17-15, 02:18 PM   #16
buffalobillpatrick
Master EcoRenovator
 
Join Date: Mar 2014
Location: Florissant, Colorado
Posts: 599
Thanks: 814
Thanked 59 Times in 55 Posts
Default

What do "All-ya-All" (Texas lingo) think of NiHaoMike's post #4, 7, & 12 regarding Superheat?

Thermistors are sure easier & cheaper than Pressure Transducers.
buffalobillpatrick is offline   Reply With Quote
Old 02-17-15, 06:30 PM   #17
Mikesolar
Master EcoRenovator
 
Mikesolar's Avatar
 
Join Date: Aug 2012
Location: Toronto
Posts: 958
Thanks: 40
Thanked 158 Times in 150 Posts
Default

Quote:
Originally Posted by jeff5may View Post
Here's the catch: ...............................packed in there?
I know all this Jeff, I do service the minisplits as well as install them, and I have built a number of 2 to 5 ton units (ground and air) and have worked with a couple of larger manufacturers and seen their test rigs, so I know what they go through to build and test them.

That said, there are more ways to build a HP than the traditional TXV or cap tube. I'm not going to measure SH with the one I want to build next, it is run with a subcooling valve which is only concerned with single phase liquid temp, not trying to keep a constant SH.

Theoretically, all that should be needed is one thermister on a liquid line and the proper PID to control it.
Mikesolar is offline   Reply With Quote
Old 02-17-15, 06:33 PM   #18
Mikesolar
Master EcoRenovator
 
Mikesolar's Avatar
 
Join Date: Aug 2012
Location: Toronto
Posts: 958
Thanks: 40
Thanked 158 Times in 150 Posts
Default

Quote:
Originally Posted by buffalobillpatrick View Post
What do "All-ya-All" (Texas lingo) think of NiHaoMike's post #4, 7, & 12 regarding Superheat?

Thermistors are sure easier & cheaper than Pressure Transducers.
I've looked at a couple obscure pages (googled EEV PID) which seem to indicate that if there is a pressure sensor in the mix, the error in valve movement can be reduced by at least 50%. Note the article I posted a few posts back.
Mikesolar is offline   Reply With Quote
Old 02-17-15, 06:42 PM   #19
Mikesolar
Master EcoRenovator
 
Mikesolar's Avatar
 
Join Date: Aug 2012
Location: Toronto
Posts: 958
Thanks: 40
Thanked 158 Times in 150 Posts
Default

BBP, I am a programming luddite, haha. I installed arduino and tried to hook up an UNO, downloaded a PID from the library and nothing worked. I have no real idea how to debug the system. Ohhh, give me a torch and brazing rod, damn it.
Mikesolar is offline   Reply With Quote
Old 02-17-15, 07:33 PM   #20
buffalobillpatrick
Master EcoRenovator
 
Join Date: Mar 2014
Location: Florissant, Colorado
Posts: 599
Thanks: 814
Thanked 59 Times in 55 Posts
Default

Mike here is some working PID code that I stole:

From Wikipedia: "A PID controller calculates an 'error' value as the difference between a measured [Input] and a desired setpoint. The controller attempts to minimize the error by adjusting [an Output]."

So, you tell the PID what to measure (the "Input",) Where you want that measurement to be (the "Setpoint",) and the variable to adjust that can make that happen (the "Output".) The PID then adjusts the output trying to make the input equal the setpoint.

For reference, in a car, the Input, Setpoint, and Output would be the speed, desired speed, and gas pedal angle respectively.




Code:
/********************************************************
 * Arduino PID Adaptive Tuning Example
 * One of the benefits of the PID library is that you can
 * change the tuning parameters at any time.  this can be
 * helpful if we want the controller to be agressive at some
 * times, and conservative at others.   in the example below
 * we set the controller to use Conservative Tuning Parameters
 * when we're near setpoint and more agressive Tuning
 * Parameters when we're farther away.
 ********************************************************/

#include <PID_v1.h>

//Define Variables we'll be connecting to
double Setpoint, Input, Output;

//Define the aggressive Tuning Parameters
double aggKp=4, aggKi=0.2, aggKd=1;

//Define the conservative Tuning Parameters
double consKp=1, consKi=0.05, consKd=0.25;

//Specify the links and initial tuning parameters
PID myPID(&Input, &Output, &Setpoint, consKp, consKi, consKd, DIRECT);

void setup()
{
//  Input = analogRead(0);

  Setpoint = 75;       // Speed, temperature, etc. etc. desired

  //turn the PID on
  myPID.SetMode(AUTOMATIC);
}

void loop()
{
  Input = analogRead(0); //Read current speed, temperature, etc. etc.

  double gap = abs(Setpoint-Input); //distance away from setpoint
  if(gap < 10)
  {  //we're close to setpoint, use conservative tuning parameters
    myPID.SetTunings(consKp, consKi, consKd);
  }
  else
  {
     //we're far from setpoint, use aggressive tuning parameters
     myPID.SetTunings(aggKp, aggKi, aggKd);
  }

  myPID.Compute();
  analogWrite(3,Output);  //Analog to GATE or BASE OF POWER TRANSISTOR
}                         //That controls the Gas pedal angle, 
                          // or, heater, etc. etc.

buffalobillpatrick is offline   Reply With Quote
Reply


Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT -5. The time now is 06:51 PM.


Powered by vBulletin® Version 3.8.11
Copyright ©2000 - 2024, vBulletin Solutions Inc.
Ad Management by RedTyger
Inactive Reminders By Icora Web Design