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.
Honestly not sure. I *think* it needs to leverage .NET 5, but I will check with my partner.

Microsoft does say,“...App availability and compatibility may vary. At this time, Surface Pro X will not install 64-bit applications that have not been ported to ARM64, some games and CAD software, and some third-party drivers or anti-virus software.”

Also, running and running well are two different animals. Will get back to you.
 
I think your biggest problem might be running sql server. Looks like that is 64 bit only and the surface pro can only run 32 bit x86 programs. Anything 64 bit currently needs to be natively ported to the ARM architecture.

BTW, the team I work on contributed to the design of the SQ1 processor in the surface pro X.
 
Ya, it's not a bug per se. The button is only a button. We need to remove the Value Appearance fields from it. Sorry for the confusion!

I'm trying to change the onscreen display name of a button. The script runs fine and updates the Value Appearance field in the Properties window but does not update the name on the workspace...is this related to the same?

[name]
new string name
name = OFF
GO DisplayName = name
sleep 1000
name = ON
GO DisplayName = name
sleep 1000
goto name
 
I don't have a GC or a UniShield as neither were available when I built my controls. I do however, have plenty of ESP32/8266 devices which run on 3.3v logic. If I were building a new system, with the options available to me now, I would likely go with a GC UniShield. The big gotcha regarding the 3.3v logic is most sensors are either 0-5v, 0-10v, or 4-20ma. The 0-5v will work natively with the MEGA, but would require a voltage divider circuit to work with the GC. Similarly, 0-10v or 4-20ma would also require a voltage divider or inline resistor, respectively, to work with either the MEGA or GC. When the time comes to retrofit my controls for 3.3v logic, it will be a bit of work to get it done, but if you start from scratch that way, it'll be much less headache moving forward.
Thanks for your response, very helpful. I started looking into how difficult building voltage dividers is, and despite it being dead easy, I found another solution which seems even easier (at least for going from 5V to 3.3V):
https://www.amazon.com/dp/B0148BLZG...olid=30RG03QE919V9&psc=1&ref_=lv_ov_lig_dp_itI was wondering if you had ever used something like this and could critic whether it would work in Brucontrol (I'm kind of thinking Brudog will also respond to this.). Thanks!
 
I have finally found a minute to install the newest "v45K" firmware and I can confirm that the previously non-functional analog inputs (A8-A15) are now working on the Grand Central. Thank you Pete!

I am one of those that has converted from the MEGA 2560 over to the Grand Central and I must say it wasn't too much effort on my rig. It is a combination rig for brewing and fermentation with ~90% of the I/O used (so it isn't a small deployment). That said, the BruControl RP, TF, and AA boards I use all work seamlessly with either 5V or 3.3V logic. My cheap flow totalizers are 5V but they do work fine at 3.3V as well. Literally the only sensors I had to do a simple voltage divider for were my 5V current sensors. I do have a number of sensors that output 4-20 mA which need to be converted over to voltage but that is no different then for the 2560. There are many ways to do that but I wanted to play around with the Automation Direct P1AM-100 Arduino controller, so I got that and an analog input and an analog output module that I use to read the incoming 4-20 mA signals and scale them to the desired voltage outputs (it was 5V previously and now its 3.3V for the GC with just a quick code change). This is total overkill of course but works flawlessly and is flexible. I also have Arduino pH and load cell transmitters that can output either 5V or 3.3V, so those too were easy enough to change over. Now that the second half of the analog inputs are functioning with the newest firmware, I would certainly say the firmware is fully functional and as stable as that of the MEGA 2560. For what it is worth, so far I have had no detectable difference in I/O signal/noise quality between the 2560 and the GC in my particular panel.

There were a couple wire map errors to make note of unless those have been rectified. Specifically, port 7 & 9 did not output a PWM signal on several GC controllers I tried even though BC allowed such a device to be created as indicated on the wire map. There are still plenty of PWM outputs however, so this is not a significant issue.
 
I believe the IOT enterprise version is basically a regular Win10 install... based on that, I would say yes. I have some older Wyse terminals that I briefly thought about playing with, but the 5070 with a quad core and 8GB of ram might work pretty well.
 
What's the latest BC software version available?

NVM I see it's 1.1.4. are we expecting a new release soon?
 
I believe the IOT enterprise version is basically a regular Win10 install... based on that, I would say yes. I have some older Wyse terminals that I briefly thought about playing with, but the 5070 with a quad core and 8GB of ram might work pretty well.
yeah, spec'd out a big order for the extended version today for a customer, wth graphics card and while verifying what cable to get for 4x monitors, I saw they can support 4x Displayport and 2x miniDP ports... 6 monitors! And a guy on ebay has 60 of em for $200 each...
 
Wow I'm still running 1.1.4 didn't realize beta testing was available. What's changed since then?

I’m still on 1.1.4 too. I decided to wait till 1.1.9 isn’t Beta or 1.2 comes out. No real reason though other than I have other projects going on right now
 
Last edited:
Good evening,

We posted v1.1.9 (v1.2 Beta). Please consult your authorization email for a direct link to the page or access it via the form on the Download section of the website.

We have a few items to add to this version before releasing it as 1.2, but below is a list of some of the updates, in addition to various fixes (thank you to those who notified us of issues). Some of the fixes below are already incorporated into the released v1.1.4.

One MAJOR item to note: This version utilizes an SQL database to store data. Therefore: the installation steps must be followed in the Product Note and your existing data will not carry over. It is possible to import that data back to the DB by but we aren't able to write that or support it right now.

Fixed: Hysteresis result is not a boolean type
Fixed: PID Calc and Out Times
Fixed: Overlapping alarms prevent second+ alarms sounds and email
Fixed: Certain text characters pasted in script causes crash
Fixed: Graph of Global on different Workspace doesn't display
Changed: Swap Settings/Menu icons
Changed: Updated to use .NET Framework 4.4
Added: Automatic Lock
Added: Direct script command
Added: SQL Database for data
Added: Switch to disable log files (default)
Added: String text line feed
Added: Element Display Name (alias) field
Added: Script running status available in another script
Added: Dual Throw output (pending FW 45K)
Added: Device Element Enable Switch
Added: Choice of 3 or no Alarm sounds, plus script control
Added: Element location and size in properties
Added: Use PWM (if available) in PID and Deadband (pending FW 45K)
Added: Direct command (to interface) via script
Added: Script window height in settings
I have new beta running. Curious if I should update firnware. Is there release notes for latest?

Can you elaborate on automatic lock and direct script command?
 
First day I left BC and panel running at the brewery. Ambient is 94F and thermometers inside panel are showing 98F. What temp would you guys say is danger zone for the components typically found in a BC panel?
 
That's getting pretty warm, but the biggest thing I would be worried about is the SSRs while they are under load, especially if they don't have good thermal conductivity to their heatsinks. Check your datasheet for your SSRs, but typically as temperature increases, current capacity decreases. Another thing to check occasionally is tightening your connections, especially on high voltage lines... Thermal creep is real. Otherwise, if you used quality components, you should be fine.
 
That's getting pretty warm, but the biggest thing I would be worried about is the SSRs while they are under load, especially if they don't have good thermal conductivity to their heatsinks. Check your datasheet for your SSRs, but typically as temperature increases, current capacity decreases. Another thing to check occasionally is tightening your connections, especially on high voltage lines... Thermal creep is real. Otherwise, if you used quality components, you should be fine.
No SSRs in the panel just PSUs, mega, contactors, relay boards and pt100 amplifiers. How hot would you say I better go down there and shut it off?
 
PSUs are likely going to be your limitation as they are generating heat as well. My decent industrial ones list a high operating temp of 140, so I think you are probably good to 110-120. How are you powering the mega? If feeding it 12v, the voltage regulator can get pretty hot and it could cause some issues.
 
PSUs are likely going to be your limitation as they are generating heat as well. My decent industrial ones list a high operating temp of 140, so I think you are probably good to 110-120. How are you powering the mega? If feeding it 12v, the voltage regulator can get pretty hot and it could cause some issues.
Ok sweet, I'll keep monitoring. Should I plan on running a PC fan to keep it cooler?

I can't recall off hand but I powered it as suggested from the wiring diagrams at BruControl website. I want to say 5v
 
Fresh air is rarely ever a bad thing, so I think that would be a good plan. If you are 5v powered you are in good shape as it's bypassing the voltage regulator.
 
Fresh air is rarely ever a bad thing, so I think that would be a good plan. If you are 5v powered you are in good shape as it's bypassing the voltage regulator.
Fresh air even if I'm not running SSRs and it stays around 110F? Trying to gauge the trade-off with dust buildup etc
 
Yeah that's a tough trade off, in that case I think I would opt to keep the dust out of the enclosure... If you feel it's too hot you could still try a fan with a filter on it.
 
I have new beta running. Curious if I should update firnware. Is there release notes for latest?

Can you elaborate on automatic lock and direct script command?

Yes, I think its a good idea. You will need it for the PWM switch in PID's and Deadbands, and for the Dual Throw function in DO's.

Automatic Lock automatically locks the environment after the set amount of time. The direct script command is kinda an advanced option - to send commands directly to the interface (without an Element doing it).
 
Agree on the discussions above. The 98 inside to 94 outside delta is pretty low and good... but you aren't really loading anything. So starting from there and ramping up the power demand might make a bigger temp difference. Even then, electronics don't really start to care until 50 C (122) is reached. As far as SSRs are concerned, the most important temperature is their die (junction) temp... which can usually reach as much as 125 C for quality units, so the heat sink matters to pull enough heat out to make sure this isn't exceeded. You might crack open the enclosure a bit if the ambient is hot like that, but I think you are OK for no load.
 
Hi, is it possible to pass a variable to the sleep command? Long story, but I have a need to dynamically calculate a time value to run one of my pumps. The scaled down test script below never goes past the "sleep waitTime" line.

If that isn't possible can I dynamically set a timer value by converting 'x' seconds into the timer's "00:00:00" format somehow?

Thx!

Code:
new value waitTime

waitTime = 1000  //this would be a calculated value in the real code

sleep waitTime

stop "Test"
 
It looks like the script runs but does not resolve the sleep variable. I would propose what you suggested as a backup. You could either use a Timer Element, that you set in your script, or a datetime variable and compare to that. Now, that said, you can't add an integer of seconds directly to a time variable, so here is a work-around, where we dynamically add 1 second of time to a time variable the number of times needed to match the number of seconds. Wonky... yes. But it works. In this example, WaitTimer is a Timer Element. LMK if you want a datetime variable example instead. secsLimit is your number of seconds to count to.

Code:
new time waitTime
new value secsCount
new value secsLimit
waitTime = "00:00:00"
secsCount = 0
secsLimit = 5

[calctime]
waitTime += 00:00:01
secsCount += 1
if secsCount < secsLimit
goto "calctime"
endif

restart "WaitTimer"
wait "WaitTimer" value > waitTime
stop "WaitTimer"
stop "Script 1"
 
The loop/timer concept worked perfectly... Thank you sir!



It looks like the script runs but does not resolve the sleep variable. I would propose what you suggested as a backup. You could either use a Timer Element, that you set in your script, or a datetime variable and compare to that. Now, that said, you can't add an integer of seconds directly to a time variable, so here is a work-around, where we dynamically add 1 second of time to a time variable the number of times needed to match the number of seconds. Wonky... yes. But it works. In this example, WaitTimer is a Timer Element. LMK if you want a datetime variable example instead. secsLimit is your number of seconds to count to.

Code:
new time waitTime
new value secsCount
new value secsLimit
waitTime = "00:00:00"
secsCount = 0
secsLimit = 5

[calctime]
waitTime += 00:00:01
secsCount += 1
if secsCount < secsLimit
goto "calctime"
endif

restart "WaitTimer"
wait "WaitTimer" value > waitTime
stop "WaitTimer"
stop "Script 1"
 
Last edited:
The loop/timer concept worked perfectly... Thank you sir!
I use the following:

I have a "hiddentimer" that is not visible.

//some code
"hiddentimer" value = 00:00:20
call "sub_wait_Timer"
//some code
"hiddentimer" value = 00:01:15
call "sub_wait_Timer"
//some code
//put at end of the script
[sub_wait_Timer]
start "hiddentimer"
wait "hiddentimer" value <= 00:00:00:00
stop "hiddentimer"
return
// some code
stop "thisScript"


I do not know if the new call from one script to another could make this more global.
 
I have also used Global Elements to use as the Value of a timer:
"HopperTime" is a Global Element. I use it for Bitter Hops, the Flavor Hops then Aroma Hops.

In fact, all of these are Global Elements. I reuse them for the different hop drops. I have a script that runs before I start the brew process that "sets" all of these variables depending on which brew I am doing. Although I did not get to it yet, I will be changing these via Brew Smith import.

//Bitter Hop Times
if "Bitter 1" state == true
//Bitter Hop Times
if "Bitter 1" state == true
"HopperTime" = "Bitter Hop Time" value
//this Bitter Hop Time is another global from my Recipe Workspace. These change for different recipes. This will eventually be imported.
"15mHopperTime" = "HopperTime" + 00:15:00
"1mHopperTime" = "HopperTime" + 00:01:00
"gHop_15m_Time_B1" value = "15mHopperTime"
"gHop_1m_Time_B1" value = "1mHopperTime"




then later when I need it,

wait "Boil Timer" <= "HopperTime"
//Bitter Hop Alarm
"alrmBttrHp" active = true
//more code
 
Last edited:
Thx Oak, I definitely could have solved this by using a global element and manually calculating. My system knows (sort of) the volume of the HLT and the flow rate of my pump, so I was going to experiment with seeing how close I could time things to get the pump to drain the HLT and shut off.

The "sort of" portion of this is that the only port I had available for a pressure transducer on the HLT is several inches off of the base, so there are about 7 gallons of water below it where my measurements go dark when draining (so using that alone, I don't know when my HLT is empty).

A few different ways I could solve it. I had a pressure transducer on my mash tun too, but it has even fewer ports, so I was using a tee with the pressure transducer on one side and the pump on the other. It's a bottom drain on the mash tun and I was having accuracy problems with that setup.

Sooooo... a few ways I could still solve it (short of finding someone to weld me a new port at the base of the HLT). I could overfill the HLT by 7+ gallons and reliably use it's pressure transducer to know how much I've pumped into the mash tun (this will be my Plan B) or I could fill the HLT up to match what I need in the mash tun (+ loss) and pump for 'x' seconds, totally draining the HLT and hopefully not running the pump dry for more than a few seconds.

I filled up ~37 gallons last night and measured the time that the pump took to drain it a few times and now have a "pump rate". Since I know my starting volume, I (in my head at least) should be able to use that plus a few seconds of padding to calculate how long the pump needs to run to jussssst drain the volume that's currently in the HLT. To your point, I could definitely key this same value into a timer or myself and that will be Plan C.

Plan D will be to just sit there and watch it, but filling the HLT with reverse osmosis water takes quite a while. BruControl takes care of filling up the HLT with a valve on the RO system, so ideally I'd like to just wake up to nice hot strike water in my mash tun and nice hot sparge water in my HLT.



I have also used Global Elements to use as the Value of a timer:
"HopperTime" is a Global Element. I use it for Bitter Hops, the Flavor Hops then Aroma Hops.

In fact, all of these are Global Elements. I reuse them for the different hop drops. I have a script that runs before I start the brew process that "sets" all of these variables depending on which brew I am doing. Although I did not get to it yet, I will be changing these via Brew Smith import.

//Bitter Hop Times
if "Bitter 1" state == true
//Bitter Hop Times
if "Bitter 1" state == true
"HopperTime" = "Bitter Hop Time" value
//this Bitter Hop Time is another global from my Recipe Workspace. These change for different recipes. This will eventually be imported.
"15mHopperTime" = "HopperTime" + 00:15:00
"1mHopperTime" = "HopperTime" + 00:01:00
"gHop_15m_Time_B1" value = "15mHopperTime"
"gHop_1m_Time_B1" value = "1mHopperTime"




then later when I need it,

wait "Boil Timer" <= "HopperTime"
//Bitter Hop Alarm
"alrmBttrHp" active = true
//more code
 
Back
Top