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