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.
@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

Are you trying to trigger something on a particular time each day?
 
Am I on the right track here? Not sure if the GND pin on Salon Board denotes earth ground or if I run this to DC- as shown. For the sake of the build is DC- equivalent to ground?


Test Diagram.png
 
Last edited:
Functionally correct. In the DC world, ground is often called DC- (though it shouldn't be because negative voltage can exist). Earth ground is usually referenced in AC circuits.

You may confuse some people with the colors... red typically denotes +DC voltage and black ground. On the relay side, you could switch 24V through the relay coil (COM and NO) and have ground permanently connected.

Also, if you are using that valve, you will definitely need a flyback diode to squash it's inductive load spike.
 
Functionally correct. In the DC world, ground is often called DC- (though it shouldn't be because negative voltage can exist). Earth ground is usually referenced in AC circuits.

You may confuse some people with the colors... red typically denotes +DC voltage and black ground. On the relay side, you could switch 24V through the relay coil (COM and NO) and have ground permanently connected.

Also, if you are using that valve, you will definitely need a flyback diode to squash it's inductive load spike.
Got it Thank you for reviewing and clarification.

Moving forward I will use colors as you suggest. Regarding 24v through relay coil and ground permanently connected, isn't this what I have depicted?

Should the DC- or ground from
24v, 12v power supplies and mega (all components for that matter) be joined together at a common bus bar?

This is not the actual valve I am using. How do i know whether or not the flashback diode is needed? All text on this valve is in Chinese. The only thing legible is 24v DC
 
Yes, per your label you are switching 24V through the relay - my apologies.

DC- aka GND from all power supplies should be tied together. Ideally, all grounds tie to a single point to reduce ground loops.

Not sure if the value you are using is a solenoid (don't recommend for low pressure / high flow) or motorized ball valve (recommended). Maybe post a link or picture.
 
1568782903769777615111.jpg

We understand ball valves are superior but 4 of these came free with our fermenters and were on a budget. Looking to buy ball valves as we expand or as these fail
 
Last edited:
Got it. Those are solenoid valves. Not sure if you are controlling brewing liquid or fermenting (sounds like the latter). They should be ok for that temp but I’m not sure about contamination resistance. That’s just a random comment. Electrically, should be set for it to work - just add the diode.
 
Got it. Those are solenoid valves. Not sure if you are controlling brewing liquid or fermenting (sounds like the latter). They should be ok for that temp but I’m not sure about contamination resistance. That’s just a random comment. Electrically, should be set for it to work - just add the diode.
Do you mind providing a link to the proper diode?

If I want to hear the contacts close (while I wait for interface) on relay board, can I jumper the input pin from Mega to 12v DC+?
 
No, as that would put 12V on the MEGA’s I/O pin and it’s only 5V tolerant.

Jumper 5V from the MEGA’s 5V pin (this is the output of the regulator) to that pin. Make sure that pin is not ON via Active Low at that time since that would creat a short.
 
View attachment 644775
We understand ball valves are superior but 4 of these came free with our fermenters and were on a budget. Looking to buy ball valves as we expand or as these fail
just a heads up I am doing what you are planning now, I use 4 (much cheaper chinese 24v soleniod valves like these https://www.ebay.com/itm/12V-G1-2-N...534330?hash=item4d95318cfa:g:msgAAOSwq9Fc70~S ) on my 4 conical setup at home and 4 12v soleniod valves just like these https://www.ebay.com/itm/12V-DC-1-2...383753&hash=item215ce2f235:g:YzMAAOSwVZBdAKDo at my brewpub controlling coolant flow to 4 3bbl conicals and they have all worked flawlessly so far... the ones at home for 5-6 years now and the ones at the brewery for 6 months. I use regular dual contact (dual pole) din rail relays to activate the main 120v chiller pumps for recirculating coolant through the manifold at the same time one or more of the 12v valves are opened through the other set of contacts.

I did have to add diodes as the electrical noise would cause my one wire and rtd temp probes to spike from the noise. my thermister probes did not spike however.

I dont know how big your fermenters are but we use 1/2" valves which work fine since we have tiny 3/8" quick disconnects on our chiller lines restricting them further.
But we are upgrading to 3.5bbl unitanks that are on order and will be stepping our valves up to 3/4" then I think. we also have dual zone jackets which means I need to build a liquid heating system vs the heat wrap setup we use now.
 
Last edited:
No, as that would put 12V on the MEGA’s I/O pin and it’s only 5V tolerant.

Jumper 5V from the MEGA’s 5V pin (this is the output of the regulator) to that pin. Make sure that pin is not ON via Active Low at that time since that would creat a short.
I don't mean jumper from the interface but rather jump from 12v+ to the in-1 pin that the interface would normally connect to. Strictly for testing
 
just a heads up I am doing what you are planning now, I use 4 (much cheaper chinese 24v soleniod valves like these https://www.ebay.com/itm/12V-G1-2-N...534330?hash=item4d95318cfa:g:msgAAOSwq9Fc70~S ) on my 4 conical setup at home and 4 12v soleniod valves just like these https://www.ebay.com/itm/12V-DC-1-2...383753&hash=item215ce2f235:g:YzMAAOSwVZBdAKDo at my brewpub controlling coolant flow to 4 3bbl conicals and they have all worked flawlessly so far... the ones at home for 5-6 years now and the ones at the brewery for 6 months. I use regular dual contact (dual pole) din rail relays to activate the main 120v chiller pumps for recirculating coolant through the manifold at the same time one or more of the 12v valves are opened through the other set of contacts.

I did have to add diodes as the electrical noise would cause my one wire and rtd temp probes to spike from the noise. my thermister probes did not spike however.

I dont know how big your fermenters are but we use 1/2" valves which work fine since we have tiny 3/8" quick disconnects on our chiller lines restricting them further.
But we are upgrading to 3.5bbl unitanks that are on order and will be stepping our valves up to 3/4" then I think. we also have dual zone jackets which means I need to build a liquid heating system vs the heat wrap setup we use now.
Good to hear the cheaper valves are working for you. We are running 10bbl fermenters but with only 6bbl full.
Can you share the diode you mention perhaps point me in the right direction for wiring correctly?
 
Good to hear the cheaper valves are working for you. We are running 10bbl fermenters but with only 6bbl full.
Can you share the diode you mention perhaps point me in the right direction for wiring correctly?
I honestly dont remember the size I used... I had a whole bag of them and they were cheap on ebay. I will have to look at one to get the value, Brundog recommended I use them at the time.
 
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?

ESP32 is via usb, that one may be the 1-wire having a bad cable or something... they always have latest code because of the availability of OTA upgrades.

ESP8266 (actually ESP8285 inside SonOff Dual, some v1.2, some v1.4) connected via WiFi. Cisco 1831 AP's, rock solid network, that is my day job.... They just go wonky, could be AC line signal issues, not sure... I have 8 of them, about half of them have the issue where after a couple days or weeks, they start bouncing in the 'interfaces tab', but in reality, they are 100% down as pointed out by brundog earlier..

edit: most are on v45C
 
Last edited:
ESP32 is via usb, that one may be the 1-wire having a bad cable or something... they always have latest code because of the availability of OTA upgrades.

ESP8266 (actually ESP8285 inside SonOff Dual, some v1.2, some v1.4) connected via WiFi. Cisco 1831 AP's, rock solid network, that is my day job.... They just go wonky, could be AC line signal issues, not sure... I have 8 of them, about half of them have the issue where after a couple days or weeks, they start bouncing in the 'interfaces tab', but in reality, they are 100% down as pointed out by brundog earlier..

edit: most are on v45C

Pls make sure you are using the most recent FW (sounds like it) and most recent BC. We did have an issue recovering from serial communication failures. That should be fixed in the most recent build.
 
No, as that would put 12V on the MEGA’s I/O pin and it’s only 5V tolerant.

Jumper 5V from the MEGA’s 5V pin (this is the output of the regulator) to that pin. Make sure that pin is not ON via Active Low at that time since that would creat a short.
I was saying to wire something like this just to see the solenoid fire.

When you say to make sure the pin is not on Active low at the time. Is this a BruControl setting?
Test Diagram2.png
 
Yeah that’s fine. I was saying if you wanted to jump it while it was tied to the MEGA’s I/O pin, that’s ok but only use +5V. While you are doing that, if running BC, need to make sure that device is disabled in the software, because in the very rare circumstance you had it enabled, ON, and active low switch set, it would be grounded, causing a short through the chip.
 
Maybe both variables need to be the same type?

That's the problem. How do I capture the current time into a time variable? now returns a datetime variable and the scripting engine throws an exception when I assign it to a time variable instead of handling it and casting it into a time variable.

time_failure_2.PNG
 
That's the problem. How do I capture the current time into a time variable? now returns a datetime variable and the scripting engine throws an exception when I assign it to a time variable instead of handling it and casting it into a time variable.

View attachment 644862

I’m not the expert, but what if you used a datetime type instead of a time type variable for the current time. Also looks like “now” might only works with datetime type variables.
 
Here you are @crane. BTW We discussed this previously in post 2399, but this is a new script I wrote before finding that.

This uses a Global to keep a permanent time. You could just use a local datetime variable if preferred, but that will not keep a permanent date in the future if you stop the script.

Code:
//Script to trigger an event once per day.
//Needs a Gobal named "Trigger Time" with variable type DateTime

new datetime trigger
new datetime current
[loop]
current = now
if current > "Trigger Time" value
print "Triggered"
trigger = current + 1:00:00:00
"Trigger Time" value = trigger
endif
sleep 5000
goto "loop"
 
That's not what I asked. I asked if there was any other way to do this other than having to add 1 day to a datetime variable. The example script below is nice and easy. Things get more complicated when you actually use the code. If your script doesn't run for a day then the next time you start up the date is behind and it will run immediately not at the set time. You can circumvent this by always initializing the global when the script starts, but then you have to hard code your set time into the script which defeats the purpose of using the global to preserve the current settime across power cycles, etc.

All of this could be greatly simplified if we could get the current time in a time variable.
Here you are @crane. BTW We discussed this previously in post 2399, but this is a new script I wrote before finding that.

This uses a Global to keep a permanent time. You could just use a local datetime variable if preferred, but that will not keep a permanent date in the future if you stop the script. The goal is to have a script that can auto start on its own without any human intervention and to not have to keep changing default values in the script.

Code:
//Script to trigger an event once per day.
//Needs a Gobal named "Trigger Time" with variable type DateTime

new datetime trigger
new datetime current
[loop]
current = now
if current > "Trigger Time" value
print "Triggered"
trigger = current + 1:00:00:00
"Trigger Time" value = trigger
endif
sleep 5000
goto "loop"
 
That's not what I asked. I asked if there was any other way to do this other than having to add 1 day to a datetime variable. The example script below is nice and easy. Things get more complicated when you actually use the code. If your script doesn't run for a day then the next time you start up the date is behind and it will run immediately not at the set time. You can circumvent this by always initializing the global when the script starts, but then you have to hard code your set time into the script which defeats the purpose of using the global to preserve the current settime across power cycles, etc.

All of this could be greatly simplified if we could get the current time in a time variable.
Agreed, a 24hr clock intrinsic variable would be useful.
 
Should you put a stop "scriptname" at the end of scripts as a good practice? I noticed that when one calls a script from another script, it is "paused" after running. I am not looking for a critique of my simple scripts as I am trying to figure out scripting and am very early in my learning curve. I just want to know if this is a good practice to always stop your scripts. I know it is not mandatory because it works fine if paused.
stop script.png
 
I think it's a good practice to get in the habit of doing for sure. I treat the paused state as an error (since that is what it typically is), and set alarms when scripts go into that state.
 
I think it's a good practice to get in the habit of doing for sure. I treat the paused state as an error (since that is what it typically is), and set alarms when scripts go into that state.
Thanks. I am not sure why you get an error after the last command but I will do use the stop command as a good practice.
 
Typically, the interpreter pauses when there is an invalid instruction and/or it doesn't know what to do. In the case of your script, it is reaching the end of its instruction set and without a stop or goto command it doesn't know what to do. Instead of crashing, it pauses which allows you to see what happened, stop and debug the code, or advance the process.
 
That's not what I asked. I asked if there was any other way to do this other than having to add 1 day to a datetime variable. The example script below is nice and easy. Things get more complicated when you actually use the code. If your script doesn't run for a day then the next time you start up the date is behind and it will run immediately not at the set time. You can circumvent this by always initializing the global when the script starts, but then you have to hard code your set time into the script which defeats the purpose of using the global to preserve the current settime across power cycles, etc.

All of this could be greatly simplified if we could get the current time in a time variable.

My apologies for not reading your request carefully. You just want a time of day, then check when that time gets crossed (basically ignoring the date)?

I’ll have to research and test that. What about using a timer that triggers an action at a certain time and is also reset?
 
Correct that I just want to get the current time without the date. It would also be nice to have more date/time functionality like adding or subtracting a value with just the hour, min, day, etc.

As far as using a timer, I'm struggling to figure out how you can have a script startup and read a global time variable and set a timer correctly such that it triggers something.

The goal is to use globals to preserve setpoints throughout power cycles, not have to start and stop the script to update hard coded startup values, and to not have to any human intervention to update stale datetime globals when the script auto starts upon bootup.
My apologies for not reading your request carefully. You just want a time of day, then check when that time gets crossed (basically ignoring the date)?

I’ll have to research and test that. What about using a timer that triggers an action at a certain time and is also reset?
 
Pls make sure you are using the most recent FW (sounds like it) and most recent BC. We did have an issue recovering from serial communication failures. That should be fixed in the most recent build.

It looks like it was v45 (no suffix), but another nearby was the same with no issues... so I upgraded both.. so I climbed up on the wall and removed it from it's box and upgraded, then climbed up and replaced it... and now it is not reading temps at all... arrgggg...
upload_2019-9-20_6-37-3.png


Since 8285's are like 8266's but with 1mb of flash, can we enable the ability to OTA program them? That would make life much easier and eliminate human error of whatever I did..
 
I think it's a good practice to get in the habit of doing for sure. I treat the paused state as an error (since that is what it typically is), and set alarms when scripts go into that state.
Looking at scripts commands, I also assume that it is a good practice to use the clear command when you are done with a variable.
 
Yes, it’s good practice to use the “delete” statement to eliminate a variable which is no longer being used. Likely no harm if you don’t - the variable will just sit there and take up a few bits of memory.

The “clear” statement deletes them all. I’m honestly not sure there is utility for it, unless you are certain your script no longer needs any. You don’t need to do it before the script ends (with “stop”) because the interpreter will handle it upon terminating the script.
 
It looks like it was v45 (no suffix), but another nearby was the same with no issues... so I upgraded both.. so I climbed up on the wall and removed it from it's box and upgraded, then climbed up and replaced it... and now it is not reading temps at all... arrgggg...
View attachment 645023

Since 8285's are like 8266's but with 1mb of flash, can we enable the ability to OTA program them? That would make life much easier and eliminate human error of whatever I did..

Keep us informed! Remember you can reset the bus with ‘%4’.
 
As far as writing scripts:

I am looking for opinions >

Really long script or divide and conquer.

For example, on the BCS I had a Hop Process and a Boil Process that run concurrently. Would it be better to write separate scripts or combine them? I know it is a personal preference, but I would think that running concurrent scripts would be easier to troubleshoot and update.

I do understand call subroutine and the start , stop , pause, and resume scripts.

My gut feeling is lots of separate scripts.
One for Preheat up to Strike
One for Mash
One for Sparge
One for Boil
One for Hop and other additions
Post Boil Whirlpooling and Cooling and Pitching
A Separate Script for any Fermentation (we have 4 fermentors, one glycol chilled and others also temp controlled via a coolbot and a room Window AC in a fermentation room.

Since there are Globals, I do intend to write a script that updates things like Strike, Mash, and Hop Additions so I can do different brews. We generally make the same Brew time after time, so I might have a script for my "Raborker Altbier" and a different script for my "St. Michael's Rauschbier" to set all the parameters with a single click on a Workspace of my recipes.

Just looking for some opinions from advanced users before I really get into the heart of coding the scripts.
 
Keep us informed! Remember you can reset the bus with ‘%4’.

OK, I spent a few hours... I cannot get any of my SonOff Duals to work with 1-wire and v45, the same pin works with the flowmeter in v45, and the 1-wire works if I downgrade to v43

setup - BC 1.1 build 4, SonOff dual (ESP8285) on my desk, simple 1-wire and 4.7k right to the sonoff, no cables, no other connectors , 6 inch leads... I have the interface configured and 2 temp probes and a digital output configred in BC.. the same 1-wire works on the ESP32 right next to it...


Code:
SonOff Dual downgraded to v43 and the one 1-wire shows temp 82.62

BruControl v43A.W Debug:1
Rsp:%1;
End:488644
Beg:488667
Msg:?200?201;
Rsp:?200=8262?#;
End:488668
Beg:490306


Same interface upgraded to 45(a), power cycled, and connected, Temperature does not work. The Digital output does work, but not shown here:

BruControl v45.W Debug:1
Rsp:%1;
End:42627
Beg:42945
Msg:?200?201;
Rsp:?#?#;
End:42947
Beg:44031
Msg:?200?201;
Rsp:?#?#;


and upgraded to 45C and no change:
BruControl v45C.W Debug:1
Rsp:%1;
End:22168
Beg:22958
Msg:?200?201;
Rsp:?#?#;
End:22960
Beg:23983
Msg:?200?201;
Rsp:?#?#;


I then completely removed the interface from BC(which removed the devices) and re-installed as a differrent named interface with newly named devices on same ports, still no temps:

BruControl v45C.W Debug:1
Rsp:%1;
End:43066
Beg:43302
Msg:?200?201;
Rsp:?#?#;
End:43304
Beg:44329
Msg:?200?201;
Rsp:?#?#;



Then as a last ditch, I re-downgraded back to v43 and BAM... the temp works again:
BruControl v43A.W Debug:1
Rsp:%1;
End:65358
Beg:66017
Msg:?200?201;
Rsp:?200=8217?#;
End:66018
Beg:67096
Msg:?200?201;
Rsp:?200=8217?#;
 
Last edited:
For future versions, have you guys thought about a having a way to clear historical data (like clearing a graph that has some garbage on it from when I was messing with the calibration math)?


One other thing that I was wondering is if there could be a way to say whether to log data for something or not? Right now, I think it remembers everything. There are lots of things I don't care about the history of, so I have no need to log that information.
Granted, storage is cheap so maybe it is a big "don't care", or a "it isn't structured that way" type of thing. Just thought I would ask.
 
As far as writing scripts:

I am looking for opinions >

Really long script or divide and conquer.

For example, on the BCS I had a Hop Process and a Boil Process that run concurrently. Would it be better to write separate scripts or combine them? I know it is a personal preference, but I would think that running concurrent scripts would be easier to troubleshoot and update.

I do understand call subroutine and the start , stop , pause, and resume scripts.

My gut feeling is lots of separate scripts.
One for Preheat up to Strike
One for Mash
One for Sparge
One for Boil
One for Hop and other additions
Post Boil Whirlpooling and Cooling and Pitching
A Separate Script for any Fermentation (we have 4 fermentors, one glycol chilled and others also temp controlled via a coolbot and a room Window AC in a fermentation room.

Since there are Globals, I do intend to write a script that updates things like Strike, Mash, and Hop Additions so I can do different brews. We generally make the same Brew time after time, so I might have a script for my "Raborker Altbier" and a different script for my "St. Michael's Rauschbier" to set all the parameters with a single click on a Workspace of my recipes.

Just looking for some opinions from advanced users before I really get into the heart of coding the scripts.

Sequential steps could be in one long script or separate ones with one starting the next before self terminating. I think the former is better since you can keep and reference your variables throughout.

Obviously parallel scripts can run simultaneously to multi-task your operations. You can have one master run the others.
 
Back
Top