View Single Post
Old 02-14-15, 04:37 PM   #1
buffalobillpatrick
Master EcoRenovator
 
Join Date: Mar 2014
Location: Florissant, Colorado
Posts: 599
Thanks: 814
Thanked 59 Times in 55 Posts
Default Arduino R290 Suction Line Superheat Calc.

Some Arduino code that calculates Suction Line Superheat for R290 (propane)

Saturation Temp / Pressure table:

HC-290 (PROPANE) PRESSURE - TEMPERATURE CHART

Must use a Pressure Sensor like this:
http://www.ebay.com/itm/271763798948...%3AMEBIDX%3AIT

Pressure must be between 30 -> 150PSI

Pressure Sensor & Temp sensor are placed close together on Suction Line.

Code:
/********************************************************
 *
 * ARDUINO R290 Calculate Suction Line Superheat.
 *
 * Note: REQUIRED SENSOR
 *       Suction Pressure Sensor:  0-150PSI with output of .5 -> 4.5vdc
 *
 * If in DEBUG mode, values are forced to test code function
 *
 * In Void Loop:
 *     , read Suction Temp sensor (analog NTC thermistor)
 *
 *     , read Suction PSI sensor
 *     , 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 Suction_PSI is not in bounds (between 30 -> 150PSI)
 *     , hang forever2
 *
 *     , calc Suction Superheat
 * Repeat
 *
 *
 * Change History: 
 * 02/14/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 Suct_Temp_sensor_pin      A0 
#define Suct_PSI_sensor_pin       A1
 
 
float  Raw_ADC, Suct_PSI, Suct_T, Saturated_Temp, Suct_Superheat;

int Y;



void setup(void)       //Start Setup
  {
        
  pinMode (Suct_Temp_sensor_pin,    INPUT);
  pinMode (Suct_PSI_sensor_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("R290_SUPERHEAT_1"));
  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 ()
{ 

  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);
  
 
   Raw_ADC = analogRead(Suct_PSI_sensor_pin);  //read Suction PSI sensor
 
if(DEBUG){  Raw_ADC = 400;}

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

 if (Suct_PSI == -1)  //Suct_PSI is 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(Suct_PSI); 

  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)  //Suct_PSI is out of bounds
  {
  lcd.clear();
  lcd.home (); // go home
  lcd.print(F("SUCT_PSI_NG"));   
  lcd.setCursor(0,1);
  lcd.print(F("HANG_FOREVER_2"));   
  do{Y = Y;} while (Y == Y);  //hang forever
  }      
  
  else
  {  
  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;
}



//input parameter Raw_ADC must indicate between 30-150 PSI (266-921)
float convert_raw_sensor_to_PSI(float Raw_ADC)
{
  //Pressure sensor output .5v = 0PSI, 1.3v = 30PSI, 4.5v = 150PSI
  //analogRead results     .5v = 102,  1.3v = 266,   4.5v = 921
  
#define PSI_0                    102.0    //ADC of .5v
#define PSI_30                   266.0    //ADC of 1.3v
#define PSI_150                  921.0    //ADC of 4.5v
#define PSI_max                  150.0

float PSI;

  if ((Raw_ADC >= PSI_30) && (Raw_ADC <= PSI_150)) //Bounds check
  {
  // in bounds, continue 
  
   PSI = mapfloat(Raw_ADC, PSI_30, PSI_150, 30.0, 150.0); 
 
   return (PSI);
  
  }  //end if in bounds
  
  else {return (-1);}       // error return, out of bounds  
  
}  //end of convert_raw_sensor_to_PSI




//input parameter Suction_PSI must be between 30-150 PSI
float Calc_R290_Saturated_Temp(float Suction_PSI)
{ 

#define Array_size            14

//Array element [0]  contains Saturation_Temp *F for 30PSI,
//Array element [1]  contains Saturation_Temp *F for 40PSI,...................>
//Array element [12] contains Saturation_Temp *F for 150PSI,
//Array element [13] contains Saturation_Temp *F for 160PSI

float R290_Saturation_Temp [Array_size] = {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};
                                
float Val, Next_val, Span, Saturation_Temp, decimals, work; 

int I;

  if ((Suction_PSI >= 30.0) && (Suction_PSI <= 150.0)) //Bounds check
  {
  // in bounds, continue
  
  //convert Suction_PSI to array index
  work = ((Suction_PSI - 30.0) / 10.0);
  
  I = work;                                //drop decimals to get array index
  
  decimals = work - I; //restore decimals to allow 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


Last edited by buffalobillpatrick; 02-14-15 at 07:39 PM..
buffalobillpatrick is offline   Reply With Quote