BruControl: Brewery control & automation software

Homebrew Talk - Beer, Wine, Mead, & Cider Brewing Discussion Forum

Help Support Homebrew Talk - Beer, Wine, Mead, & Cider Brewing Discussion Forum:

This site may earn a commission from merchant affiliate links, including eBay, Amazon, and others.
As Oakbarn pointed out my original suggestion is flawed because calling the start command to launch another script will cause the script to restart if it is already running. In this case we need to add a boolean to indicate the previous state so we trigger on the switch state changing from off to on only once.

View attachment 647983

In the above example you can see that I only added this "one-shot" triggering to starting the fermentation script. This script will continuously call the stop command which results in your fermentation script output window filling up with garbage stop statements.

View attachment 647984

So we can add another nested if statement in the else block to change both sides of the switch detection to a one-shot trigger.

View attachment 647986

Now our output window for the fermentation script will be cleaner.

View attachment 647988

edit: this worked great. I was able to modify script to shut off and reset the timer in the off state
 
Last edited:
So i have the fermentation start switch working with the fermentation profile script. How would I disable the hysteresis control in the off state of the switch?

I currently have FV-1 START disabling FV-1 CONTROL in false state but then I lose the measured input? How do I disable the output but preserve the input from shutting off?

new bool previous_state
previous_state = false

[main_loop]
if "FV-1 START" State == true
if previous_state == false
Start "FV-1 ALE"
previous_state = true
endif
else
stop "FV-1 ALE"
reset "FV-1 TIMER"
previous_state = false
endif
if "FV-1 START" State == False
"FV-1 CONTROL" Enabled == False
endif


sleep 500
goto "main_loop"
 
Last edited:
Trying to run it in place of an Arduino Mega with ethernet interface, which will not fit where I need the sensor interface, detailed back on post 3142
img_20190901_174446_1-jpg.642464
 
Is there any method to set more than one condition for an if or wait statement



logic: wait "some Element" state == Condition 1 or condition 2 or condition 3

I know about nested ifs or multiple ifs , but was wondering if there was an easier way with or statements
 
Is there any method to set more than one condition for an if or wait statement



logic: wait "some Element" state == Condition 1 or condition 2 or condition 3

I know about nested ifs or multiple ifs , but was wondering if there was an easier way with or statements

Nested if statements seem to be the only solution at this time. For a wait statement, you can add the timeout value, but that may or may not help you.
 
Nested if statements seem to be the only solution at this time. For a wait statement, you can add the timeout value, but that may or may not help you.
I had not seen that timeout option when I was reading the manual. That certainly can come in handy when testing the code. I had already built in a delay timer named "hiddentimer" that I use for a longer delay like 10 to 30 seconds.

I add it in my code to bench test when I cannot use the real condition (such as the start of boil based on a temperature). I also use it in the code when I want a delay not associated with any other timer. I have 4 global fields where I pop up information that need to be independent of the "normal" code. In the normal code I call the hidddentimer script to display some info. The code will delay and then set visibility hidden after some time for the global that was displayed.

I put the long comment lines around code that I need to replace or comment out in the real world so I can find them quickly when rewriting the code.

hiddentimer.png
 
How does one enable 12-bit ADC resolution on the ESP32? I see the MaxValue setting in the AnalogOptions portion of the interface "XML" file, and while I have a good inkling of what needs to be done, I'd rather know for sure.
 
Ive ran a dedicated DC-/GND line to a DIN mount block as called for by each component which I believe is the "star pattern" 110v AC Ground ties to my metal backing plate which has continuity to DIN bars.

Do the solenoid valve ground need to tie in here as well? A bit confused with the DC circuitry as I am currently thinking DC- is ground. Do i need to separate all ground and DC- circuits? If so, I'm left wondering where the DC- circuit will "exit" the panel if not through the ground circuit. I believe the group has clarified DC- should not tie to neutral.
 
Ive ran a dedicated DC-/GND line to a DIN mount block as called for by each component which I believe is the "star pattern" 110v AC Ground ties to my metal backing plate which has continuity to DIN bars.

Do the solenoid valve ground need to tie in here as well? A bit confused with the DC circuitry as I am currently thinking DC- is ground. Do i need to separate all ground and DC- circuits? If so, I'm left wondering where the DC- circuit will "exit" the panel if not through the ground circuit. I believe the group has clarified DC- should not tie to neutral.

You should tie your DC- from different sources (12VDC, 5VDC, 24VDC) together. Also, you can ground the DC- of each source, this is optional.
 
You should tie your DC- from different sources (12VDC, 5VDC, 24VDC) together. Also, you can ground the DC- of each source, this is optional.
Got it. Should this tie to AC GND? If so why does my DC device (solenoid) have DC- and GND if eventually they will tie together? Seems redundant
 
First, let’s synch in terminology: for DC devices, there are only two key signals: positive and ground. Ground is often labeled as negative or DC- but this is technically incorrect since it is possible to have negative voltages (voltages are always relative to two different circuit points).

For AC devices, there are three key signals: Line, Neutral, and Ground.

So for our systems, DC circuits should have all the grounds (aka negative or DC-) from all power supplies and devices tied together - ideally to one point (star format). If switching the positive side (active high) of a circuit, the ground is permanently tied. If switching the ground side, the other side of the switch ties to ground.

Optionally, the AC ground can be also tied to this DC ground point - this will often reduce noise which can creep in to DC circuits.

Hope that helps!
 
Found this online to create free text to voice wav files
https://www.text2speech.org/
Great fun creating your own unique wav files for an Alarm.

I have created some hidden alarms that give me a 15 minute prior to a hop drop and one minute the the hop drop all with unique wav files. 15 minute and 1 minute do not loop but just play the wav file, sleep for a while then active = false.

BTW, you cannot have more than a single alarm active and have the wav file play, so you must have them active = false after you are done with them. Since these are hidden (except the Hop Drop Alarm), you must include the sleep long enough to play the wav file then active = false.
 
See attached. These are 24vDC from China. Perhaps it’s a typical and/or AC harness and adapted to DC?
View attachment 649384

Those DIN connectors are deceiving... sometimes its noted in the scant literature that the pin labeled ground is not connected to anything. Test for continuity from the pin to the solenoid body to be sure. Mine were not connected though that pin was labelled that way. Also, on mine anyway, the polarity of pins 1 and 2 made no difference as far as actuating the solenoid. I used the same pin across all my DC components for DC+ and DC- to keep everything consistent.
 
Agree with RCB. In fact, I would ignore the ground signal altogether on that.

Keep in mind this valve will create a big spike when de-energized. It will need a flyback diode such as a 1N4007.

You told me about that a while back and I posted the diode, believe you mentioned wire as close to the valve as possible. Are these diodes polarity sensitive?

I have confirmed continuity of my DC-/GND circuit across my DIN blocks
 
Any ideas on how to handle an Alarm to disable during ramp up and down? A 10bbl fermenter has quite a delay during on its way to Drest or cold crash temps. My current script is giving false alarms as it is simply coded to go off if PV is high or low from SP.
 
I was going to suggest something exactly the same as brunDog. My website does not enter is alarm mode for tracking ferment temps against target temps until it has got inside the threshold of 2 degrees (my current alarm value)
 
You could put a “gate” in front of the alarm trigger that does not allow that section of the script to execute until a baseline temperature is reached.

Without your script example, it would be hard to give you a definite answer.
Here is an example of the script I'm working with. Not sure what you mean by gate.


"FV-1 INPUT" Enabled = true sensor
"FV-1" Enabled = true

new value daycounter
daycounter precision = 0

reset "FV-1 TIMER"
start "FV-1 TIMER"
daycounter = 1

new value fermentation

[Loop]

wait "FV-1 TIMER" Value >= 00:00:3
reset "FV-1 TIMER

daycounter += 1

if daycounter == 3
fermentation = "FV-1 CONTROL" target + 2
"FV-1 CONTROL" Target = fermentation
endif

if daycounter == 4
fermentation = "FV-1 CONTROL" target + 4
"FV-1 CONTROL" Target = fermentation
endif

if daycounter == 5
fermentation = "FV-1 CONTROL" target + 6
"FV-1 CONTROL" Target = fermentation
endif

if daycounter == 5
"FV-1 CONTROL" Target = 33
endif
goto "Loop"
 
Here is an example of the script I'm working with. Not sure what you mean by gate.

"FV-1 INPUT" Enabled = true sensor
"FV-1" Enabled = true

new value daycounter
daycounter precision = 0

reset "FV-1 TIMER"
start "FV-1 TIMER"
daycounter = 1

new value fermentation

[Loop]

wait "FV-1 TIMER" Value >= 00:00:3
reset "FV-1 TIMER

daycounter += 1

if daycounter == 3
fermentation = "FV-1 CONTROL" target + 2
"FV-1 CONTROL" Target = fermentation
endif

if daycounter == 4
fermentation = "FV-1 CONTROL" target + 4
"FV-1 CONTROL" Target = fermentation
endif

if daycounter == 5
fermentation = "FV-1 CONTROL" target + 6
"FV-1 CONTROL" Target = fermentation
endif

if daycounter == 5
"FV-1 CONTROL" Target = 33
endif
goto "Loop"

I'm sorry but I'm not sure what you are doing here. Without comments or explaining the name of the elements, I don't know what each is. Plus the first line has a syntax error and the value 'fermentation' has no value assigned. There is no time delay so this will execute rapidly and 'daycounter' will be in the 10's of thousands within seconds. Have you actually run this?
 
I'm sorry but I'm not sure what you are doing here. Without comments or explaining the name of the elements, I don't know what each is. Plus the first line has a syntax error and the value 'fermentation' has no value assigned. There is no time delay so this will execute rapidly and 'daycounter' will be in the 10's of thousands within seconds. Have you actually run this?
The syntax error in first line is due to me not fully deleting the comments or notes section of script...and FV-1 CONTROL has since been renamed to FV-1, a bit of beer last night and I forget to rename a portion of this script. See revised

The time delay is three seconds per day, this allows me to test it without having to wait days. This will be modified when testing is complete.

I am unsure at this time if the value fermentation is redundant or not. My goal here was to allow user to change fermentation temperature with the script running and have it add to the target as the days progress. If I had used "FV-1" Target = 65, as the original script suggests, I no longer had this option. Perhaps there is a better way to achieve this? I do recall trying to use a Target + option but couldnt get it to work.

"FV-1 TEMP" Enabled = true // Enables FV INPUT Temp Sensor
"FV-1" Enabled = true // Enables FV Hysteresis

new value daycounter // Creates a new variable named daycounter
daycounter precision = 0 // Decimal places in FV DAY Inspector

reset "FV-1 TIMER" // Reset the timer (to its default of 0:00:00)
start "FV-1 TIMER" // Start the timer running
daycounter = 1 // Set the variable daycounter to one

new value fermentation // Create new value fermentation, needed to preserve auto control in the event of manually changing fermentation temperature

[Loop]

wait "FV-1 TIMER" Value >= 00:00:3 // Wait for a day to elapse
reset "FV-1 TIMER" // Reset the timer (to default of 0:00:00)

daycounter += 1 // Increase the variable daycounter by 1

if daycounter == 3
fermentation = "FV-1" target + 2 // Xth day, change the fermentation temp
"FV-1" Target = fermentation // Increase temperature
endif

if daycounter == 4
fermentation = "FV-1" target + 4 // Xth day, change the fermentation temp
"FV-1" Target = fermentation // Increase temperature for Diacetyl Rest
endif

if daycounter == 5
fermentation = "FV-1" target + 6 // Xth day, change the fermentation temp
"FV-1" Target = fermentation // Increase temperature for Diacetyl Rest
endif

if daycounter == 5 // Xth day, change the fermentation temp
"FV-1" Target = 33 // Decrease temperature for Cold Crash
endif
goto "Loop" // Go back to loop and wait again


FV-1 INPUT = SPI INPUT
FV-1 = HYSTERESIS
FV-1 TIMER = TIMER
 
Last edited:
I don't see any alarm triggering in this script so I'm still a bit confused. Your timer also has a syntax error.

I would write the script such that you set a temp target per each time period. Then create a separate timer which delays the alarm from going off for another period of time (to give it time to catch up).
 
I don't see any alarm triggering in this script so I'm still a bit confused. Your timer also has a syntax error.

I would write the script such that you set a temp target per each time period. Then create a separate timer which delays the alarm from going off for another period of time (to give it time to catch up).

There’s no alarm script cuz I’m not sure what to write.

What syntax error in timer?
 
wait "FV-1 TIMER" Value >= 00:00:3 // Wait for a day to elapse

Is that 30 seconds? Should be in format hh:mm:ss. It is not a day.

It is 3 seconds and tests out as such. I’ll change duration to a true day after testing.
 
There’s no alarm script cuz I’m not sure what to write.

this is a sample of my code to turn on a bitter hop alarm as an example :
My Boil Timer is a countdown from 01:30:00
The "HopMessage " is a global String
"HiddenHopDrop" is a global time element ( I use this so I can see what my code is based upon when testing it).
"HopperTime" is a calculated time variable (I have a R workspace where I put all my Temperature Targets and Times for Hop Drops and such.
"HidddenHopTimer" is like a sleep command, but I set the delay in seconds. A sub routine that is called then returns.
My "HopMessage " is displayed for an additional 15 seconds after I click the alarm off
The last little if if statements will take me to a different workspace is my big mac valve is on and my "Boil Timer" is >= to 01:18:00
I fill my Bic Mac (Huge HLT) but if my "Bitter Hop Alarm" comes on, the code (elsewhere) pops up the Brewery Page where all my temps, Timers, etc are displayed. My Water Workspace only has items dealing with Filling vessels from filtered tap water.

.

BTW the "gHopStatus" is an incremental number that is really just place keeper. It is also a global value that is visible when I am testing the code. It allows me to go to a problem area very fast if I find something I do not like.

I would appreciate any comments as this is a work in progress.

alarm sample.png
 
this is a sample of my code to turn on a bitter hop alarm as an example :
My Boil Timer is a countdown from 01:30:00
The "HopMessage " is a global String
"HiddenHopDrop" is a global time element ( I use this so I can see what my code is based upon when testing it).
"HopperTime" is a calculated time variable (I have a R workspace where I put all my Temperature Targets and Times for Hop Drops and such.
"HidddenHopTimer" is like a sleep command, but I set the delay in seconds. A sub routine that is called then returns.
My "HopMessage " is displayed for an additional 15 seconds after I click the alarm off
The last little if if statements will take me to a different workspace is my big mac valve is on and my "Boil Timer" is >= to 01:18:00
I fill my Bic Mac (Huge HLT) but if my "Bitter Hop Alarm" comes on, the code (elsewhere) pops up the Brewery Page where all my temps, Timers, etc are displayed. My Water Workspace only has items dealing with Filling vessels from filtered tap water.

.

BTW the "gHopStatus" is an incremental number that is really just place keeper. It is also a global value that is visible when I am testing the code. It allows me to go to a problem area very fast if I find something I do not like.

I would appreciate any comments as this is a work in progress.

View attachment 649687
Thankyou for the example, ill try to extrapolate for my own process.
Truth be told... I try not to write script for you guys as I think/believe/hope that you are better off in the long run if you grind through it and teach yourself. Trust my goal isn't to frustrate anyone, and I will provide whatever help you require...
Agreed, infact i almost posted last night to not share a script but rather push me in the right direction. I am starting to feel a bit more comfortable with writing script but still very lost. I appreciate any advice you have to offer...

How can I make something happen when a certain condition is met. For instance, I want to say if temperature is 68 for 10min then allow alarm. This rule should take care of the ramp phase.
 

Latest posts

Back
Top