BrewManiacEx 0.3


There are more and more functions, but I can’t test all functions because I don’t have all the hardware setup. Neither can they be tested in one single brew. Therefore, please verify before put it into real use.

What’s new

  • Post Boil Hop(HopStand)
  • Customized audio
  • Multi-button in Web interface
  • New setting options
    • button feedback, buzz on button pressed, or not
    • pump priming cycle, on time, off time.
  • Iodine test.
    • There are two options after Iodine Test. Go to Mash Out or Extend the mashing rest.
  • Export/import settings in web interface
  • Dual heater support by compile option. config.h@39
    #define SecondaryHeaterSupport true


  • Sparge heater is no longer  by default supported.
  • revise setting temperature of web interface. Correct setting temperature will be displayed in manual mode.
  • code revision.

Known issues:

  • The sound doesn’t paly on mobile Safari.
  • If the audio file is larger than 120k, it might not work.
  • Sometimes, Chrome don’t play the audio unless reloading the page.

Post Boil Hop(HopStand)

Check this post.

Customized audio

Currently, it works on Safari and Chrome, not tested on other platform. It doesn’t work on mobile Safari of iOS because it doesn’t allow downloading and playing audio without users’ action.

Two files are involve: sounds.json and the audio file. All segments of sound is put in a audio file, preferred to m4a(AAC) format, and specified by the sounds.json file.

sounds.json should be put in the root of the file system of ESP8266. If it is missing or in wrong format, all the sound effect will be replaced by simple buzzing.

The format of sounds.json is like this:


“src” specifies the source of the audio file. It doesn’t have to be on the controller. It can be a HTTP URL, and you can put it anywhere that can be assess by your browser. (If your audio file is larger than 150k, you might need to put it anywhere else instead of the controller.)

“seg” sepcifies the voices:

  • “s”: start of the audio, by seconds
  • “t”: duration of the audio, by seconds. Use 0 if not used.
  • “r”: times of repeat.

The meaning of the tags:


tag When Example
open Successfully connecgted BrewManiac, at your service
tr Setting temperature reached. Temperature reached.
addhop reminder of adding hop Time to add hop
addmalt reminder of adding malt Time to add malt
boil Boiling phase starts start boiling
boilend Finish boiling boiling finished
bye brew finished. brew finished. goodbye.
chill reminder of chilling for hopstand start chilling
cool start of cooling stage time to cool
iodine reminder of iodine test Time for iodine test
maltin temperature reaches mash-in temperature ready to doughing-in
mashout start of mashout start mash out
nmash proceed to next mash steop continue to next mash step
removemalt reminder of removing malt Time to remove malt
whirlpool reminder of whirlpool starts time to whirlpool
disc connection disconnected Controller disconnected


Guideline/tips of audio files

  • Keep the file as small as possible. It’s not concert recording, so use lowest sampling rate as possible.
  • If your audio file are larger than 150k, putting it on the controller might not work. (This might be issues of ESPAsyncWebServer/ESPAsyncTcp. Keep it as a known issue.)
  • There is a lag of playing audio on Safari. Around 200~250ms silence before(including) and after(not including) the audio segment is necessary to make it work better on Safari. For example, if the audio segment is 1 seconds and will be appended at time 15 seconds, you should insert a silence of 0.2 second before the real audio, and another 0.2 second of silence after the audio segment. Then, mark the segment start at 15 second with 1.2 duration.
  • OSX has text to speech built-in. You can type something like this to create a audio segment.
    >say -v "Samantha" "Hello, I am Siri."

    To output the audio to a file, add “-o” option, like “-o siri”.

  • oceanaudio is very good for creating the audio file. You can use it to
    • merge the audio segments
    • insert/delete silence space between segments
    • re-sample the audio to make it smaller
    • check the start and duration of the audio segment.

Multi-button in Web interface


On iOS, you can just press the buttons simultaneously, and release at the same time. (Not tested on Android devices.)

Using mouse to press two or more buttons on laptops or desktops is trickier:

  1. Click (and hold) anywhere on the rectangle area around the buttons, but not on the buttons.
  2. Drag through the buttons. The buttons will be hiligh-lighted.
  3. Release the mouse on one of the button.
  4. Releasing the mouse outside the buttons will have no effect. Moving outside the rectangle area during dragging will also cancel the action.

37 thoughts on “BrewManiacEx 0.3

  1. It has been finished a few weeks ago, and I release it after doing a real brew.

  2. Hi Vito, just finished building a setup yesterday and will try to hook it up to my grainfather tonight to do a test of the functionality.

    I’ve started thinking though, as i also have the alembic pot still accessory for the grainfather to see whether this could be adapted for distilling as well. Often distillation is run twice, with the first run basically running a “stripping run” at full blast, initial cleaning and volume reduction. This could be done manually quite easy with the current software i believe.

    But for the 2nd (and usually final) run, all the collected output from a few “stripping runs” is run, normally at full blast until the vapor temperature reaches a certain point (there’s an opening in the pipe coming from the dome for a thermometer to measure the vaportemp, which can be calculated to the abv% of the distillate)

    Depending the the abv or vapor temp one would like to slow things down a bit not ‘blend’ the various fractions too much (giving a better/higher yield).

    I only had a quick look at the code base and it is quite large, so any pointers as to where to start look more in depth would be awesome.

    You could drop me an email and perhaps i’ll be able to find some time to understand the code and see where these features could fit in. Or if you feel interested i could provide a typical flow chart and possibilities.


  3. This is what I understand, correct me if I am wrong.
    The controller heats the liquid until the temperature at the pipe reaches a set value.
    Then, the heating power should be lowered.

    The concept is simple, or I misunderstand. However, the “lower heating” is not a clear description.
    I don’t really know how it could be done except lowering the setting temperature.
    It is easier to control the temperature of liquid than “lowering” the heating. Yes, PWM can be done, and you can set the output to a lower value, like 50%.
    What if the temperature drops to 60 Celsius?

  4. You’re not wrong Vito, a secondary distillation is where one separates out methanol and other dangerous volatiles(foreshots), this evaporates first (lower boiling point), then comes the ‘heads’ which is a mix of foreshots and ethanol (smeared together), and then comes the hearts (‘good alcohol), although one can generally mix in a bit of the other fractions for flavour/aroma. (last one is referred to as tails, which tends to be bitter in flavour)

    depending on the amount of liquid in the boiler, a distiller typically discards x amounts of ml, which are foreshots. but at this point, to make the separation between the different fractions more distinguished, one would at the start of the output pwm to a certain % pwm, and once the stage reaches a different temperature in the vapor, the boiler would change to a different % pwm.

    Now these are not always the same, you might want to separate differently if you are to distill a smoky whiskey vs a clean whiskey, or if you are distilling a fruit brandy etc.

    But this is what would lend to automating, just like mashing profiles, one could have distilling profiles

    Example pseudo code
    Start of heater ->
    If temperature => 55degrees C //part of automation/recipe, although 55 is a good start to turn on cooling water
    Display(“turn on cooling water”)
    sleepUntil(WaitForUserAcknowledge();); //turn off heater as this is important
    set pwm(50%) // part of automation/recipe
    Display(“Remember to discard foreshots (x ml) //where x is also part of the automation/recipe

    if temperature => 83degrees C //start of hearts fraction, part of automation/recipe
    Display(“start collecting hearts”)
    set pwm(70%) // part of automation/recipe
    if temperature => 90degree C //Start of tails fraction, part of automation/recipe
    Display(“start collecting tails”)
    set pwm(100%) // part of automation/recipe
    If temperature => 98degree C //Then the amount of ethanol left in the boiler is very small so the water/power effort isn’t perhaps worth the trouble. (this could be part of automation/recipe)
    set pwm(0%)
    Display(“Distillation is done”)

    The actual functionality and control is not very complex at the most basic, but getting into another persons code is a bit tricky, which was why i wanted to pull it by you to see what you think

  5. Are the temperatures liquid temperature?

    The process seems simpler than beer brewing. However, in beer brewing, the controller controls only temperatures.
    PWM is used only after boiling temperature reaches. Off course it’s not difficult to change the code from PID to PWM.
    The problem is that 50% heating power might gets different results in the winter and summer.
    If you distill outdoors in chilling weather, the temperature might even drops. I think that can be handled by correct temperatures.

    heaterControl() in BrewManiac.ino(it will be rename to BrewManiac.cpp in next release, mainly for PlatformIO.) is the code you need
    to look at. It is where PID and/or PWM is applied.

    I have seen some distiller, and none of them has pump. Therefore, the pump control might be used for “chilling” by either pumping cold water or turning on the solenoid that controls the flow of cold water. That would make the process more automatic.

    The procedure is simple. I would suggest you don’t mess with manual or automatic mode, buy you can reference automatic mode. ( I am sorry that the part of code is the worst code I ever had, because I was not familiar with Arduino and avoided using C++ for memory issue.)

    BTW, a few months ago, a friend asked me about distilling. Is that you?

  6. Hey Vito, no, all the temperatures are read from the vapour (sensor in the copper dome condenser). So it’s not very interesting to control the actual temperature in the boiler, only the speed of heating.

    I had a look at heatingControl() and i think perhaps its more straightforward to add a distillingControl() that could be chosen initial at startup instead of manual and auto. I’ll have a look at how the various variables are named and how multiple sensors are handled. But first i need to try out and brew a beer (or a few) with the stock version to see wether it works properly or not. If i get time over to start coding, i’ll try to do so in a way that it could be merged to your codebase and if not enabled through config.h (or similar) the extra code won’t be affecting the default running code.

    And no, i don’t think i was that friend who asked about distilling. It’s illegal in most countries 😉

  7. In version 0.3, the sparge heating function is NOT available by default.
    You have to turn on the compile options.

    However, that won’t result in connection failure. There might be some other problems.

  8. Vito, where turn compile option?
    If I upload your bin-file BrewManiacEx.multisensor.023.bin, not work temperature sensor, temperature always 100.75C.

  9. Vito, thanks!
    I find parameters and change, compile, upload – not work. Temp always 100.75.

    I’m return to simplesensor.
    Best regards.

  10. hi Andreas,

    Surprise for you.
    I implement a quick and simple distilling function. You can check this branch

    There is a Distill Recipe submenu in setup.
    To start distilling, press the “UP” key in idle(start screen.) I did’t change the label display.

    I might not keep maintaining this work. There are already too many options.

  11. Hi Vito, I had this problem when I was update firmware of my controller using system update by Chrome.
    Error:Server not Report Size.
    Do you know what I can do to solve this? I searched but did’n find the .bin of version 0.3 on github reporitory, just 0.2.3 version.

  12. I forgot to add the binaries. Now they are on GitHub. Please check again.

    The web server starts to discarding the content-length field a few months ago.
    The on-line update relies on the content-length, so it doesn’t work for now.
    I found that updating of HTML/Javscript sometimes doesn’t work either.

    The web hosting service is so cheap that they don’t provide easy access customer service.
    Before I move it to other hosting, just download the binary and update manually.

  13. Hello Vito, What IDE version do you recommend to use? I’m dealing with some upload issues (fatal error: avr/interrupt.h: No such file or directory).

  14. Woah, you’re a machine Vito 🙂

    I’ll clone the branch and diff to the 0.3 tag to see what’s been added and if needed i’ll try to refine, and perhaps have a fork available for those looking to add distilling features 🙂

    I’ll try out the tag with some water!


  15. It might be easier to search the following options

    Arduino IDE is used for old 0.3, and the new branch is using PlatformIO.

  16. Wow… it’s so smooth with PlatformIO. Just FYI, #define EnableMultiSensor is missing in the distilling branch – I guess it’s specific for distilling.

  17. Check the manual for detail:

    In a nutshell, you can specify which(or both) heater to use during different stages: pre-mash, mashing, boiling, post-boil.

    For general SINGLE kettle e-BIAB, you can use secondary heater to help heating mashing water and boiling. In which, you will set BOTH heaters on during Pre-Mash and Boiling stage, and only one heater during mashing and post-boil.
    For 3-kettle HERMS system, check my other post

    You will need an additional SSR to control the heater. It is controlled by D8 by default.You might need to avoid overloading the power, though.

  18. Man, oh man, what a beautiful work!
    I am quite new to microcontrollers and one of the things that I find most amazing is how people are generous in sharing great stuff on that field. Thank you for that!

  19. Hi Vito. Many thanks for your firmware. I use your program for a year. It allowed me to save a lot of time and automate the process of brewing beer. I also use the distillation function. Could you correct the time delay when setting the temperature in the web interface in manual mode (also PWM level in the distillation mode). When I repeatedly press the button up or down, the temperature in the corresponding field changes after 10-20 seconds.

  20. There is no such delay. It’s the overhead of HTTP request or the implementation of the browser.

    Nothing I can do to improve the latency except changing to use WebSocket instead of ServerSideEvent.
    However, I’ve tried WebSocket, and it was not stable at that time. Sometimes Safari, the browser, even crashed. (I hate the new interface of WireShark and miss Ethereal, so I didn’t dig into that issue.)
    It was over one year ago, and I have been thinking about trying WebSocket again. It just takes time to verify and test the stability and compatibility. I am in a one-man team and frequently distracted by other stuff…

    Would you share your experience about distilling? I don’t have equipment for distilling and I don’t distill. The logic is a result of discussion with Andreas, in previous comments. I wonder how it works.

  21. Vito, thanks for reply. I’ll try to use another browser (it was a google chrome before).
    Latency in manual mode is not so critical. I use manual mode to pre-clean the brewery (boiling with soda) before mashing in automatic mode.
    For distilling I use the same equipment with distillation column.
    In my experience distillation process is easy than brewing, but it is more difficult to automate.
    In common, the process of distillation is divided on two stages. The first stage consists in rapid distillation of the sugar (or malt) brew at the maximum power of the heater. At that stage we obtain dirty alcohol. So brewery (50l with 2.5kW heater) work at 100% PWM. Water supply to the refrigerator (pump control), when temperature in top of column reached 35-40C. When temperature in top of column reached 97C the first stage end. At that stage I use automatic brew mode with zero mashing time and switch pump to inverted mode (“pump stop temperature” set to 35-40C).
    Fraction distillation of dirty alcohol is carried out at the second stage. The second stage is rather difficult to automate. I use distill manual mode. The first brewery works at 100% PWM. Program signaling me when temperature in top of column reached 35C. Next I control process of distillation by myself. At that stage it is impossible to rely on the thermometer. I control the output of alcohol and the selection of head (and other) fractions by adjusting water flow in refrigerator and the power of the heater (PWM).
    So it is my distillation experience. Maybe other people have another way of distilling.

  22. Thank you for your sharing.

    I am upgrading to latest ESPAsyncWebServer and verifying WebSocket which should make buttons more responsive. It is also possible to implement continuous button press, which might result in massive HTTP request under current ServerSideEvent architecture.

    I found a bug that affect the update of setting temperature. By design, the setting temperature should be updated when it is changed, but the bug delay the update of setting temperature. I will update it later.

  23. Many Thanks Vito. I’m looking forward to the update.
    I’m sorry. I’m forget about another bug in distillation mode. I can’t turn on pump in distillation mode. In brew mode pump can be controlled by button or via web. After enabling device power and entering distillation mode, pump button not working. I need to enter any brew mode (automate or manual) and press pump button. After that I can turn on pump in distillation mode by pressing the button.

  24. Hi Vito. I tested firmware (v040pre) for brewing beer. There is no latency on setting temperature and heater PWM via web interface (google chrome, opera). And now pump button work in distilling mode.
    Thank you for your job!

Leave a Reply

Your email address will not be published. Required fields are marked *