I've spent many hours and and a ton of paper sketching and I haven't been able to stumble upon anything to get me past this problem.
We got two tanks filled with water and two pumps between them. We need to automatically push the water to the second tank using these pumps if h>hmax (Tank 1) and H
I can't figure out one thing. First sequence assumes that if H>Hmax the pump 1 or 2 will work (they can't work simultaneously). When the water is pumped to second tank and in first tank will fall, the sequence is repeated after the water is replenished in first tank. I can't figure out how to make automatic change in pumps using only potentiometer after each sequence. What i need to do more is to include failure of one of the pump. I'm dealing with this problem for almost a week.
Hope this is what you mean. I wrote it as an "working" pseudo code. In real life this code is not the best, cause from the moment on you have more then 2 pumps it should be complicated, but this one is very detailed. Also an emergency switch is missing (so a button someone can push if he has to stop the pumps manually). Better would be to use some function_blocks and methods...
declaration:
VAR
//INPUT
levelTank1 AT %I* : INT; //potentiometer 1
levelTank2 AT %I* : INT; //potentiometer 2
pump1Malfunction AT %I* : BOOL; //TRUE=pump has no malfunction || FALSE=malfunction
pump2Malfunction AT %I* : BOOL;
//OUTPUT
pump1Operation AT %Q* : BOOL; //TRUE=pump should run
pump2Operation AT %Q* : BOOL;
lastPumpInOperation : BYTE := 1;
nState : UINT := 0;
END_VAR
Somewhere you should define the min and max levvels, I did it as a constant value:
VAR CONSTANT
tank1Hmax : INT := 32000;
tank1Hmin : INT := 5000;
tank2Hmax : INT := 25000;
tank2Hmin : INT := 2000;
END_VAR
As remark: the analog inputs are usually INT values, so max. level equals 32767
And now the program:
CASE nState OF
0: //wait till tank 1 is filled and make sure tank2 is not overcharged
IF (levelTank1 >= tank1Hmax) AND NOT (levelTank2 >= tank2Hmax) THEN
nState := 1;
END_IF
1: //start one pump
//first check worst case - both pumps are broken
IF NOT pump1Malfunction AND NOT pump2Malfunction THEN
nState := 100; //emergency
//last time pump1 was used, and now pump 2 should start when it has no malfunction
ELSIF lastPumpInOperation = 1 AND pump2Malfunction THEN
pump2Operation := TRUE;
lastPumpInOperation := 2;
nState := 2;
//last time pump2 was used, and now pump 1 should start when it has no malfunction
ELSIF lastPumpInOperation = 2 AND pump1Malfunction THEN
pump1Operation := TRUE;
pump2Operation := FALSE;
lastPumpInOperation := 1;
nState := 2;
//now we have to define what happens when one pump is in malfunction
ELSIF NOT pump1Malfunction THEN
pump2Operation := TRUE;
pump1Operation := FALSE;
lastPumpInOperation := 2;
nState := 2;
ELSIF NOT pump2Malfunction THEN
pump1Operation := TRUE;
lastPumpInOperation := 1;
nState := 2;
END_IF
2: //pump operation till tank1 is "empty", tank2 is "full" or pump failure occurs
IF (levelTank1 <= tank1Hmin) OR (levelTank2 >= tank2Hmax) THEN
nState := 3; //stop pumps
ELSIF (pump1Operation AND NOT pump1Malfunction) THEN //pump has gone in malfunction during operation
nState := 1; //go back to step2 to start another pump
ELSIF (pump2Operation AND NOT pump2Malfunction) THEN
nState := 1;
END_IF
3: //stop pumps
pump1Operation := FALSE;
pump2Operation := FALSE;
nState := 0;
100: //emergency
//do what you can do - close the valve to tank1 or run as fast as you can
pump1Operation := FALSE;
pump2Operation := FALSE;
IF (pump1Malfunction OR pump2Malfunction) THEN
nState := 0;
END_IF
END_CASE