EcoRenovator  

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


Blog 60+ Home Energy Saving Tips Recent Posts


 
 
Thread Tools Display Modes
Prev Previous Post   Next Post Next
Old 02-18-15, 04:45 PM   #1
buffalobillpatrick
Master EcoRenovator
 
Join Date: Mar 2014
Location: Florissant, Colorado
Posts: 599
Thanks: 814
Thanked 59 Times in 55 Posts
Default Arduino Subcooling code

Subcooling only code:

Code:
/********************************************************
 *
 * ARDUINO R290 Calculate Subcooling
 *
 * Note: REQUIRED SENSOR
 *       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
 *
 *     , if RAW_ADC is in bounds:
 *     , convert Raw_ADC to PSI
 *     , calc_R290_Saturated_Temp
 *     , read Subcooling_Temp_sensor (analog NTC thermistor)
 *     , calc Subcooling
 *
 *     , if RAW_ADC is out of bounds, Hang Forever
 *
 * Repeat Void loop
 *
 *
 * Change History: 
 * 02/18/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 ADC_Low_Limit        102.0    //ADC of .5v
#define ADC_Hi_Limit         921.0    //ADC of 4.5v
#define PSI_min                0.0
#define PSI_max              300.0

 
float Raw_ADC, Hi_Side_PSI, Subcooling_T, Subcooling, Saturated_Temp;

int Y;


void setup(void)       //Start Setup
  {
        
  pinMode (Subcooling_Temp_sensor_pin,      INPUT);
  pinMode (Hi_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("R290_SUBCOOL_3"));
  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 = 921;}


  //Raw_ADC Bounds check
  if ((Raw_ADC >= ADC_Low_Limit) && (Raw_ADC <= ADC_Hi_Limit))
  {
  // in bounds, convert Raw_ADC to PSI
  
  Hi_Side_PSI = mapfloat(Raw_ADC, ADC_Low_Limit, ADC_Hi_Limit, PSI_min, PSI_max); 
  
  lcd.clear();
  lcd.home (); // go home
  lcd.print(F("SUBCOL_PSI="));
  lcd.print(Hi_Side_PSI);  
  delay(10000);  
    
  Saturated_Temp = calc_R290_Saturated_Temp(Hi_Side_PSI); 

  lcd.clear();
  lcd.home (); // go home
  lcd.print(F("SAT_T="));
  lcd.print(Saturated_Temp);  
  lcd.print(F("*F"));
  delay(10000);
 
    
//read Subcooling Temp sensor
  Subcooling_T = (Read_10K_NTC (Subcooling_Temp_sensor_pin)); 
  
if(DEBUG){ Subcooling_T = 150;}
      
  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 if in bounds
 
  
  else         //ADC 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
  }     
 
  
}  //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 calc_R290_Saturated_Temp(float psi)
{ 
//MMF Model: y=(a*b+c*x^d)/(b+x^d)
//Coefficient Data:
float a = -6.63511955666E+001;
float b =  6.30623048298E+001;
float c = 7.72874234743E+002;
float d = 5.32503085812E-001;
float p;

  p = pow(psi,d);

  return (((a * b) + (c * p)) / (b + p ));
}




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-19-15 at 08:11 PM.. Reason: improved function: calc_R290_Saturated_Temp
buffalobillpatrick is offline   Reply With Quote
 



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 12:13 PM.


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