Spunding Automation and Logic

Since I brew according to the Reinheitsgebot, I have to carbonate the beer naturally, which means no force carbonation (unless the carbonation is recaptured from fermentation). It’s actually a very simple thing to do, and I have already wrote about its numerous benefits prior. I prefer to do this via spunding (or basically capping the fermenter as fermentation winds down). For this I dedicated some automation to it. Here I am going to lay out my scripting and automation for it.

The system uses the temperature of the beer, a carbonation chart, and a pressure sensor to figure out the proper pressure to keep the beer. If the pressure exceeds that amount it automatically opens a solenoid to release pressure. That setup looks like this.

The manifold consists of a QD, to a pressure sensor, to a solenoid, to a needle valve. The needle valve allows for a very slow pressure release to maintain pressure with great accuracy.

The controller side looks like this:

I have 4 separate manifolds, that can independently control 4 beers at a time. As you can see by the graphs it is very accurate. The code for this is pretty intense.

[setup]
new value DesiredCarb1
new value DesiredCarb2
new value DesiredCarb3
new value DesiredCarb4
new value pressure1
new value pressure2
new value pressure3
new value pressure4
new value temp1
new value temp2
new value temp3
new value temp4
new value pressure1vol1
new value pressure1vol2
new value pressure1vol3
new value pressure1vol4
new value pressure1vol5
new value pressure1vol6
new value pressure2vol1
new value pressure2vol2
new value pressure2vol3
new value pressure2vol4
new value pressure2vol5
new value pressure2vol6
new value pressure3vol1
new value pressure3vol2
new value pressure3vol3
new value pressure3vol4
new value pressure3vol5
new value pressure3vol6
new value pressure4vol1
new value pressure4vol2
new value pressure4vol3
new value pressure4vol4
new value pressure4vol5
new value pressure4vol6
new value pressure1psi
new value pressure1psi1
new value pressure1psi2
new value pressure1psi3
new value pressure1psi4
new value pressure2psi
new value pressure2psi1
new value pressure2psi2
new value pressure2psi3
new value pressure2psi4
new value pressure3psi
new value pressure3psi1
new value pressure3psi2
new value pressure3psi3
new value pressure3psi4
new value pressure4psi
new value pressure4psi1
new value pressure4psi2
new value pressure4psi3
new value pressure4psi4

DesiredCarb1 = 2.5
DesiredCarb2 = 2.5
DesiredCarb3 = 2.5
DesiredCarb4 = 2.5

[loop]
temp1 = 0.0101059 * “Spunding Chamber Control” Target
temp2 = 0.00116512 * “Spunding Chamber Control” Target
temp3 = temp2 * “Spunding Chamber Control” Target
pressure1vol1 = 0.173354 * “Spunding Chamber Control” Target
pressure1vol4 = pressure1vol1 * DesiredCarb1
pressure1vol2 = 4.24267 * DesiredCarb1
pressure1Vol3 = 0.0684226 * DesiredCarb1
pressure1vol5 = pressure1vol3 * DesiredCarb1
pressure2vol1 = 0.173354 * “Spunding Chamber Control” Target
pressure2vol4 = pressure2vol1 * DesiredCarb2
pressure2vol2 = 4.24267 * DesiredCarb2
pressure2Vol3 = 0.0684226 * DesiredCarb2
pressure2vol5 = pressure2vol3 * DesiredCarb2
pressure3vol1 = 0.173354 * “Spunding Chamber Control” Target
pressure3vol4 = pressure3vol1 * DesiredCarb3
pressure3vol2 = 4.24267 * DesiredCarb3
pressure3Vol3 = 0.0684226 * DesiredCarb3
pressure3vol5 = pressure3vol3 * DesiredCarb3
pressure4vol1 = 0.173354 * “FV2 Beer Temp” value
pressure4vol4 = pressure4vol1 * DesiredCarb4
pressure4vol2 = 4.24267 * DesiredCarb4
pressure4Vol3 = 0.0684226 * DesiredCarb4
pressure4vol5 = pressure4vol3 * DesiredCarb4

pressure1psi = -16.6999
pressure1psi1 = pressure1psi – temp1
pressure1psi2 = pressure1psi1 + temp3
pressure1psi3 = pressure1psi2 + pressure1vol4
pressure1psi4 = pressure1psi3 + pressure1vol2
pressure2psi = -16.6999
pressure2psi1 = pressure2psi – temp1
pressure2psi2 = pressure2psi1 + temp3
pressure2psi3 = pressure2psi2 + pressure2vol4
pressure2psi4 = pressure2psi3 + pressure2vol2
pressure3psi = -16.6999
pressure3psi1 = pressure3psi – temp1
pressure3psi2 = pressure3psi1 + temp3
pressure3psi3 = pressure3psi2 + pressure3vol4
pressure3psi4 = pressure3psi3 + pressure3vol2
pressure4psi = -16.6999
pressure4psi1 = pressure4psi – temp1
pressure4psi2 = pressure4psi1 + temp3
pressure4psi3 = pressure4psi2 + pressure4vol4
pressure4psi4 = pressure4psi3 + pressure4vol2

pressure1 = pressure1psi4 – pressure1vol3
pressure2 = pressure2psi4 – pressure2vol3
pressure3 = pressure3psi4 – pressure3vol3
pressure4 = pressure4psi4 – pressure4vol3
if “Auto Spund 1” state == true
if “Spund Pressure Sensor 1” value >= pressure1
“PRV 1” state = on
else
“PRV 1” state = off
endif
if “Spund Pressure Sensor 1” value <= 5
“Spund 1 Alarm” active = true
else
“Spund 1 Alarm” active = false
endif
if “Spund Pressure Sensor 1” value >= 60
“Spund 1 Alarm” active = true
else
“Spund 1 Alarm” active = false
endif
endif

if “Auto Spund 2” state == true
if “Spund Pressure Sensor 2” value >= pressure2
“PRV 2” state = on
else
“PRV 2” state = off
endif
if “Spund Pressure Sensor 2” value <= 5
“Spund 2 Alarm” active = true
else
“Spund 2 Alarm” active = false
endif
if “Spund Pressure Sensor 2” value >= 60
“Spund 2 Alarm” active = true
else
“Spund 2 Alarm” active = false
endif
endif

if “Auto Spund 3” state == true
if “Spund Pressure Sensor 3” value >= pressure3
“PRV 3” state = on
else
“PRV 3” state = off
endif
if “Spund Pressure Sensor 3” value <= 5
“Spund 3 Alarm” active = true
else
“Spund 3 Alarm” active = false
endif
if “Spund Pressure Sensor 3” value >= 60
“Spund 3 Alarm” active = true
else
“Spund 3 Alarm” active = false
endif
endif

if “Auto Spund 4” state == true
if “Spund Pressure Sensor 4” value >= pressure4
“PRV 4” state = on
else
“PRV 4” state = off
endif
if “Spund Pressure Sensor 4” value <= 5
“Spund 4 Alarm” active = true
else
“Spund 4 Alarm” active = false
endif
if “Spund Pressure Sensor 4” value >= 60
“Spund 4 Alarm” active = true
else
“Spund 4 Alarm” active = false
endif
endif

if “Auto Spund 1” state == false
“PRV 1” state = off
endif
if “Auto Spund 2” state == false
“PRV 2” state = off
endif
if “Auto Spund 3” state == false
“PRV 3” state = off
endif
if “Auto Spund 4” state == false
“PRV 4” state = off
endif
sleep 3000
goto loop

A whole bunch of math there! What does it mean? Basically it turns the spunding procedure into a dynamic automatic pressure release valve. But this isn’t a basic post, lets break it down!


In the script language you have to declare values, I always do this at the top of the script, these values will come in to play later and you will understand. Here they are.

[setup]
new value DesiredCarb1
new value DesiredCarb2
new value DesiredCarb3
new value DesiredCarb4
new value pressure1
new value pressure2
new value pressure3
new value pressure4
new value temp1
new value temp2
new value temp3
new value temp4
new value pressure1vol1
new value pressure1vol2
new value pressure1vol3
new value pressure1vol4
new value pressure1vol5
new value pressure1vol6
new value pressure2vol1
new value pressure2vol2
new value pressure2vol3
new value pressure2vol4
new value pressure2vol5
new value pressure2vol6
new value pressure3vol1
new value pressure3vol2
new value pressure3vol3
new value pressure3vol4
new value pressure3vol5
new value pressure3vol6
new value pressure4vol1
new value pressure4vol2
new value pressure4vol3
new value pressure4vol4
new value pressure4vol5
new value pressure4vol6
new value pressure1psi
new value pressure1psi1
new value pressure1psi2
new value pressure1psi3
new value pressure1psi4
new value pressure2psi
new value pressure2psi1
new value pressure2psi2
new value pressure2psi3
new value pressure2psi4
new value pressure3psi
new value pressure3psi1
new value pressure3psi2
new value pressure3psi3
new value pressure3psi4
new value pressure4psi
new value pressure4psi1
new value pressure4psi2
new value pressure4psi3
new value pressure4psi4

Once all the values are declared. I can start to use these names (values) in the script.


Here I declare a hard value for a set of the values I defined.

DesiredCarb1 = 2.5
DesiredCarb2 = 2.5
DesiredCarb3 = 2.5
DesiredCarb4 = 2.5

That means that the default carbonation level will always be 2.5 vols, the default could be anything. I chose 2.5 as it is the one I use the most.


Here you see the loop command, this means it will be going in an infinite loop, making the script fully dynamic to changing variables (temperature, carbonation level, etc). More on that later.

[loop]


Now we start to get into the nitty gritty of the math. I start with temperature. Temperature is a very important part of the carbonation process. The temperature of the beer not only determines the amount of co² needed, but it also determines how much co² is retained in the beer. The higher the temperature the more pressure is needed, and the less that is residual in the beer to start.

temp1 = 0.0101059 * “Spunding Chamber Control” Target
temp2 = 0.00116512 * “Spunding Chamber Control” Target
temp3 = temp2 * “Spunding Chamber Control” Target

These inline equations factor these two factors I talked about above. You can also see here that it uses some of the values we declared above, temp1,temp2, temp3.


Next up is some more inline math, this is factoring in temperature of beer+ desired carbonation level. This sets the carbonation level (in volumes) to carbonate the beer.

pressure1vol1 = 0.173354 * “Spunding Chamber Control” Target
pressure1vol4 = pressure1vol1 * DesiredCarb1
pressure1vol2 = 4.24267 * DesiredCarb1
pressure1Vol3 = 0.0684226 * DesiredCarb1
pressure1vol5 = pressure1vol3 * DesiredCarb1


Since I have 4 pressure sensors like this, I can just repeat the same calculations 4 times.

pressure1vol1 = 0.173354 * “Spunding Chamber Control” Target
pressure1vol4 = pressure1vol1 * DesiredCarb1
pressure1vol2 = 4.24267 * DesiredCarb1
pressure1Vol3 = 0.0684226 * DesiredCarb1
pressure1vol5 = pressure1vol3 * DesiredCarb1
pressure2vol1 = 0.173354 * “Spunding Chamber Control” Target
pressure2vol4 = pressure2vol1 * DesiredCarb2
pressure2vol2 = 4.24267 * DesiredCarb2
pressure2Vol3 = 0.0684226 * DesiredCarb2
pressure2vol5 = pressure2vol3 * DesiredCarb2
pressure3vol1 = 0.173354 * “Spunding Chamber Control” Target
pressure3vol4 = pressure3vol1 * DesiredCarb3
pressure3vol2 = 4.24267 * DesiredCarb3
pressure3Vol3 = 0.0684226 * DesiredCarb3
pressure3vol5 = pressure3vol3 * DesiredCarb3
pressure4vol1 = 0.173354 * “FV2 Beer Temp” value
pressure4vol4 = pressure4vol1 * DesiredCarb4
pressure4vol2 = 4.24267 * DesiredCarb4
pressure4Vol3 = 0.0684226 * DesiredCarb4
pressure4vol5 = pressure4vol3 * DesiredCarb4


Since we now have our residual carbonation, plus our desired carbonation, now its time to start and set the pressure needed for that to happen. We do that here.

pressure1psi = -16.6999
pressure1psi1 = pressure1psi – temp1
pressure1psi2 = pressure1psi1 + temp3
pressure1psi3 = pressure1psi2 + pressure1vol4
pressure1psi4 = pressure1psi3 + pressure1vol2

We are subtracting residual carbonation, and adding the remaining needed. I can only do 1 inline math equation per line so that is why you see it this way.


Again since we have 4 sensors this is repeated 4 times.

pressure1psi = -16.6999
pressure1psi1 = pressure1psi – temp1
pressure1psi2 = pressure1psi1 + temp3
pressure1psi3 = pressure1psi2 + pressure1vol4
pressure1psi4 = pressure1psi3 + pressure1vol2
pressure2psi = -16.6999
pressure2psi1 = pressure2psi – temp1
pressure2psi2 = pressure2psi1 + temp3
pressure2psi3 = pressure2psi2 + pressure2vol4
pressure2psi4 = pressure2psi3 + pressure2vol2
pressure3psi = -16.6999
pressure3psi1 = pressure3psi – temp1
pressure3psi2 = pressure3psi1 + temp3
pressure3psi3 = pressure3psi2 + pressure3vol4
pressure3psi4 = pressure3psi3 + pressure3vol2
pressure4psi = -16.6999
pressure4psi1 = pressure4psi – temp1
pressure4psi2 = pressure4psi1 + temp3
pressure4psi3 = pressure4psi2 + pressure4vol4
pressure4psi4 = pressure4psi3 + pressure4vol2


The final carbonation equation is going to give us the real pressure in PSI needed for the proper carbonation level.

pressure1 = pressure1psi4 – pressure1vol3

This is finally going to allow the script to dynamically set the pressure to hold or release at.


Repeated 4 times

pressure1 = pressure1psi4 – pressure1vol3
pressure2 = pressure2psi4 – pressure2vol3
pressure3 = pressure3psi4 – pressure3vol3
pressure4 = pressure4psi4 – pressure4vol4


Now we get into some if statements. If statements wait until it sees a variable, then does something. It works like “IF” you see something happen, then “DO” this. “IF” you don’t see something happening (else) do this.

if “Auto Spund 1” state == true
if “Spund Pressure Sensor 1” value >= pressure1
“PRV 1” state = on
else
“PRV 1” state = off
endif
if “Spund Pressure Sensor 1” value <= 5
“Spund 1 Alarm” active = true
else
“Spund 1 Alarm” active = false
endif
if “Spund Pressure Sensor 1” value >= 60
“Spund 1 Alarm” active = true
else
“Spund 1 Alarm” active = false
endif

So we can break this down.

if “Auto Spund 1” state == true

Thats really straight forward, above we have a slider tab that said “Auto Spund”. If that toggle is on (true in this case) then that is the signal that the script is the controller of the carbonation level. There is the “if” statement that sets off the chain reaction.

Next we have another “if” statement.

if “Spund Pressure Sensor 1” value >= pressure1
“PRV 1” state = on
else
“PRV 1” state = off
endif

This one is for controlling the pressure release valve. It says, if the pressure sensor that is connected to the spunding keg is > (above) the dynamically determined pressure for the carbonation level open the valve, if its not, keep it off (shut). Really straight forward.

We now have some fail safes or alarming functions.

if “Spund Pressure Sensor 1” value <= 5
“Spund 1 Alarm” active = true
else
“Spund 1 Alarm” active = false
endif
if “Spund Pressure Sensor 1” value >= 60
“Spund 1 Alarm” active = true
else
“Spund 1 Alarm” active = false
endif

These state, if the pressure sensor that is connected to the spunding keg is below 5psi or above 60psi activate an alarm, and email me with the issue. The else statement means if the “if” statement is not met, else is the status quo. So all is normal no alarms, if there is a problem with a high or low pressure, THEN alarm.

Since there is 4 setups it is repeated 4 times.

if “Auto Spund 1” state == true
if “Spund Pressure Sensor 1” value >= pressure1
“PRV 1” state = on
else
“PRV 1” state = off
endif
if “Spund Pressure Sensor 1” value <= 5
“Spund 1 Alarm” active = true
else
“Spund 1 Alarm” active = false
endif
if “Spund Pressure Sensor 1” value >= 60
“Spund 1 Alarm” active = true
else
“Spund 1 Alarm” active = false
endif
endif

if “Auto Spund 2” state == true
if “Spund Pressure Sensor 2” value >= pressure2
“PRV 2” state = on
else
“PRV 2” state = off
endif
if “Spund Pressure Sensor 2” value <= 5
“Spund 2 Alarm” active = true
else
“Spund 2 Alarm” active = false
endif
if “Spund Pressure Sensor 2” value >= 60
“Spund 2 Alarm” active = true
else
“Spund 2 Alarm” active = false
endif
endif

if “Auto Spund 3” state == true
if “Spund Pressure Sensor 3” value >= pressure3
“PRV 3” state = on
else
“PRV 3” state = off
endif
if “Spund Pressure Sensor 3” value <= 5
“Spund 3 Alarm” active = true
else
“Spund 3 Alarm” active = false
endif
if “Spund Pressure Sensor 3” value >= 60
“Spund 3 Alarm” active = true
else
“Spund 3 Alarm” active = false
endif
endif

if “Auto Spund 4” state == true
if “Spund Pressure Sensor 4” value >= pressure4
“PRV 4” state = on
else
“PRV 4” state = off
endif
if “Spund Pressure Sensor 4” value <= 5
“Spund 4 Alarm” active = true
else
“Spund 4 Alarm” active = false
endif
if “Spund Pressure Sensor 4” value >= 60
“Spund 4 Alarm” active = true
else
“Spund 4 Alarm” active = false
endif
endif


Lastly is the command that makes this dynamic.

sleep 3000
goto loop

This means that it is going to execute the whole script listed above. It is going to sleep (or stop) for 3 seconds, then go directly back to the top of the script. This script follows that pattern indefinitely, therefore any change that happens, temperature change, pressure change, carbonation level change will be reflected and accounted for every 3 seconds. While it looks quite daunting to the lay person, this script was put together in a few hours. The benefit is having perfect carbonation levels, while being “hands off”.


Here are some youtube videos detailing this.

Hope this helps in detailing the scripting and automation of spunding for carbonation. It has carbonated a good number of beers for me and I couldn’t be happier.