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.
No lie, I literally just ran into this myself about 20 minutes ago…. Tried to install SQLLocalDB and it failed. Found same note online.
Yes, we’ll update documents.
No evil intention with this post.
But I think we had an exchange regarding the same issue in private messages on 23.Sept.2020. It's amazing that you are able to cope with all the issues and posts(questions) people are asking. @BrunDog. Thank you for that!

Whatever is the best solution, should be in the doc. I'll repost what worked for me, although not ideal.
 
Last edited:
Sep 23, 2020 Just in case someone finds it useful, when upgrading from 1.1 to 1.2 beta




[SNIP]
It seems I can get trough last step when it's starting VSS services. That times out, service is not started and installation is rolled back.
I know it looks pretty stupid, but my admin account has log on as a service right, too. I did try to start service manually with other accounts, but I wasn't able.
Searched internet, but can't find solution yet.
Did you experience such issues ?

I have Windows 10 Pro ( Build 19041) OS is 64bit.


1600808789169.png
1600808805834.png


_______

The solution was for me:



I tried everything I know, but it wouldn't work to install LocalDB from your MSI.

What I did - you'd have to install the full SQL Express and then uninstall most of it.

I first acquired the MSI install file SQL2019-SSEI-Expr - SQL Server Express 2019.
Then by running the GUI for the SQL Server 2019 Express Edition installer and selecting the “Custom” option.

1600844345375.png


Leave default selection + you need to select LocalDB option during install - check both Instance Features -> Database Engine Services and Shared Features -> LocalDB in the Feature Selection pane. This action have installed LocalDB but also SQL instance.

Then you'd need to uninstall the SQL Server express instance separately:
  1. Go to your Control Panel Add/Remove, or Programs/Uninstall a program.
  2. Right click 'Microsoft SQL Server', and select uninstall.
  3. In the next dialog next, you will see 'Add', 'Repair' and 'Remove'. You will choose 'Remove', and then 'OK'.
  4. The next dialog is 'Select Instance', you will select the instance you want to uninstall, and click 'Next'.
  5. In the dialog where is 'Select Features', you could select features other than LocalDB, and then finish the uninstallation. Which will remove unneeded engine.
However, I do suspect that I have additional components. Could you please check on your PC which components are needed for LocalDB?

The following items remain in the Add/Remove Programs registry:
Microsoft ODBC Driver 17 for SQL Server
Microsoft OLE DB Driver for SQL Server
Microsoft SQL Server 2012 Native Client
Microsoft SQL Server 2019 T-SQL Language Service
Microsoft Visual C++ 2017 Redistributable (x64) - 14.14.26429.4
Microsoft Visual C++ 2017 Redistributable (x86) - 14.14.26429.4

My 1.2 Beta works now.

[SNIP]
 
Last edited:
I
Where does the other else go? Cant get it to work...

Code:
[Loop]

if "CS ROOF + ROOM HYSTERESIS" value == true
    if "CS ROOF HEATER HYSTERESIS" value == true
        "CS ROOF ACTIVE" value = Yes
    else "CS ROOF ACTIVE" value = No
    endif
else "CS ROOF ACTIVE" value = No
endif

sleep 1000
goto "Loop"
Use "enabled" not "value"? value is a number for HYSTERESIS
 
Also, this line is invalid:

if "CS ROOF + ROOM HYSTERESIS" value == true

I don't believe the interpreter is capable of inline math in an IF statement.
 
@exoticatom You are definitely right. I don’t think I understood the issue until I ran into it myself.

Your solution solved the problem, which is good. But for future installations, the simple pre-install of the VC redistributable solves the problem. I updated the Installation note per @clearwaterbrewer ‘s advice.
 
Also, this line is invalid:

if "CS ROOF + ROOM HYSTERESIS" value == true

I don't believe the interpreter is capable of inline math in an IF statement.
The plus sign should be read as the element name think of it as an "and" sign. I'm not trying to perform inline math.
does this work?
No that didn't work. I currently have all variations of the statement (true/false) working without utilizing "else" was wanting to get the else to work to shorten code and learn something new
 
I ran a test and it works correctly. You could eliminate the else statements by resetting the value on the way into the nested if's:

Code:
[Loop]
"CS ROOF ACTIVE" value = No
if "CS ROOF + ROOM HYSTERESIS" value == true
    if "CS ROOF HEATER HYSTERESIS" value == true
        "CS ROOF ACTIVE" value = Yes
    endif
endif
// need to act on the CS ROOF ACTIVE variable here, as it will be reset on next loop
sleep 1000
goto "Loop"
 
Seems odd to me that every one of my PT100s require a large negative offset (between -8 and -12F) to read correctly at boil and in slushy ice water. This is across 5 fermenters, hot side vessels and glycol loop. Any ideas what would cause this? I admit they are the cheap chinese ones...

https://www.amazon.com/Temperature-...cphy=9032297&hvtargid=pla-1395486940748&psc=1

If you have a decent meter... measure the resistance of each at these respective bounds (ice water and boiling water). See if the probes are off compared to a proper RTD chart. For example, at freezing (0 C), you should get 100 ohms, and at boiling (100 C) you should get 138.5 ohms.
 
I ran a test and it works correctly. You could eliminate the else statements by resetting the value on the way into the nested if's:

Code:
[Loop]
"CS ROOF ACTIVE" value = No
if "CS ROOF + ROOM HYSTERESIS" value == true
    if "CS ROOF HEATER HYSTERESIS" value == true
        "CS ROOF ACTIVE" value = Yes
    endif
endif
// need to act on the CS ROOF ACTIVE variable here, as it will be reset on next loop
sleep 1000
goto "Loop"

I see what you did there. I'll give that a shot. Thanks

If you have a decent meter... measure the resistance of each at these respective bounds (ice water and boiling water). See if the probes are off compared to a proper RTD chart. For example, at freezing (0 C), you should get 100 ohms, and at boiling (100 C) you should get 138.5 ohms.

I should be able to check resistance without any wires right, straight on the terminals of the probe?

While the topic is fresh, if I get the correct ohms I assume this would indicate a change in resistance because of wiring/length? If I do not get correct ohms perhaps these were made with their own chart/standard in mind?
 
You can measure it like the amplifier does. First measure the resistance of the wire loop. That’s the two wires of the same color, and will be a very low number, like a half an ohm. Then measure the sensor. Subtract the loop from the sensor resistance, and compare that to a Pt100 chart. If the sensor uses actual Platinum (doubt it if it’s an cheap knockoff), it should follow the chart mostly. If it doesn't, then you have your answer.

That said, @clearwaterbrewer and I both ran some tests and did see some variability with the RTD amplifiers. My tests showed pretty good accuracy but admittedly slightly off what what I expected. He saw differences with the same sensors on different amplifiers if I recall. You can search above or perhaps he'll summarize for us.
 
Does it happen with every I/O disconnected from the board? Some pins, like 12 if pulled high, will prevent the ESP from booting.
I'm using 12-14 to drive the relays and the 200s for the (3) 1-wire probes. Should I try new ports for the relays?
 
Last edited:
Has anyone tried to integrate these type of wireless bluetooth probes into a brucontrol build yet ? Inkbird Wireless Temperature
looks like battery life will be several months-1 year and some even have an lcd screen for remote temperature reading. Seems like they could be a game changer for avoiding probe wiring runs and quickly setting up multiple tanks in a bigger build.
 
If you were worried about BC communication interruption, you could keep the process on the same board by using 2 temp probes, and 2 hysteresis elements controlling 2 SPDT relays. Wire the heater circuit through the NC on 'FIN' relay to the NO on the 'Air Temp' relay and you've created an interlock of sorts. This setup would require no direct communication to BC and should be able to run on its own at its last setpoints should BC comms drop out.
Cold storage made it through a few days of testing (20' x 10'). This is with a wall mounted split unit and a roof mounted window unit.

For the NC on the FIN relay, I'll need to set the hysteresis to active high and jumper the pin on the relay board correct? I assume I need to reverse the logic on the control side since the circuit is NC. So cutout when cooling at setpoint.
 

Attachments

  • Screenshot_20210901-085332.png
    Screenshot_20210901-085332.png
    339.5 KB · Views: 12
Has anyone tried to integrate these type of wireless bluetooth probes into a brucontrol build yet ? Inkbird Wireless Temperature
looks like battery life will be several months-1 year and some even have an lcd screen for remote temperature reading. Seems like they could be a game changer for avoiding probe wiring runs and quickly setting up multiple tanks in a bigger build.
https://duino4projects.com/indooroutdoor-wireless-thermometer-using-arduino/
There seems to be a lot of these projects. There is also ink inbird hub that could take 4 sensors and repeat over a longer distance. It would be nice for no wires. Be nice to have (but beyond me).

As a side:

I have two "brewery" rooms. They are separated by a common wall so I could just run wires between them. One (my Fermentor Room), is in an Air Conditioned space. The Hot side is inside a barn. I have wifi extenders in both with free RJ45 jacks.

I was thinking of running wires (control and Temp) through the wall. It would be easier to simply add a "Fermentor" Mega (or ESP 32) interface. I was already going to have ESP 32s in the Fermentor Room for my Tilts.


I know the Mega well, but not so much for the ESP 32.


I will have 3 Tilts.





I already have an extra Mega that I use to control some items (so I can have the exact same Control look and feel on different Workspaces). I had not planed to use it except for this, but it could be in the Fermentor Room and have the Tilts, the Glycol pumps and associated Temperature Probes on it.

I would still need the ESP 32 bridge. Do I need 3 bridges? How many Tilts on one ESP 32?
 
Last edited:
Has anyone tried to integrate these type of wireless bluetooth probes into a brucontrol build yet ? Inkbird Wireless Temperature
looks like battery life will be several months-1 year and some even have an lcd screen for remote temperature reading. Seems like they could be a game changer for avoiding probe wiring runs and quickly setting up multiple tanks in a bigger build.

Battery part is interesting. You would need to translate the data from the source into BruControl via Data Exchange, and an intermediate handler like NodeRed.
 
Cold storage made it through a few days of testing (20' x 10'). This is with a wall mounted split unit and a roof mounted window unit.

For the NC on the FIN relay, I'll need to set the hysteresis to active high and jumper the pin on the relay board correct? I assume I need to reverse the logic on the control side since the circuit is NC. So cutout when cooling at setpoint.

You can reverse the hysteresis as needed. Or reverse the contacts on the relay.
 
@RiverCityBrewer, You say to run the NC fin relay through the NO air temp relay. I understand the interlock aspect of this suggestion but are you suggesting through NC to NO to prolong the life of the relay?
 
I'm working on a button that changes a global to indicate the status of a given fermenter. I was able to come up with the code below and all is working but not as intended, It wasnt till I went to add the other fermenters that I realized the flaw in the wait command. Looking for a solution to integrate all fermenters into one script as opposed to running various scripts for each fermenter. I tried eliminating the wait command as to trigger the next if statement but it didnt work as i expected. Is the following true?

Button not pressed = false
Button pressed = true
After button pressed = return to false

Why cant I say the button is now false and if true then do this?

Code:
[Setup]
"FV-1 STATUS" value = "CLEAN"

[Loop]
if "FV-1 BUTTON" State == true
"FV-1 STATUS" value  = CLEAN
"FV-1 BUTTON" State = false
endif

wait "FV-1 BUTTON" State == true

if "FV-1 BUTTON" State == true
"FV-1 STATUS" value  = SANITIZED
"FV-1 BUTTON" State = false
endif

wait "FV-1 BUTTON" State == true

if "FV-1 BUTTON" State == true
"FV-1 STATUS" value  = FERMENTING
"FV-1 BUTTON" State = false
endif

wait "FV-1 BUTTON" State == true

if "FV-1 BUTTON" State == true
"FV-1 STATUS" value  = CONDITIONING
"FV-1 BUTTON" State = false
endif

wait "FV-1 BUTTON" State == true

if "FV-1 BUTTON" State == true
"FV-1 STATUS" value  = DIRTY
"FV-1 BUTTON" State = false
endif

wait "FV-1 BUTTON" State == true

goto "Loop"
 
I don't like buttons because of their logic. I use switches instead and have an easier time with logic as I can tell the state (true or false) , which you cannot with a button.

Besides that, I would use another global value element to set the state. I would have it so I could edit just in case I wanted manually to set the "status" back if I clicked my switch by accident.

You could still use a switch to change the state, but the switch would increment the value of your global value element and after the last status, reset it to something like "Dirty"


I do not have a computer right now to test but I think this is good. It may need some tweaking.

global value element is gblVFV1Number
"FV1 Switch" is a switch element


[Setup]
// You may manually set the "gblVFV1Number" for your status. When it starts it is 0.
gblVFV1Number = 0
"FV1 Switch" state =false
[loop]
wait "FV1 Switch" state == true
if gblVFV1Number == 0
"FV-1 STATUS" value = Dirty
goto "Ender"
endif
if gblVFV1Number == 1
"FV-1 STATUS" value = Clean
goto "Ender"
endif
if gblVFV1Number == 2
"FV-1 STATUS" value = SANITIZED
goto "Ender"
endif
if gblVFV1Number == 3
"FV-1 STATUS" value = SANITIZED
goto "Ender"
endif
if gblVFV1Number == 4
"FV-1 STATUS" value = FERMENTING
goto "Ender"
endif
if gblVFV1Number == 5
"FV-1 STATUS" value = CONDITIONING
gblVFV1Number = -1
"FV1 Switch" state = false
goto "Loop"
endif
[Ender]
gblVFV1Number += 1
"FV1 Switch" state = false
goto "Loop"
 
I don't like buttons because of their logic. I use switches instead and have an easier time with logic as I can tell the state (true or false) , which you cannot with a button.

Besides that, I would use another global value element to set the state. I would have it so I could edit just in case I wanted manually to set the "status" back if I clicked my switch by accident.

You could still use a switch to change the state, but the switch would increment the value of your global value element and after the last status, reset it to something like "Dirty"


I do not have a computer right now to test but I think this is good. It may need some tweaking.

global value element is gblVFV1Number
"FV1 Switch" is a switch element


[Setup]
// You may manually set the "gblVFV1Number" for your status. When it starts it is 0.
gblVFV1Number = 0
"FV1 Switch" state =false
[loop]
wait "FV1 Switch" state == true
if gblVFV1Number == 0
"FV-1 STATUS" value = Dirty
goto "Ender"
endif
if gblVFV1Number == 1
"FV-1 STATUS" value = Clean
goto "Ender"
endif
if gblVFV1Number == 2
"FV-1 STATUS" value = SANITIZED
goto "Ender"
endif
if gblVFV1Number == 3
"FV-1 STATUS" value = SANITIZED
goto "Ender"
endif
if gblVFV1Number == 4
"FV-1 STATUS" value = FERMENTING
goto "Ender"
endif
if gblVFV1Number == 5
"FV-1 STATUS" value = CONDITIONING
gblVFV1Number = -1
"FV1 Switch" state = false
goto "Loop"
endif
[Ender]
gblVFV1Number += 1
"FV1 Switch" state = false
goto "Loop"
Without running through testing this is seems your adding a value each time the switch is pressed and it automatically returns the switch to false. Each increment then reports the status to the global.
Why can't we control the state of the button?

Also, I think I'll have an issue with the wait command as my goal is to have all fermenters addressed in one script. In other words I can't "wait" for FV 1 if I'm editing FV 2s status
 
Last edited:
You would need to just duplicate everything for each fermentor

You would need a switch for each fermentor. You could use just an if statement instead of the wait to check state of switch
 
You would need to just duplicate everything for each fermentor

You would need a switch for each fermentor. You could use just an if statement instead of the wait to check state of switch
I'll see if I can re write this using your example to make use of multiple fermenters. Thanks for the help!
 
I got my computer working and did some tweaking.

I forgot that the += operand does not work with Globals

Regardless I created the following Elements:

Global Element String Type FV1 : Fermentor 1 Status
Global Element String Type FV2 : Fermentor 2 Status
Global Element Value Type Precision 0 gblV_FV1 : Numeric status of Fermentor 1
Global Element Value Type Precision 0 gblV_FV2 : Numeric status of Fermentor 2
Button Element btnFV1 : Button to control FV1
Button Element btnFV2 : Button to control FV2

This Code worked with a Button.
I had to look at some of my AutoSwitch code where I do this. The AutoSwitch code I have is like a housekeeping code that takes care of things like this. It is several of these types of things. I control my brew steps with a number that is incrementally increased just like the code below. This script runs constantly when I am using Brew Control and may call other Scripts (or Kill them) depending on the incremental number.

If you did want the gblV_FV1 and gblV_FV2 you could move them to a different workspace or make them hidden. I have a Workspace where I place all of these if I don't want them to show. That is because my Workspaces are so crowded but when testing, I like to be able to see them if I need to.

Downside of using Globals is they are recorded in the Database and are of no importance to log.

Using nested if endif statement allows the code to check the status of each button rather than a wait statement.
:

[Loop]
// Fermentor Status 1
if "btnFV1" state == true
if "gblV_FV1" value == 0
"FV1" value = "DIRTY"
goto Ender1
endif
if "gblV_FV1" value == 1
"FV1" value = "CLEAN"
goto Ender1
endif
if "gblV_FV1" value == 2
"FV1" value = "FERMENTING"
goto Ender1
endif
if "gblV_FV1" value == 3
"FV1" value = "CONDITIONING"
"btnFV1" state = false
"gblV_FV1" value = 0
goto Loop
endif
goto Loop
endif
// Fermentor 2
if "btnFV2" state == true
if "gblV_FV2" value == 0
"FV2" value = "DIRTY"
goto Ender2
endif
if "gblV_FV2" value == 1
"FV2" value = "CLEAN"
goto Ender2
endif
if "gblV_FV2" value == 2
"FV2" value = "FERMENTING"
goto Ender2
endif
if "gblV_FV2" value == 3
"FV2" value = "CONDITIONING"
"btnFV2" state = false
"gblV_FV2" value = 0
goto Loop
endif
endif
goto Loop
[Ender1]
"btnFV1" state = false
new value varFV1
varFV1 = "gblV_FV1" value
varFV1 += 1
gblV_FV1 value = varFV1
delete varFV1
goto Loop
[Ender2]
"btnFV2" state = false
new value varFV2
varFV2 = "gblV_FV2" value
varFV2 += 1
gblV_FV2 value = varFV2
delete varFV2
goto Loop

xx.png
 
Last edited:
I'm working on a button that changes a global to indicate the status of a given fermenter. I was able to come up with the code below and all is working but not as intended, It wasnt till I went to add the other fermenters that I realized the flaw in the wait command. Looking for a solution to integrate all fermenters into one script as opposed to running various scripts for each fermenter. I tried eliminating the wait command as to trigger the next if statement but it didnt work as i expected. Is the following true?

Button not pressed = false
Button pressed = true
After button pressed = return to false

Why cant I say the button is now false and if true then do this?

Code:
[Setup]
"FV-1 STATUS" value = "CLEAN"

[Loop]
if "FV-1 BUTTON" State == true
"FV-1 STATUS" value  = CLEAN
"FV-1 BUTTON" State = false
endif

wait "FV-1 BUTTON" State == true

if "FV-1 BUTTON" State == true
"FV-1 STATUS" value  = SANITIZED
"FV-1 BUTTON" State = false
endif

wait "FV-1 BUTTON" State == true

if "FV-1 BUTTON" State == true
"FV-1 STATUS" value  = FERMENTING
"FV-1 BUTTON" State = false
endif

wait "FV-1 BUTTON" State == true

if "FV-1 BUTTON" State == true
"FV-1 STATUS" value  = CONDITIONING
"FV-1 BUTTON" State = false
endif

wait "FV-1 BUTTON" State == true

if "FV-1 BUTTON" State == true
"FV-1 STATUS" value  = DIRTY
"FV-1 BUTTON" State = false
endif

wait "FV-1 BUTTON" State == true

goto "Loop"


It's kinda difficult to debug these scripts taken out of context of their Workspaces and Elements... You are just trying to use a button to change the Global (which shows a status), and your code works (I just tested it). But the wait statement isn't flawed necessarily... the script execution holds on that line until its condition is met (or it times out if included).

Here is a way to tackle this without wait statements. It uses a local variable to count up each time the button is pressed, then the correct string value is loaded into the global value with each pass. You can mirror the code across however many fermenters as you like. Now, hardcore coders might not like updating the global every pass when it hadn't actually changed, and we can add a comparator local variable to see only when it changed, but this code isn't going to bog down the script interpreter much.

Alternatively, you could use the

Code:
[Setup]
new value FV-1
new value FV-2
FV-1 = 0
FV-2 = 0

[Loop]
if "FV-1 BUTTON" State == true
FV-1 += 1
if FV-1 >= 5
FV-1 = 0
endif
"FV-1 BUTTON" State = false
endif

if "FV-2 BUTTON" State == true
FV-2 += 1
if FV-2 >= 5
FV-2 = 0
endif
"FV-2 BUTTON" State = false
endif

if FV-1 == 0
"FV-1 STATUS" value = "CLEAN"
endif

if FV-1 == 1
"FV-1 STATUS" value = "SANITIZED"
endif

if FV-1 == 2
"FV-1 STATUS" value = "FERMENTING"
endif

if FV-1 == 3
"FV-1 STATUS" value = "CONDITIONING"
endif

if FV-1 == 4
"FV-1 STATUS" value = "DIRTY"
endif

if FV-2 == 0
"FV-2 STATUS" value = "CLEAN"
endif

if FV-2 == 1
"FV-2 STATUS" value = "SANITIZED"
endif

if FV-2 == 2
"FV-2 STATUS" value = "FERMENTING"
endif

if FV-2 == 3
"FV-2 STATUS" value = "CONDITIONING"
endif

if FV-2 == 4
"FV-2 STATUS" value = "DIRTY"
endif

sleep 100
goto "Loop"
 
Last edited:
Here is another way to do it, with the comparisons being based on the previous status... might be cleaner. Note that the local variable 'Status1' is used because the interpreter can't compare a global property (need to fix that!). You would need to copy it for the 2nd+ fermenters.

Code:
[Setup]
"FV-1 STATUS" value = "CLEAN"
new string Status1

[Loop]
Status1 = "FV-1 STATUS" Value
if "FV-1 BUTTON" State == true
if Status1 == "CLEAN"
"FV-1 STATUS" value = "SANITIZED"
endif
if Status1 == "SANITIZED"
"FV-1 STATUS" value = "FERMENTING"
endif
if Status1 == "FERMENTING"
"FV-1 STATUS" value = "CONDITIONING"
endif
if Status1 == "CONDITIONING"
"FV-1 STATUS" value = "DIRTY"
endif
if Status1 == "DIRTY"
"FV-1 STATUS" value = "CLEAN"
endif
endif
"FV-1 BUTTON" State = false

sleep 100
goto "Loop"
 
Its interesting to see the various ways to perform the same goal. The second one @BrunDog sent seems pretty elegant. Thankyou for the help guys
 
Still having issues with random Mega disconnects after adding the third RP 3 board. @BrunDog this is the same issue we tried to diagnose a while back to no avail, you recommended having various interfaces as to not rely too heavily on any one. I currently have Mega 3560 controlling/monitoring hot side and cold side..that is HLT, MLT, Kettle, CLT, Glycol loop and Fermenters 1 thru 4. I also have ESP32 controlling the cold storage.

I've been able to get by with the two RP3 boards on the Mega but with our grand opening soon I'm thinking about adding a third.

Any suggestions on an interface? Thinking about keeping FV-1 thru 4, CLT and Glycol loop monitor on the Mega (utilizing 2 RP3s) and add the new interface for the hotside with one RP3. Keep the ESP32 solely for cold storage.

Also considering phasing out the PT100s and eliminating the amplifier boards..thoughts?
 
Last edited:
"But the wait statement isn't flawed necessarily... the script execution holds on that line until its condition is met (or it times out if included)."

The problem with using a wait in this case, that the code stops until the condition is met. Since he wanted to change the status of different fermenters in the same script, nested if are the ticket. In your brilliant second example, you did use the nested if for the buttons (and no Globals to log). If using separate Scripts, the wait would work.

I ran into this early when trying to learn scripting.


I use wait when I wish for a certain condition to be met before proceeding and the script stops.

I use nested ifs when I want to have the code continue on.

I also use it as you did in your examples instead of the wait statement in my housekeeping code as I want to check several variables or conditions rather than just one.

You can loop through nested ifs to have the following AND logic (a and b must be true at the same time)

[Loop]
if a == true
If b == true
//do something if both are true.
goto Ender
go to Loop
end if
endif
[Ender]

or for OR logic.

[Loop]
if a == true
//do something (same Thing or branch)
goto Ender
end if
If b == true
//do something (same Thing or branch)
goto Ender
endif
go to Loop
[Ender]



My code was verbose.
 
Just fired up the Olimex ESP32-EVB-EA as I noted in post BruControl: Brewery control & automation software.

Dang... for $45 (a bit more now than when I paid for it) this is a pretty easy fermenter controller (1x heating and 1x cooling relay). You would have to solder in 3 wires and a resistor to get 1-wire sensor integration, but that's not too hard. Needs a 5V power supply, but with wire terminals, a LiPo battery plug, box and external antenna, it's a very easy & quick option.

Just sayin!
Just bought on of these. Gonna give it a try!
 
Back
Top