Could someone please give me some help. I am 19 years old i don't have allot of programming experience and i think iv bitten off more than i can chew.
I have written a program that will be used to control a solenoid operated valve on a compressor. The valve controls the flow of liquid ammonia from the compressors condensers and the oil coolant chamber. leave the valve closed too long and the compressor will trip on high discharge pressure and leave the valve open to long and the compressors oil will overheat because there wont be any ammonia there to cool the oil. Based on a reading from 2 pressure transducers one measures the condenser and the other measures the oil temperature. unfortunately it is not as simple as telling the valve to close when the oil temperature reaches a certain point or when the discharge temperature reaches a point either. the only way to control the valve is by taking a reading of the oil temperature at 0 seconds then another reading some time after i.e. 5 seconds. If the temperature is increasing too quickly then we know that there is no more coolant left in the tank to cool the oil therefore we must close the valve to let the oil coolant tank fill back up again and bring the oil temperature back down. The valve also needs to close if the oil temperature reaches a certain point (65 degrees, although this might change so its set as a variable) even thought the temperature is not rising too quickly. When the valve closes a timer should start that will keep the valve closed regardless if the oil temperature has recovered or not.
That's all good, but here is where i have a problem the timer needs to be interrupted and the valve re-open if the discharge temperature(condenser temperature) reaches a set point. Could you help me with this. i know my code is a mess but i have done my best to clean it up and comment it appropriately.
What temperature sensors are you using? How precise are they?
Here is your sketch modified so it will at least compile.
//the only variables that should be adjusted. to change the value simply replace
//the numbers after the equals symbol to what they need to be.
//Take note of the values before you change them incase there is a mistake made.
//***********************************************************************//
const double maxO = 65.0; //maximum oil temperature before solenoid remains closed for set time
const double maxD = 38.5; //maximum discharge temperature
const double mIncrease = 0.25; //the maximum increase rate of the oil temperature before solenoid closes.
unsigned long time = 5; //the time between the 1st oil temp reading and the 2nd oil temp(seconds)
unsigned long timeClosed = 480000; //how long the solenoid once open will remain open (milliseconds)
unsigned long timerClosed = 480000; //how long the solenoid once open will remain open (milliseconds)
//***********************************************************************//
//DO NOT edit or change anything after this point.
//This program will NOT work if you do.
const int oTempPin = A1; // Analog pin used to read current oil temperature
int oValue = 0; //oil temp pin value. analogRead values go from 0 to 1023
double oTemp; //oil temperature
const int dTempPin = A2; //pin used to read current discharge temperature
int dValue = 0; //discharge temp pin value. analogRead values go from 0 to 1023
double dTemp; //discharge temperature
const int solenoidPin = A3; //pin used to open solenoid
int oil1; //1st timed reading of oil temperature (0s)
int oil2; //2nd timed reading of oil temperature (delay time set by "double time")
double increase; //=oil temp at time(milliseconds) divided by oil temp at 0seconds(degrees per second)
boolean solenoid = 0; //shows if the solenoid is closed or open;
unsigned long reset = 0;
void setup() {
Serial.begin(9600); //im not sure what this is needed for but i see it in 90% of the source code i look at
// pinMode(oTempPin, INPUT); //sets the pin used to moniter the oil temperature to an input (not needed for analog inputs)
// pinMode(dTempPin, INPUT); //sets the pin used to moniter the discharge temperature to an input
pinMode(solenoidPin, OUTPUT); //sets the solenoid open/close pin to an output
}
void loop() {
unsigned long timerOpen = millis(); //this variable is used to start a timer when the valve opens.
unsigned long timer = millis(); //this timer will be used to time the difference between the 1st oil temp (1oil) reading and the 2nd oil temp(2oil) reading
int i = 0; //i used this to stop my first reading of the oil temp from refreshing everytime loop() runs.
int j = 0; //the solenoid needs to open when the compressor is first started so i used this variable in an if statement below
oValue = analogRead(oTempPin); //read the analog value for oil temperature
oTemp = ((oValue*0.0049)); //i dont know yet what voltage == what temperature
if(i==0) {
oil1 = oTemp; //first reading of oil temp
}
i=1;
dValue = analogRead(dTempPin); //read the analog value for discharge temperature
dTemp = ((dValue*0.0049)); //i dont know yet what voltage == what temperature
if(j == 0 & oTemp < maxO) {
digitalWrite(solenoidPin,HIGH); //when the program first starts running open solenoid if the oil temperature is below the max oil temperature.
j++;
}
if(solenoid == 0 & timerClosed >= timeClosed) { //im not sure if i need to check for the solenoid being closed as well as checking the timer
digitalWrite(solenoidPin, HIGH); //open the solenoid
solenoid = 1;
timerClosed = 0; //resets the timer to 0 after the solenoid valve has been closed for the time set by the "timeClosed" variable.
}
if(timer >= time){
oil2 = oTemp; //setting "2oil" = the oil temperature so i have a second reading to work out
increase = oil2-oil1/(time/1000); //how much the oil temperature is increasing per second
i = 0; //sets i back to 0 so that "1oil" will be set again to the oil temperature
timer = reset; //resets timer so this if statment will set "2oil" when timer = time again
}
while(increase > mIncrease || oTemp > maxO) { //if the increase in oil temperature is > the max increase then close the solenoid.
digitalWrite(solenoidPin,LOW); //close solenoid
solenoid = 0;
}
delay(5); //im not sure if 5ms is long enough for the loop
}
the pressure transducer that will be used for reading the oil temp will be 0-40 bar and the transducer that will be used for the discharge temp will have to be 0-60 bar. And as for the accuracy. im not sure but i think it will be +/- 0.25%
Make different sketches that get each piece/concept working before having any serious thoughts about how they go together. What works may well be different than what you thought would work and that can change how it all fits, works and plays together well.
Work in steps and check compile often. Use Auto Format now and then, if your braces don't match up it will tell you. The -last- thing you want to do is throw up a pile of code and -then- run compile, you end up troubleshooting with many unknowns and their interactions and then what? You end up simplifying down to the stages you should have started with after going through more work. If you're stuck on the original overall structure, fitting the fixed pieces in "to save time" usually doesn't save time or fit well.
It's good to have an original plan but don't get too specific until you have the pieces. Always be ready to make changes and keep your eyes and mind open to discoveries along the way. Don't expect to be perfect, just keep getting better through practice and learn/adapt from everything that interests you.
I have no idea if there's some way to use this:
if(solenoid == 0 & timerClosed >= timeClosed)
but that's not how to make something happen on time.
The BlinkWithoutDelay Example (in 02. Digital) in your IDE shows how. The example does use longs for 2 of the time variables. They should be unsigned long but unless you're going to have intervals over 23 days long it isn't an issue.
What blinks a led can flipp a switch. What reads a pot reads analog. Do tutorials.
AwesomeGauge:
the pressure transducer that will be used for reading the oil temp will be 0-40 bar and the transducer that will be used for the discharge temp will have to be 0-60 bar. And as for the accuracy. im not sure but i think it will be +/- 0.25%
Pressure transducers measure pressure, not temperature. Which do you want to measure?
Yes pressure transducers measure pressure but that pressure corosponds to a temerature. Measuring in temp more convenient because there will be someone else changing the values on the first set of variables.
If you have a fixed volume and mole of gas, your pressure is proportional to temperature. Is this your case? I thought ammonia is changing quantity and liquid. Just wanted to be clear what's being discussed.
GoForSmoke:
That table seems pretty deterministic.
Yes, which bothers me. What condition is the ammonia in so that it exhibits this behavior between temperature and pressure? The document doesn't say, just numbers with no conditions. I guess it's when it is in a sealed can with no air. Otherwise if you keep the container open, pressure will always be 1 ATM. From what I gather, the OP has some way of moving ammonia so there might not be a sealed container. Need more information.
yes the ammonia is in an enclosed refrigeration system so the pressures on that table will always correspond to the temperature or it will be so close that the difference is irrelevant. all I will be doing is instead of converting the output voltage to the corresponding pressure, I will just convert it to the corresponding temperature. That will make the program more manageable considering the compressors plc outputs the temperature to an lcd.
AwesomeGauge:
yes the ammonia is in an enclosed refrigeration system so the pressures on that table will always correspond to the temperature or it will be so close that the difference is irrelevant. all I will be doing is instead of converting the output voltage to the corresponding pressure, I will just convert it to the corresponding temperature. That will make the program more manageable considering the compressors plc outputs the temperature to an lcd.
OK as stated above break this down into chunks and start monitoring the system - once that runs for a few time periods successfully then you can look at starting to control the system. I personally would also have a backup that measured the temperature to ensure your correlations are correct on an ongoing basis.
Have a look at the softtimer library - it is an easy to use implementation of millis that will ensure you do not use blocking code and get hungup at the wrong moment.
It would also be a good idea to incorporate some form of external data storage - either pumping it out an attached computer, or the internet or eeprom.
This will enable you to analyse how your program is performing and whether it is doing what you expect.
I have recently implemented the nearbus library on my project and have it pumping data over ethernet to a google spreadsheet which then performs all the averaging and data manipulation and representation for me
I am 19 years old i don't have allot of programming experience and i think iv bitten off more than i can chew.
I have written a program that will be used to control a solenoid operated valve on a compressor. The valve controls the flow of liquid ammonia from the compressors condensers and the oil coolant chamber.
(just as a warning)
It sounds to me as a serious application. Even a professional programmer should first build up extensive domain knowledge before building such an application.
How do you cover the legal aspects when the program/system fails?
I assume you make this for a company or is it for personal use?
the system I want to put will simply handle opening and closing a valve. the compressor has been installed incorrectly and this is the cheapest option. It is for professional use at my fathers company. if my system fails there is a plc in place on the compressor that takes care of everything. The compressor will simply shut down due to high oil temperature or high condenser temperature.
AwesomeGauge:
yes the ammonia is in an enclosed refrigeration system so the pressures on that table will always correspond to the temperature or it will be so close that the difference is irrelevant. all I will be doing is instead of converting the output voltage to the corresponding pressure, I will just convert it to the corresponding temperature. That will make the program more manageable considering the compressors plc outputs the temperature to an lcd.
Do you still not know what voltage corresponds to what temperature? Do you know the range fo voltages the pressure sensor will give for what range of pressures it will cover? I doubt that it is for the whole range of those tables.
If there's a nice equation, that would be best but be aware that you can put a lot of lookup data in a table in flash memory, 1024 floats only takes 4k bytes where UNO has 32k flash for code and data. Chances are that your code won't take half of that. Conversion can be as simple as reading a table location. That would be a bite in itself if you don't know how, chew it well before swallowing.
yeah I had the same thoughts as you for setting all 1024 values in the program. I havnt purchased pressure transducers yet but i can get ones that output 0-5volts and there are different ones for almost everything you could imagine. the pressure transducers are not going to be a problem
GoForSmoke:
I don't expect any big problems with the code and hardware, what could go wrong?
This is unfortunately not how things work. It isn't a question of "what could go wrong" as if nothing will go wrong, but instead "what could go wrong" assuming something can and will eventually go wrong. It is foolish to design a system and believe under no circumstance will it fail. Honestly it really sucks, but you know what they say, "hope for the best, plan for the worst."