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.
Ladder is kinda obsolete eh? I prefer scripting but maybe it would be more intuitive with boolean operators like and & or in the scripting language. And maybe inline math.
 
I would hardly say obsolete in industry... use it every day. That said, I'm not sure if you would be able to run both ladder and scripting in parallel without giving one priority (typically ladder). For me, it would not be something I'd be interested in as I believe there is more inherent flexibility in scripting.
 
If someone wants ladder logic, there are a lot of controllers out there that will already do it, BCS did state machine and ladder logic, however, I like scripting much, much better.... I think scripting has it covered, but always looking forward to incremental improvements like @smort mentions..
 
Ladder logic does not add any new functionality to BruControl. Anything you want to do with ladder logic can be done with scripting. I understand that some people are more comfortable with ladder logic, but I think the limited resources that BruControl has for development and support should be focused on adding new features that continue to evolve the platform that everyone can benefit from.

For example there are several features that programming IDEs support that arent supported by BruControl's scripting editor at this point in time. Adding features like auto completion of commands and previously declared variables helps to avoid spelling and syntax mistakes. Better error messages and syntax checking can help make debugging scripts easier. Effort can be spent to make scripting more comfortable for people who aren't used to it.
 
BrunDog, I am interested in getting the draw.io source for the 50a system schematic. Also, is there an electrical symbol library for draw.io? I am not having any luck finding one. Thanks.

Edit: Oh, I see electrical symbols under more shapes.
 
Last edited:
Good feedback here. We put a lot of energy into the scripting language and speaking honestly, will not look to change it structurally.

I agree it could be bolstered and want it to handle more such as noted above. We do have a scope for a “pre-interpreter” which will look at syntax before allowing a script to be run - it’s annoying when a script gets part way through then errors out. We’ll get there!

Right now, we are focused on the DB back end and web server support along with some basic upgrades and bug fixes.
 
BrunDog, I am interested in getting the draw.io source for the 50a system schematic. Also, is there an electrical symbol library for draw.io? I am not having any luck finding one. Thanks.

Edit: Oh, I see electrical symbols under more shapes.

Email us and we’ll send it. I suppose we could just put it online!
 
TBH, I’m merely skimming the surface on both ladder logic and coding. I ask because my partner at work recommended ladder logic (he programs robotic systems, i fabricate/install the mechanical stuff) and hinted on scripting being obsolete or more challenging. I’ve committed to BC so I’m going down scripting path just wanted to understand the pros and cons of each. Sounds like this is just a matter of preference with neither being obsolete but rather the better tool for the job??
 
Ladder logic is just a bunch of nested “ifs” and can easily accomplish the same thing in scripts. Ladder Logic “coils” can also cause some issues that you may not like. the BCS has ladder logic and you can “lose” control of an output in a “coil” slot of Ladder Logic. I am sure that ladder logic is only a restrictive script or programming. Some of the work is done for you, but you can get done what you need simply by scripts.
 
Background: I am a ladder logic guy that dabbles in some python... Dabbles as in simple QT based GPIO stuff.

Just want to say I love the software, interface, and ease of part procurement... Wow I wish I paid more attention to this my first go around with my eHerms setup!

Couple of Questions
Question 1:

I have a "Step Timer" global element that I want to push a recipe defined preset into. I have other global time elements "Mash Timer", "Boil Timer" and "Sparge Timer".
Here is what I have tried that isn't working:

[mash]
new time mashtmr
"Step Timer" Value = "Mash Timer" Value

Output: [ERROR: 'Value' is not a valid operator.]

[mash]
new time mashtmr
mashtmr = "Mash Timer" Value
"Step Timer" Value = mashtmr

Output: [ERROR: 'Value' is not a valid operator.

Question 2:
Concatenation of multiple parts and values into a string. I have this working as below:

[strike water]
new string strikestatus
strikestatus = "Add " + "Strike Water Amount" Value
strikestatus += " gallons of water to MLT and "
strikestatus += "Sparge Water Amount" Value
strikestatus += " gallons of water to HLT."
"System Status" Value = strikestatus

Why can I not just do:
new string strikestatus
strikestatus = "Add " + "Strike Water Amount" Value + " gallons of water to MLT and " + "Sparge Water Amount" Value + " gallons of water to HLT."
"System Status" Value = strikestatus


Question 3:
We should make a script repository. I am sure someone has done something in a cool way that is reproducible?

Question 4:
I have been reading posts and saw working beer.xml imports. From what I understand this is user generated. Is this supported? Or currently still in progress?

I have attached my single script (heh) for reference. It runs as expected until Question 1. Any suggestions, comments appreciated via PM
 

Attachments

  • BrewBros.zip
    2 KB · Views: 19
Responding to above post:

Code:
"Step Timer" Value = "Mash Timer" Value
This should work fine (does in my testing), as long as both 'Step Timer' and 'Mash Timer' are both timer elements or global elements (using either time or datetime type data). Also, you declare a time variable but don't use it in the example, so I'm not sure what your intention is there.

Code:
new time mashtmr
mashtmr = "Mash Timer" Value
"Step Timer" Value = mashtmr
This works fine. Are you sure you have 'Step Timer' as a Global with time type variable?

Code:
new string strikestatus
strikestatus = "Add " + "Strike Water Amount" Value + " gallons of water to MLT and " + "Sparge Water Amount" Value + " gallons of water to HLT."
"System Status" Value = strikestatus
You cannot do this because the interpreter cannot handle inline math yet.

Repository is a good idea. We have a user forum that isn't used much. I suppose that would be a PITA for users to bounce forums. Perhaps the HBT guys would be OK with a BC script thread? Happy to field suggestions here.

Importing is done via a third party interpreter. I think most are using NodeRed to read the XML and hand it to the Data Exchange protocol in BC. We do not have a native XML reader yet, and honestly have back-burnered it in favor of the data exchange. We could resurrect if enough support.
 
Would like to bump the request for Tilt integration improvements.

  1. I see a great benefit for displaying every beacon that the tilt puts out, every 2 seconds, like the TiltPi app shows.
  2. I also see a great benefit in consolidating this data into 1/5/10/15 minute intervals (30/150/300/450 samples) for graphing.
  3. I see a pretty good benefit in being able to throw out values that are outside of a reasonable limit.

Here is my graph of the current rum wash ferment. #1 would show better instantaneous readings, #2 would smooth the SG line a LOT, and #3 would take out the spikes that make using auto-scale impossible...

upload_2019-9-15_11-43-38.png



here it is using auto-scale:
upload_2019-9-15_11-44-33.png

*note - if you have not seen my graphs before, this is fairly normal, unfermentables in molasses such as cellulose cause final SG to be in the 1.04x range, and the vertical jumps in SG are from adding sterilized, thinned molasses in stages as to not stress the yeast with a 1.120+ initial pitch, 80-90 of which is fermentable)
 
Spent a bit of time on the aberrant readings... I think it has to do with the simultaneous BT and WiFi radio transmissions... unlike most applications, the interface firmware needs to keep rolling, so it can't stop to wait for packets to come in and put Wi-Fi transmissions on hold. Just need some more time to get it worked out. Working on the SPI thing first tho!
 
And in the meantime, we're about ready to release this bad-boy (well, that's my opinon... you'll decide...)

MEGA UniShield-3.jpg


MEGA UniShield-1.jpg


MEGA UniShield-2.jpg


This is the MEGA Uni-Shield. It is a shield for MEGA format interfaces such as the MEGA, Due, or Grand Central (shown here). It is a stacked design, containing a base board for I/O and a riser board for the interface. These are connected by ribbon cable, allowing for native shields to be used on top. It also contains an on-board 3A DC-DC buck converter to reduce the need for multiple power supplies in the panel. The buck converter can be powered with 12 or 24VDC and its output is adjustable from 3 to 24VDC. It's output can be switched to either supply the interface via its VIN pin (think 6-9 V here), supply the 5V pin directly thereby bypassing the interface's 5V regulator (no more overheating regulators), or to supply an onboard terminal, creating a discrete DC-D converter to be used for whatever reason you like (think extra 5V power supply for flowmeters, RTD-amps, etc.).

The baseboard contains 48 high-current outputs which are split into four banks, so you can power each with different sources (e.g. 5, 12, 24VDC) if desired. We'll have to finalize the power ratings per bank, but the drivers can actually output up to 2.5A per channel! This will eliminate any electro-mechanical relays which switch DC. So contactors, valves, relays, DC pumps can be powered directly. PWM will work too, so you could throttle down a DC pump without any additional hardware. This should reduce panel space and simplify wiring (the drivers are fault tolerant - for example, will not be damaged on a short-circuit). Each I/O terminal set includes a high-current driver output and a "direct" pin, allowing for digital inputs. We included fly-back diodes to damp inductive loads, so powering solenoids shouldn't be a problem. The model above has solder-pads to disconnect the high-current drivers, but we are considering swapping these for switches (need to consider the cost impact).

The shield also includes on-board pull-up resistors for I2C and 1-wire, so you can wire without external resistors easily enough. It also has jumpers for AREF, terminals for analog inputs, and SPI I/O, and a reset button. The unit is currently mounted in a DIN carrier, but we're going to source a metal case at some point, allowing the whole assembly to be protected and EMI shielded.

Figuring out pricing then will get it up on the site. We may also produce different versions for other interface boards like the ESP32.

EDIT: Current limits for the MEGA UniShield will be, the maximum of: 2.5A per output, 6A per driver (4 outputs each), 12A per bank (4 banks). Updated above per channel note.
 
Last edited:
I tried searching all afternoon, is there a way to evaluate if a script is running (evaluate from inside of another script)?

Code:
if "Script 1" State == true
 print "Script 1 Running"
endif

I eventually want to use it to have the bootloader script only allow one 'process script' to run at a time.. so I can eliminate the 6 different configurations I have, I am setting a digital output on when the bootloader starts a process script, and shutting it off before the process script exits, but if the script exits, the bootloader script still thinks it is running...
 
No, there is no way to check for a running script other than for some creativity... such as a global that the script continues to update every few iterations (think boolean ON then OFF etc) ... then another script can see if that value is changing. This is kinda like a watchdog - not ideal but a workaround in the meantime. I think we can add a check easily enough.
 
Responding to above post:

Code:
"Step Timer" Value = "Mash Timer" Value
This should work fine (does in my testing), as long as both 'Step Timer' and 'Mash Timer' are both timer elements or global elements (using either time or datetime type data). Also, you declare a time variable but don't use it in the example, so I'm not sure what your intention is there.

Code:
new time mashtmr
mashtmr = "Mash Timer" Value
"Step Timer" Value = mashtmr
This works fine. Are you sure you have 'Step Timer' as a Global with time type variable?

Code:
new string strikestatus
strikestatus = "Add " + "Strike Water Amount" Value + " gallons of water to MLT and " + "Sparge Water Amount" Value + " gallons of water to HLT."
"System Status" Value = strikestatus
You cannot do this because the interpreter cannot handle inline math yet.

Repository is a good idea. We have a user forum that isn't used much. I suppose that would be a PITA for users to bounce forums. Perhaps the HBT guys would be OK with a BC script thread? Happy to field suggestions here.

Importing is done via a third party interpreter. I think most are using NodeRed to read the XML and hand it to the Data Exchange protocol in BC. We do not have a native XML reader yet, and honestly have back-burnered it in favor of the data exchange. We could resurrect if enough support.

It seems I have Step Time as a Timer Element. I may have gone about this the wrong way, I just want to pass a user defined Time SP per step, to a generic Timer.

I guess I could just go with a new timer for every step, and selectively hide them based on the active step. My thought was that by having a step timer I can simplify the display, and new timed steps (EG additions) are easy to implement.

Long story short I am open to suggestions.
 
Last edited:
I'm not following you... Whatever is in quotes like "Step Timer" must be an element... that element has certain properties, like value. You need to use the reference a property that actually exists for that element, per the manual.

That said, if you are using a timer element on screen, you can continue to use it... just reset it as you go:

Code:
restart "Step Timer"
 
I'm not following you... Whatever is in quotes like "Step Timer" must be an element... that element has certain properties, like value. You need to use the reference a property that actually exists for that element, per the manual.

That said, if you are using a timer element on screen, you can continue to use it... just reset it as you go:

Code:
restart "Step Timer"

I am dumb. The error is coming from the line after. I was trying to calculate a "Remaining Time" and display it as a string. Did not work.

Seems like my major issues are all cleared up. I was able to simulate a brew-day step by step!!!

I was also able to use a WAV for a custom alarm sound (Alien Siren).
 
No doubt, scripting can be be one of those things where trees disappear in the forest! We have bounced around a pre-interpreter which could flag issues before they run, but haven’t got to it just yet.

This would be nice, but after about an hour in the interface, you should be able to catch it on your own. Or my own lol.
 
I am dumb. The error is coming from the line after. I was trying to calculate a "Remaining Time" and display it as a string. Did not work.

I was also able to use a WAV for a custom alarm sound (Alien Siren).

I use wave sounds to give verbal instructions, warnings etc.
 
I am dumb. The error is coming from the line after. I was trying to calculate a "Remaining Time" and display it as a string. Did not work.

I was also able to use a WAV for a custom alarm sound (Alien Siren).

I use wave sounds to give verbal instructions, warnings etc.
 
I am dumb. The error is coming from the line after. I was trying to calculate a "Remaining Time" and display it as a string. Did not work.

I was also able to use a WAV for a custom alarm sound (Alien Siren).

I use wave sounds to give verbal instructions, warnings etc.
 
Funny... we talked about porting the FW over. It’s mostly possible though I’m not sure the benefit over a microcontroller? RPi runs an OS which is not real-time so certain timings will not be accurate. May not matter for brewing but unless the reward:risk is very positive, it’s tricky to jump in willingly.
 
yeah, it would have to come with a big disclaimer that any other software running on it might screw the pooch... One thing I know is that I can SSH and reboot a Pi ZeroW, and I cannot do that to a ESP32/8266.... walking up and down stairs is good exercise, but getting tiresome...
 

Well, the ESP is plugged into BruControl Laptop for usb power, so....

and those have an ESP8266/ESP8285/ESP32 in them, so...

FYI - have several of the iTead.cc items such as the SonOff Dual, SonOff TH10, SonOff S31, SonOff 4ch Pro, and even the new T1 touchless light switch... The Dual I use quite a few of, and they have issues that I have been so far unable to capture the log file of them failing... maybe an on-board watchdog reset could be possible......
 
@BrunDog How can I achieve something like this below? I want to be able to compare the current time to a time variable or global without a date attached to it. As far as I can tell I have to use a datetime variable and keep adding one day to it once every 24 hrs to get things to happen at a specific time each day.

time_failure.PNG
 
I am starting to write my scripts:


I have a Big Mac Element (a huge HLT) that I want to heat using Hysteresis


I also have a switch "Big Mac" to control the script

I want my switch status script to constantly check the status of switches and buttons.




//script scrSwithStatus

[Loop]

//Big Mac Switch

if “Big Mac” == true

sleep 100

start “scrBigMacEnabled”

else

“Big Mac Element” enabled = false

start “scrBigMacEnabledFalse”

endif

Goto “Loop”


In the simplest terms


// script scrBigMacEnabled

“Big Mac Element” enabled = true

//other script items


// script scrBigMacEnabledFalse s

“Big Mac Element” enabled = false

//other script items

start “scrFillMLT_with_Strike”


When I run the switch status it looks like it is doing what I ask, but the

scrBigMacEnabled and scrBigMacEnabledFalse script run then they are “paused”. Is there any issue with doing it this way. I have several other items dealing with probes and targets in both these scripts but did not show the code.


Should I stop the scripts as a good practice after they have finished rather than leave them paused?


// scrBigMacEnabled script

“Big Mac Element” enabled = true

//other script items


stop scrBigMacEnabled
 
Ok stop the insanity! The whole point of using a micro-controller is they don’t crash. When implemented correctly should run like little clocks and never need to be reset. If one needs this, then something is likely wrong with the power supply (flaky) or the code running on it (also flaky).

I’d like to understand why an ESP8266 needs resetting, because if it’s the latter of the two above, we need to fix it.

I have a Feather M0 running for about three years without a single hiccup. My BC computer goes down on occasion due to power failures or other reasons but that micro never stops running the two refrigerators it supports. It’s got a LiPo battery plugged into it so survives power flashes, but still. Granted this is a sample size of one, but this should be the goal.

Before you add some remote power hardware, let’s figure out what’s going on with that ESP8266.
 
@BrunDog How can I achieve something like this below? I want to be able to compare the current time to a time variable or global without a date attached to it. As far as I can tell I have to use a datetime variable and keep adding one day to it once every 24 hrs to get things to happen at a specific time each day.

View attachment 644735

Maybe both variables need to be the same type?
 
Are you running the latest firmware on the 8266? I had some problems with connectivity a couple versions back, and would have to reboot it for that but I haven't had any issues with the three of them I'm running since I upgraded the FW on them. You said it is plugged into the BC laptop, is it using the WiFi to talk or is it talking over serial?
 
Back
Top