Multi-liquid loading station; self-cleaning single pipe system

This board is to show, discuss and archive useful combinator- and logic-creations.
Smart triggering, counters and sensors, useful circuitry, switching as an art :), computers.
Please provide if possible always a blueprint of your creation.
FaceyMcGee
Manual Inserter
Manual Inserter
Posts: 2
Joined: Sat Jan 11, 2025 6:18 pm
Contact:

Multi-liquid loading station; self-cleaning single pipe system

Post by FaceyMcGee »

Been playing for a month now and this is my first proper design. Hope it is of some use to somebody.

The problem: For distant oil fields I wanted to process the oil on-site and have a single export station for all three fluids; using a single pipe to convey the fluids to the train wagon pumps.

The issue: If a fluid wagon is filled to capacity then the pumps connected to it will retain 400 fluid, which can only then flow forwards and will contaminate the next train if a different fluid type is pumped.

The solution: Two easy solutions to the pump issue would be to either use a dedicated purge wagon in-between loading sessions, or to ensure that wagons are never filled to capacity so that the excess pump fluid can be pumped in. I didn't like either of those; the former is lame, the latter would require testing to get the threshold correct if the system were scaled up (more pipe holding fluid between the wagons and storage tanks). So, I set about coming up with a self-cleaning system.

The design: Requirement: Loading wagons can be generic, but must be empty.
The system is comprised of 5 groups of combinators. Functionality, in visual order from top-to-bottom:
  1. Takes fluid level of all three types, sorts for the highest, and when a train docks to the station that fluid type is put into a memory cell for the duration of the loading. This signal is used to control which fluid type pumps should activate; if you just used the sorted signal it would change during the loading when the highest is no longer the highest
  2. Controls the train limit; for each fluid type over a threshold, add/subtract limit.
  3. Main storage tank pump controls; when the wagon pump flush is complete, activate the pumps on the main storage tanks for the fluid type (includes lower threshold stop control if wanted)
  4. (single combinator to the right of flush tank pump); when there is no train docked or the flush process is complete activate the OUT pump on the two flush tanks; fluids are recycled into the main tanks through filtered pumps. It is necessary to separate the flush tank in/out process, so that you don't get a false positive if the in/out flow rates somehow match for more than 90 ticks
  5. The meat and potatoes, the flush system; when a train docks to the station the wagon IN pumps connect and activate by default (no control or filter), pushing any previous fluid from the pipes and pumps into the train wagons. This is immediately pumped back out of the wagons by a single pump and pushed into the two flush tanks.

    The flush tank level is measured twice, once by an arithmetic combinator adding zero, and by a decider combinator that also takes in the arithmetic value (now delayed 1 tick); if the values are the same then the fluid level has not changed in 1 tick and a signal is emitted - 'everything' wildcard ensures that if flush system is completely empty (i.e. before the first ever train) then the signal is still emitted (can't compare two zero signals).

    That signal then passes into another decider combinator, which counts up to 90; it takes about 62 ticks just for the wagon pumps to engage when a train docks; fluid levels might appear steady between ticks when the fluid level integers are being rounded, so the extra 30 ticks adds a buffer to prevent a false positive of flush complete. Anytime the flush tank level changes the counter resets. When the counter reaches 90 a memory-cell emits a 'flush complete' signal.

    This signal then deactivates the wagon OUT pumps and also feeds into the main storage tank pump controls to begin the loading process. Due to the combinator system itself the main tanks don't click on until 1 tick after the wagon OUT pumps - not sure if it would matter if they activated/deactivated in the same tick, but a useful outcome anyway.
  6. Station chain signal blocks next incoming train until the flush tank has been emptied, though this happens before the loading is complete at this scale anyway.
I decided to utilize two IN pumps and one OUT pump on the same side; prefer the aesthetic of it than going for maximum loading efficiency especially given that it loads pretty fast anyway.

One potential issue I could see is that if you are somehow able to fill the main storage tank of a fluid type before the flush system can recycle any flushed fluids, then it might back up until it stalls. Not sure if that's even possible, but as you can tell by the scale I was only designing for a small oil field with a handful of refineries.

I let it run for awhile, refilling with infinity pipes, to see if it broke and it seemed fine. One potential improvement you could make is to increase the flush capacity so you could drain any incoming wagons that are not empty. For my purposes I was using a generic wagon system with train interrupts.

Image




Mods: Not sure whether this is best placed here or in the station sub-forum; feel free to move and/or duplicate it if you wish.
Tertius
Smart Inserter
Smart Inserter
Posts: 1331
Joined: Fri Mar 19, 2021 5:58 pm
Contact:

Re: Multi-liquid loading station; self-cleaning single pipe system

Post by Tertius »

I praise you for commenting your blueprint by using the comment feature of the combinators!

Interesting challenge.

It might be easier for the flush mechanics to read the train content and compare the content of the train with the fluid that's supposed to load into the train. Add both signals, count the amount of different fluids with the EACH wildcard. Amount=1: just the fluid supposed to load is present or the train is empty. 2=train has different fluid than supposed to load.

Be careful with the counting: There are virtual signals such as the train id being added to the counting. Either filter these out from counting or just make sure they're always there, so they're just a constant offset to the amount.
If you use 2 different wires to the station, you can use one of them to just read from the train and not contaminate the wire with signals from outside the station.

Now the pumps:
- activate the flush pumps if amount>1 (in this case we have a different fluid in the train than we want to load). Probably doesn't need even one combinator. for the whole flushing mechanics. Just use the activation condition in the pumps for checking the amount value.
- activate the loading pumps for the wanted fluid unconditionally, all the time as long as a train is at the station.

This will work from tick 0 on. If the train is empty, we have amount=1 (just the fluid we want to load). The loading pumps are active as soon as the train arrives, so they immediately start pumping. If their buffers were empty or they had the fluid we want, amount stays 1 and we continue the loading process up to the end.

If their buffers contained an unwanted fluid, amount will increase to 2, because the buffered fluid gets spilled into the train. The loading pumps will stall after their buffers got empty, since they will not fill a different fluid into their wagon. Since amount=2, the flush pumps will activate.

When the spilled fluid is flushed, amount returns to 1, the flush pumps deactivate, and the regular loading continues. Since the train will have a different fluid than the flush pipes have, no fluid will be pumped into the wagons and at the same time flushed again.

If the train arrives with a foreign fluid, the same thing will happen: amount raises to 2 (foreign fluid + fluid to load = 2), flush pumps activate, foreign fluid flushes. Amount=1 again, flushing stops. Loading pumps emptying their buffers, amount goes to 2. Is flushed. Amount back to 1, flushing stops. Loading automatically continues.

This will work even if some of the loading pumps have an empty buffer and other have some fluid to flush in their buffer. The empty ones will pump the correct fluid, the full ones the wrong fluid. As soon as the wrong fluid is appearing in the wagon, the flushing starts and it gets flushed out right away.

To make flushing bullet-proof so the spilled fluid is flushed and not the wanted fluid, use the signal you read from the station (that's the train content), filter out the fluid you intend to load (that's one decider combinator), and set the remaining fluid as filter to the flushing pumps. This enables us to even handle the situation every wagon has different remains of an unwanted fluid. This way one unwanted fluid after the other is flushed until eventually both are gone. To make that multi-fluid flush work, emptying the flushing fluid segment has to take place continuously.

If the train leaves, the pipe segment between the loading pumps and the wagon pumps could be flushed so just to 400 fluid buffer per pump needs to be flushed through the train. As far as I see it in your blueprint, you don't flush this. So connect this segment with the flush segment with a pump that activates if train id=0.

The only thing remaining that also needs combinators is the memory cell that decides which fluid to load as soon as the train connects to the circuit network. To have the fluid fixed from tick 0 on, set the memory cell if train id=0 (if no train is present) and don't set the memory cell if train id >0 (so the memory cell is fixed the whole time the train is present, even on tick 0). You create this R signal, but you can use the train id T directly as set condition for the memory cell.
FaceyMcGee
Manual Inserter
Manual Inserter
Posts: 2
Joined: Sat Jan 11, 2025 6:18 pm
Contact:

Re: Multi-liquid loading station; self-cleaning single pipe system

Post by FaceyMcGee »

Version 2.0

Tertius wrote: Sat Jan 11, 2025 9:28 pm I praise you for commenting your blueprint by using the comment feature of the combinators!
Good old documentation. Saves having to parse the logic flow again in the future :D
Tertius wrote: Sat Jan 11, 2025 9:28 pm It might be easier for the flush mechanics to read the train content and compare the content of the train with the fluid that's supposed to load into the train. Add both signals, count the amount of different fluids with the EACH wildcard. Amount=1: just the fluid supposed to load is present or the train is empty. 2=train has different fluid than supposed to load.
I didn't realize that the IN pumps would automatically stall if the wagon contained a different fluid - or that disabled pumps would actually continue to pump out their internal buffer IF connected to an empty/compatible fluid system. Taking this into account, in conjunction with your idea, I reworked the design.

The design is now down to 7 combinators from 10, with the flush system now controlled by a single decider combinator;
Image

This takes in the memory-cell signal of the fluid to be loaded (value 1), and any wagon contents signals (as value 1's); for every wagon fluid not equal to the signal to be loaded a [Q] of value 1 is emitted and also the fluid type again as value 1 - empty wagons emit nothing. The flush pumps are now activated when [Q] is greater than 0 and a filter applied.

Also the train wait condition should now be set to 'Inactivity' AND '[Q] = 0', OR 'Full Cargo'. This is because if there are multiple fluids to be flushed the flush pumps will stall while there is a different fluid in the flush pipes ahead of them, and if all the other wagons fill up with the correct fluid before the first fluid flush has complete then the 'Inactivity' count will start and potentially dismiss the train with an erroneous fluid still present. Using [Q] for the train holds it until one after another erroneous fluid has been purged.
Tertius wrote: Sat Jan 11, 2025 9:28 pmIf the train leaves, the pipe segment between the loading pumps and the wagon pumps could be flushed so just to 400 fluid buffer per pump needs to be flushed through the train. As far as I see it in your blueprint, you don't flush this. So connect this segment with the flush segment with a pump that activates if train id=0.
In the old and new designs that pipe segment gets flushed into the wagons when they first connect, rather than doing it after the train leaves the station. This was required due to the memory cell;
Tertius wrote: Sat Jan 11, 2025 9:28 pmYou create this R signal, but you can use the train id T directly as set condition for the memory cell.
This won't work and is why I had to use that memory-cell with the additional AND block, and its twin reset combinator that converts [T] into a reset signal. A regular memory cell will hold all values passed to it, whereas the one I used will only take the first value passed to it until it is reset, and the reset condition has to be a positive integer value unfortunately. Holding on to the first value is necessary because the select combinator outputs the highest stored fluid level, and when the train loads that fluid obviously it may dip below the next highest fluid; that would flip the select combinator, in turn adding a new value to the memory cell, and in turn erroneously activating that new highest fluids pumps.

I also reworked the flush tank part; doubled up the recycling pumps, and added a condition to the main storage IN pumps to not activate while there is respective fluid in the flush tank. Also removed the train chain signal condition - the system is still really predicated on the wagons being mostly empty, as it is primarily a loading station and not a recycling system.
Image
Tertius
Smart Inserter
Smart Inserter
Posts: 1331
Joined: Fri Mar 19, 2021 5:58 pm
Contact:

Re: Multi-liquid loading station; self-cleaning single pipe system

Post by Tertius »

FaceyMcGee wrote: Mon Jan 13, 2025 5:41 pm
Tertius wrote: Sat Jan 11, 2025 9:28 pmYou create this R signal, but you can use the train id T directly as set condition for the memory cell.
This won't work and is why I had to use that memory-cell with the additional AND block, and its twin reset combinator that converts [T] into a reset signal. A regular memory cell will hold all values passed to it, whereas the one I used will only take the first value passed to it until it is reset, and the reset condition has to be a positive integer value unfortunately.
By carefully choosing colors of input and loopback wires, you're able to feed the (re)set signal independently from the signals to store/to retrieve within the memory cell. Actually, you're free to use an arbitrary and complex reset condition, as long as it can be negated (one combinator uses the given condition, the other the negated version). I showed such a memory cell here: viewtopic.php?p=654036#p654036 It's even possible to squeeze a counter into such a cell to take a signal snapshot every n ticks.

You kept the 2 storage tanks for flushing. This vastly extends the time required to empty the flush segment, because throughput within a segment depends on fill state. Fill state = volume / space. With the 2 tanks, space is > 50000. Without the tanks, it's just about 1000 - just the pipe pieces, so fill state would be 50 times higher, so flushing speed will be significantly higher.
If there are 11 tanks with 90% fill state instead of 10 tanks there is room for the recycled fluids and a full train load. Limit is 25000 * 10 / 11 = 22727 per tank.

I took the liberty and rebuilt your station how I would do it.

The top right combinator computes the station train limit.
The selector combinator selects the most available fluid from the storage tanks.
The memory cell is the 2 combinators below the selector. It stores the most available fluid the moment the train connects.
The combinator on the left manages the flushing. It's simpler than I thought. Just determine if there is an unwanted fluid in the train and set the filter on the flushing pumps accordingly. No need to enable/disable them: if the filter is empty, they don't pump.
01-13-2025, 20-16-29.png
01-13-2025, 20-16-29.png (844.84 KiB) Viewed 1062 times



out.mp4
(3.84 MiB) Downloaded 65 times
Post Reply

Return to “Combinator Creations”