BrewManiacEx Release v0.2

New features

  • Recipes management
    • Import BeerXML
    • View and brew recipes

Bugs fixed:

  • No logging if the automatic process is interrupted and power-off or entering manual mode before resumption.
  • Wrong hop schedule of automation editing


  • Add a minimum limit of time(500ms) for sensor reading. Without this limitation, the system will be busy trying to get temperature readings when the sensors are not correctly connected and response with error.

About Recipes

The recipes are created by import of BeerXML. The imported BeerXML should have the following information so that it can be used and translated as automation settings:

  • Boil time
  • Mash profile

The following fields are also referenced if available

  • Hop and other additions schedules
    • The information will be translated into time of “Hop#1”, “Hop #2”, etc.
  • Water amount of first mash step
    • If the mash-in temperature is set to “calculated”, this field is used in the formula to derive mash-in temperature.

Other fields are display only.

Recipe Options



  • The unit setting is for displaying the recipe only.
  • Mash-in temperature will be inserted automatically based on the settings. The formula to calculate mash-in temperature is based on Palmer’s formula.

    Temp = R * [Grain weight] / [Water amount] * ( [First rest temp] – [Grain temp] ) + [First rest temp] + [Equipment Adjustment]
    R: is the heat capacity coefficient of grain.

    General speaking, the “Equipment Adjust” should be a minus value because the kettle is at the “mash-in” temperature when dough-in.

  • Mash-out is necessary for BrewManiacEx. If the last mash step in the BeerXML recipe is in the mash-out range( >75C), it will be regarded as Mashout step. Otherwise,”Default Mash Out” will be inserted automatically.

Import BeerXML



  • A BeerXML file might contains more than one recipes. Therefore, you might need to select desired recipe.
  • The recipe can be “Save” and “Brew” only if it has at least Boil Time and Mash Profile.
  • The saved name can’t contains special characters and space. The maximum length is 28.
  • Using the same recipe name as existing saved recipe will overwrite the existing saved recipe.
  • You can “brew” it without “saving” it. Press “Brew” button will set the automation settings.
  • The “Mash-In” temperature is derived from the settings at the time it is shown. So does the “Mash-out” step if it is missed in the BeerXML imported. The original BeerXML is saved, and you can have different Mash-In and Mash-out(if not present in the BeerXML) if you change the options before “viewing” a recipe.

Saved Recipes



  • You can “delete” and “brew” the saved recipes.
  • You can change the options to get different Mash-In temperature just before “brew” it.


Boiling and Boil Temperature Setting

Boiling temperature is one important setting for boiling stage.
First, counting of boil time starts when boiling temperature is reached.
Second, the PWM control is available when temperature is higher than “Boiling temperature” AND “Setting temperature“. (Setting temperature is the temperature controlled by UP/DOWN during boiling.)
If the temperature can’t reach boil temperature for some reasons, the timer will never start and the brew will never finish.
The default boiling temperature is 100 degree Celius, which might be a problem for some people, like me.
At my very first brew, the temperature stop at 99.75. I had to stop the brew and change boil temperature setting to 99. The is also one reason for pause function during boil stage, which pauses counting of time.


  • Set the Boil Temperature to 99 degree Celius or lower at your first brew.
    If the wort is not really boiling at 99 degree, you can just adjust the PWM to 100%, pause the timer, and resume the timer after it really boils. The default value of boil temperature will be changed to 99 on next release.
  • The design is arguable. Checking only the setting temperature might just be fine.

A Facebook page for BrewManiacEx and my future plan

I have been develop BrewManiacEx myself, but I am not alone. Although most of the features are design to fit my own requirements, some of them are from discussions with readers of this blog. I appreciate your suggestions. To make it easier for you to provide your invaluable suggestions and to setup a better way of communication, I setup a Facebook page dedicated for BrewManiacEx. That should also provide a better notification of new release in the future, if you ‘like’ it. You can still comment here, though.


There is not a project manager, so the development is erratic and arbitrary. Current release already has almost everything I need except recipes. Therefore, the next feature to added will be recipe. In my opinion, editing recipe on a brew controller doesn’t make much sense because the brew controller is usually only turned on at brewing day. Importing of a recipe is ratively reasonable. The current de-facto standard seems to be BeerXML, and that’s what I am going to support. Given the fact that browsers have XML parser built-in, the difficult part will be the presentation. I haven’t thought of a way to display. Any suggestions are welcome.

BrewManiacEx v0.1.2

This release is to enable BrewManiacEx to work under AP mode, so that you can use it without an Access Point.

It also fixes a bug which will result in RESET of system if the connected network disappears.

A new button to “disconnect current WiFi” is added in “Network Config”. The username and password must be input to enable the button. This button is used to clear the WiFi data, so that you can disconnect from current WiFi. You must, however, restart the system to select new network after that.

The user manual is also updated. Thanks to Iain, who corrected my typos and grammar errors.

LCD and Hardware Configuration of BrewManiacEx

Hardware configuration

There are three files you might need to check if you are not using default settings.

  • config.h
    Most software configuration is defined here. The most important one is the number of sensor supported.

    #define MaximumNumberOfSensors 5

    For single sensor, set it to 1(one), or 2~5 for multiple sensors.
    Changing other options is not recommended if you don’t what the options mean. Please also note that some of the options are used during development, and changing them might result in compile error.

  • pins.h
    All hardware related definition is in this file, including PINs and PCF8574 address.
  • ui.h
    LCD type definition. Please see following description. (I should’ve created a option in pins.h, but I did it in a rush manner.)


Most of the cheap I2C LCDs available on eBay seem to be adapted by a PCF8574/PCF8574A. That is the type BrewManiacEx supports.

  • Address of LCD
    BrewManiacEx uses another PCF8574 for input, the address of LCD should be different from the PCF8574 for input. The address of input PCF8574 must be defined in pins.h, while the address of LCD is derived automatically by scanning the I2C to find the other LCD.
    The reason of this design is because the two PCF8574 is non-distigunishable, but we have control over the input one. The address of I2C LCD is usually not clear from eBay sellers.
  • Type of I2C LCD
    There are multiple way to interfacing LCD by PCF8574. The most popular one that marked as “sainsmart” on eBay seems to be “YWROBOT”, which is the default setting. Other configuration and information can be find here. If your LCD doesn’t work, you might need to find out the type of your LCD adaption, and change the last parameter at line 30 to one of the following values:

    Thanks to Robert Holmström who pointed out this issue.
    I might switch to the NewLiquidCrystal library, which seems to be more flexible. FYI, the reason I don’t use it is because you have to delete unused files because of the bad design of Arduino IDE.

About Relay Module

I am not good at hardware but just want to share my experience with you. I have two 2-way relay modules which work fine with NodeMcu 3.3V logic. However 2 of my 3 1-way relay modules are inverted logic and don’t accept 3.3V as HIGH. All the relay modules are marked as 5V. I have no idea how to differentiate them. I would suggest please test them by connect the signal directly to 3V3, GND, and 5V before you use them.

BrewManiacEx BrewShield



  • 1~3, ACT1, ACT2,ACT3
    connect to 5V driven SSR or Relay. for pump, heater, and sparge Heater control. If “Relay Modules” are used, use port “9. ACT Signal“.
  • 4. Buzzer
    5V driven buzzer.
  • 5. Sensor
    DS18B120 sensor. Connect 3V3 to power(vcc) of sensors.
  • 6.Power
    5V power supply. 1.5A+ is recommended.
  • 7. I2C LCD
    I2C bus connection for LCD. The power is +5V.
  • 8. Input
    For keypad or buttons. P0 for Down, P1 for Up, P2 for Enter, and P3 for Start. Pushing the keypad or buttons cause the PIN to GROUNDED.
  • 9. ACT Signal
    The direct control signals of pump, heater, and sparge heater. 3V signal. They control  the same ACT1~ACT3 output and are used to connect to relay modules.
  • 10. WEMOS D1
    The two 8pin headers are for WEMOS D1 mini or pro. Antenna Up, USB down.



  • 52mm x 52mm


  • $15.00 USD
  • $5.00 USD shipping within USA.

Note: I wanted to run BrewPiLess on this board also. However, it turns out the rotary encoder doesn’t work smoothly without capacitors. Therefore, I don’t recommend to use it for BrewPiLess.

Please leave the message if you want to buy. I will send you PayPal invoice.



My New BrewManiacEx Controller and the result of latest brew

This is my new controller.



The log:gfbrew

The PID parameters used were tuned by using 2 gallons of water. I should’ve tuned with 5 gallon water, but I wanted to check the effectivity of PID parameters. The result seems to be OK. However, the temperature stability seems to be vulnerable to pump actions. The first turbulence was caused by adding malt, which was expected. The second turbulence at the beginning of MashOut was caused by adjustment of the flow rate of wort. The others were caused by turning on the pump.

What does it mean? Well, that means the temperature difference of the mash might be bigger than I have thought. Therefore, I will setup a multiple sensor for next brew.


BrewManiacEx Release

bmexBrewManacEx is a brew controller based on ESP8266. It was started by mimicking famous Arduino-based Open ArdBir, so most of Open ArdBir functions are included.

  • Manual and Automation brewing process control
  • PID and PWM heat control
  • Automatic PUMP control

The most important feature that BrewManiacEx differs from Open ArdBir is

  • WiFi Enabled, Web-based interface
    You can view, change the settings, monitor and control the brew on your phones, tablets, and computers.


  • Multiple sensors support
    Up to 5 sensors are supported. Different sensors can be used in different stages.
  • PID autotune
    Run the PID Autotune to get the best PID parameters for your system instead of guessing.
  • Sparge water Heating control
    Run the sparge water heating when the main heating element is idle during mashing to enable using only one 15A/20A GFCI socket.
  • Temperature logging chart
    Watching the temperature chart during brew and after brew


Special Note about the IO Expander and LCD

Most 20×4 I2C LCDs are in fact interfaced by a PCF8574/PCF8574A. Therefore, there is two PCF8574/PCF8574A’s in the system on the same I2C bus. You have to make sure they have different addresses. The default address of IO Expander is 0x38, and the address of LCD can be any other address. BrewManiacEx will try to find the address of LCD on startup. It just has to be different from the address of IO Expander, and the address of the IO expander must be correctly set.



Real Brew:



Draft user Manual


BrewManiacEx Preliminary information

BrewManiacEx is the integration of BME8266 and BrewManiac on ESP8266. All functions of BrewManiac are available for BrewManiacEx. There are a few extra new functions:

  • PID Auto Tune
  • Multiple sensors
  • Sparge water heater control
  • Temperature Chart


PID Auto Tune

It is based on the implementation of PID AutoTune library. I am not going to explain how it works, but there are something you should know if you want to use it. The parameters are baed on how quickly and how far the temperature fluctuates, so that not only the heating power, the mass of mash, the environment temperature, and the desired temperature do mater. Therefore, to run the AutoTune, fill the volume of water as your usual brew, like 5-6 gallon for 5 gallon, put the kettle where you usually brew at, and set the temperature to the temperature you usually mash at.

To run AutoTune, enter Manual Mode and set the desired temperature, like 150F/65.5C. When the temperature reaches, long press “heat” button.

When the AutoTune process is finished, it will back to Manual Mode, and all parameters will be saved automatically. The quicker the temperature changes, the quicker the AutoTune finishes. If you run it at the same temperature of the environment temperature, you might never get it done.

Multiple Temperature Sensors

The web UI is redesigned to support multiple sensors. Maximum 5 sensors can be supported, and different sensors can be used in different stages, including Pre-Mash, Mashing, Boild, and Cooling.

Only two temperature readings can be shown on the LCD screen, but all can be shown on the web page.

Multiple sensor support is available in BrewManiac as a branch. However, that is not complete. I might merge part of the code into it later.

Sparge water heater control

Heating elements usually need large current. A 1500W of 120V heating element, while considered “weak”, will draw maximum 12.5A and running two of them will requires 25A. Inspired by Jelle Klinge, the sparge water heating control is to solve this issue by running them exclusively by taking the advantage of the fact that the heating element is idle most of the time during mashing.

The sparge water heating is enabled from Mash-In to Mashout if it is enabled. As a reminder, BrewManiacEx will prompt “Sparge Water Added?” when starting automation process. Answering NO result in disabling of sparge water heating control function in that brew. Since the sparge water is heated when the main heating element is OFF, the temperature might not reach desired temperature if the mash time is short and the heating element of sparge water heater is not powerful enough.

The heating of sparge water can be temperate-controlled or not. If temperature control is not applied, the heating is ON when the main heating is OFF. The temperature should be controlled manually or by other mechanism. If multi-sensor is not enabled, temperature control for sparge water heating is not available.

If temperature control is enabled, the auxiliary temperature display during Mashing is always the sparge water temperature sensor.

Temperature Chart

Powered by Chart.js, BrewManiacEx will displayed the temperature chart during Manual and Auto mode. The temperature chart is refreshed every minute. The data of auto mode is logged, saved, and can be download later. Maximum number of saved logs is 20. The oldest log will be deleted when new log is generated. The data under Manual Mode is not saved, and the temperature data is not logged after the record buffer is full, which should happen after 4 hour for single temperature sensor.


Time runs continuously, so does the temperature. The log, however, is and can only be discrete. Using shorter period results in bigger log file and more memory usage. Longer period results in a longer ‘lag’ of chart update. IMO, one minute is a good value. The temperature chart looks good for one minute period while the memory usage is limited. The change of temperature is usually slow so that the lag doesn’t mater.
However, it is a different story for the progress annotation. For example, If the time when the temperature reaches the set point is at 5th second of the minute, it will be shown after 55 seconds. Let’s say the temperature at 30minute is 63.9 and it reached setting 64 at 30m:05s, the “temperature reach” annotation will be at 31minute time line. It’s totally OK when displaying a “history” log. When in a really brew, you will feel the “lag” because the annotation will be shown after 55 seconds.
There are ways to ‘solve’ this issue, but I can’t think of a “clean” and simple way to do it. Two ways I’ve tried are to set the time to “previous” time, like 30m in the example, and to “draw” next time point,31m, when the event happens. The former one seems odd because the temperature at 30m has not reached the setting point, the later is also odd because the temperature of 31m is not yet available and the line ends at 30m. I am leaving this for further enhancement, or leave it as is.

Other Changes

  • Temperature Sensor resolution
    There is a menu item under “PID-PWM” for configuration of sensor resolution. The readings of temperature will reflect the real resolution instead of .25 resolution in original Open ArdBir.
  • Heating algorithm
    The heater is full ON before the difference between current temperature and setting temperature is smaller than a configurable value, which is the menu item “PID Start” under “PID-PWM”. The value ranges from 1.0 to 3.5 Celius. PID is not applied in boiling stage: it will be full on before boiling point reaches and controlled by PWM after boiling point.
  • Pump control
    Sampling the pump control. No more sensor position selection.
  • Network setting
    Configurable host name for mDNS, username, and password. Access to system update and file management are protected by simple username/password authentication. Authenticated access to main page can be configured.
  • Delay Start
    There is an option under “Unit” menu to enable or disable Delay Start feature. Enabling Delay Start provides the chance of delay start when starting automation process. (I want this option because of not liking to be asked every time I start.)
  • Brew calculators
    It’s handy to have these during brew: Hydrometer temperature correction, Refractometer reading converter with correction(BRIX to gravity conversion with wort correction), and boil off/dilution calculator. A first wort SG estimation function is also provided.

Know Issues

  • No sensor setup menu for web pages.
  • The change of network takes effect after reset. Only last change is effective if multiple changes are made. For example, if the hostname is changed, and username is changed later before the system restart, the change to hostname is voided.
  • The web page will not reflect the changing of sensor settings automatically. Manual reload is necessary.
  • The sensor resolution is read from the sensor, and the resolution setting goes directly to the sensor. That is, setting of sensor resolution must be run again for new sensors.
  • In multi sensor configuration, the resolution display is get randomly from one of all sensors. Setting the resolution result in the same resolution of ALL sensors.
  • The temperature chart is updated every minute. That means the chart is always ‘out of date’ for one minute before next update.
  • The temperature chart is ‘splined’. The values between two valid value points are not real values. They are interpolated to make the line smooth and could be wrong. The lines are changed to straight lines. Uglier, but less misleading.


  • Off-line log viewer. (well, copy-n-paste also takes time.)

How to tune the Auto Tune?

The PID parameters have bothered me for a while, so I managed to integrate the PID AutoTune library:

It was very easy, but testing it takes longer than I have thought. I finally get a set of PID parameters for 2 gallons of water. (Yes, I was testing and didn’t want to spend too much time waiting the water to be heated.) It took almost two hours to get the auto tune done, and it took me two days to get this result. The reason: there are parameters for Auto Tune to tune the PID parameter automatically. They are

  • Start output
  • step
  • noise range
  • look back time

Noise and look back time are well explained on author’s page, and I mis-understood the meaning of start output and step until I checked the source code:

//oscillate the output base on the input's relation to the setpoint
 if(refVal>setpoint+noiseBand) *output = outputStart-oStep;
 else if (refVal<setpoint-noiseBand) *output = outputStart+oStep;

I set both outputstart and step to 127.5 to make it finish the tuning, so that the output is full at 255 or nothing at zero.  The time it took, however, is not reasonable. That might imply that the values of the other two settings are not appropriate. I have to figure out the correct settings of Auto Tune to get the correct settings of PID. That is kind of funny thing to me.

The library needs a few “peaks” to get the tuning done, which means the quicker the temperature changes, the faster the tuning can be finished. Since I change the heating mode of my Grainfather to Mash mode, it heats up slowly. I am testing it indoor, so the temperature drops slowly. The result is a slow tuning process. I don’t know how other PID device can perform the auto tune so quickly in a few minutes.

The parameters for different volume(or mass) and different heating power should be different. Even in different environment, the parameters should be different. However, I would bet the parameter for 5 gallon water would be good enough in most cases.To make this function more practical, the tuning time should be shorter.

BTW, I’ve changed the heating(PID) algorithm. The original ArdBir will use PID when the temperature is 3.5 degree away from target and 1 degree from boiling. I think PID is meanness for boiling phase, so I make it full before boiling and turn it into PWM mode after boil. PID is only used before boiling phase after the temperature reaches a defined range. I think 0.5-1.5 might be a good value, given that fact that the mass of 5 gallon or more water won’t be heated up so quickly.


Using 0.2 as the noise range, 30 seconds as Look Back time, and tuning at 60C, the Auto Tune can finish in 30 minutes. The key seem to be the tuning temperature. The higher temperature, the quicker it drops, and the quicker to get peaks for the AutoTune algorithm.