02-14-15, 04:37 PM | #1 |
Master EcoRenovator
Join Date: Mar 2014
Location: Florissant, Colorado
Posts: 599
Thanks: 814
Thanked 59 Times in 55 Posts
|
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.. |
|
|