New ESP8266/Arduino framework, to update or not to update?

The recently released ESP8266 framework has caused some issues. The first issue is compile errors of ESPAsyncTCP. To solve this error, you can simply force to use old version of the framework, by editing platformio.ini

platform = espressif8266@~1.5

I do migrate to latest ESPAsyncTCP/ESPAsyncWebServer with latest framework(1.6), but that is the real issue. The new framework is about 26.5k bigger than previous release 1.5, and the image built with 1.6 framework will make OTA impossible.

The current flash layout of ESP8266 use 1M for program, or sketch. To support OTA, the sketch size must be smaller than half of the total program space. The image of default BPL is about 500k, so using latest 1.6 framework breaks the limit.

The latest ESPAsyncTCP/ESPAsyncWebServer libraries work pretty with latest 1.6 framework but seem to have some issues with 1.5 framework. The README.MD of ESPAsyncWebServer states that latest framework might be necessary, and I encountered some no-response issue when using latest libraries with old 1.5 framework.

(BTW, one extra advantage of latest libraries with latest framework is that WebSocket is pretty solid, compared to the result I had a few months ago. My other Project, BrewManiacEx does benefit from WebSocket because of the short latency of uplink data transmission. BrewPiLess, on the other hand, does not gain much from that.)

Staying with old 1.5 framework is a simple solution but I am not sure if it is a good idea.

To upgrade to latest 1.6 framework, something will have to be removed. It’s unlikely that I can squeeze 25k or even 10k program space for it. A few solutions I come up:

  • Remove OTA update support
    It’s unlikely that I would do this. Opening project boxes to flash it is PITA.
  • Remove embedded files.
    Manually uploading the HTML file will be necessary.
  • Expanding the sketch space to 1.5M or 2M.
    IMO, this might be the best solution. 2M file space is good for 5~6 months. The drawbacks will be

    • Editing of flash configuration file needed. 2M file system is not built-in standard configuration while 1M file system is. However, 3M for sketch is a waste.
    • Upgrading to latest version might require formatting of SPIFFS.


Poorman’s Glycol system

A real glycol chiller is expensive, and DIY glycol chiller from an air conditioner is kind of too hardcore for people like me. Therefore, I am using a re-purposed fridge as “glycol” chiller. The air is bad heat conductor, so I ended up using a bucket of water and bending the plate into water. It works really well except that the water sometimes gets frozen because I  use no glycol but plain water. One thing I also observe is that the beer temperature seem to be more stable if the temperature of “glycol” is not too cold.

In a nutshell, a temperature controller is necessary to control the poorman’s glycol chiller.

I have a spare BPL, but somehow I don’t want to use it. The BPL I am using has a two way relay board, and I am using only one for cooling, controlling the pump. The temperature of “glycol” is monitored by the “room” sensor. Simple hysteresis temperature control with timed constraints to protect the compressor would do the job.

I am not going to make it “official”, but I would love to share if anyone wants to try it.

The option is not enabled by default, so you have to build it by yourself.

build_flags = -Wl,-Tesp8266.flash.4m.ld -DEanbleParasiteTempControl=true

You will need a HTML file for setting. It is “paractrl.htm” in “extra” folder at Github. Manually upload it to BPL, and open it. The setting should be straightforward.

  • Enable Parasite Temperature Control
  • Cooling PIN /Inverted.
    Only coolingPin, heatingPin, and doorPin can be used. They are D5, D7 and D4 in default configuration. If they are used by BrewPi temperature control, the options of PINs used will be disabled. You CAN mess it by selecting the PIN and later assigning it for cooling or heating in Device Setup page. Don’t do that.
  • Target Temperature
    The cooling will stop when the temperature is equal or lower than this value.
  • Triggering Temperature
    The cooling will be started when the temperature is greater than this value. This value should be at least 0.5 higher than “Target Temperature”
  • Minimum Cooling Time
    Must be greater than or equal to180 (seconds).
  • Minimum Idle Time
    Must be greater than or equal to180 (seconds).

My setup:

The water level is higher when in use. (I was pumping out the water.)  Before applying the parasite temperature control, the water might get frozen and clog the tubing.

Sharing BPL log online

Here is a new easy way to share BrewPiLess logs over the internet, on-line.

Step 0: Hosting on GitHub.

If you have your own host, it should be easy and you can skip this part. Using GitHub hosting service is simple and easy. I would suggest you too google on this subject to find better illustration and description.

Step 2: Get the log viewer

Get the “BPLog.htm” file from my GitHub:

Don’t forget to get the “raw” version.

Step 3: Upload the file and logs to share

The logs will be put at the same place as the BPLog.htm file. Subdirectories can be used. I put my log in a subdirectory, named “log”.

Step 4: Test the shared link.

First open the log viewer page on your browser.  The url should be something like

If you can see the empty log chart page. You are almost done.

Step 5: Create the shared link.

Append log name after the URL above in this format[Your log name]

If the log is put in a subdirectory, replace “/” by “%2F”. You will need to uriEncodeComponent special characters. If you don’t understand previous sentence, please don’t use special characters in the path and log file names.

eg. A log name “nottingham.035.20171114” in subfolder “log

Copy the URL above to your browser or see it in a iFrame here:

Step 6: Optional with selection range

Select the desired range, right click mouse on the chart.

A menu of “Open Selection” will popup, click that item to open a new window that will zoom to the selection range on open.

BrewPiLess release v2.4

BrewPiLess release v2.4

  • Brew and calibrate iSpindel
  • Use iSpindel temperature reading as Beer Sensor.
  • Display tilt value of iSpindel.
    This is part of the “Brew and calibrate” functions.
  • Enhance SSE re-establishment
  • Default configurable minimum cooling/heating time & back-up sensor. (That is, Glycol supported.)
  • HTTP Port settings in Config page.

    Please note: you will have to run Device Setup to setup temperature sensors and PIN usages if you are upgrading from old version other than glycol option. 

I really like the new “Brew and Calibrate” feature. My iSpindel works great. However, every time I open the cap to charge it, the stuff inside moves a little, and the readings will drift a little bit. The result of using this method is better than that of calibrated one.

BTW, the working principle of iSpindel is exactly the same as a hydrometer. Therefore, temperature correction is necessary.

In the following chart, Purple line is temperature-corrected reading and green line is non corrected readings. Without correction, the gravity reading rises when the temperature drops. The corrected reading also rises a little bit, though.

The gravity readings used to calibrate iSpindel should be NOT temperature-corrected. The way of deriving gravity values from TILT values is using a function(formula) having a single parameter, the tilt value. We assume that there exists such a function exists and try to find one that is approximate to the perfect one.

The physics principle of iSpindel is the same as a floating hydrometer. A hydrometer will show different values for wort at different temperatures.

For example, wort of 2.6% BRIX will be measured as 1.010@20C, 1.011@4C, and 1.009@24C. The Specific Gravity, which is the value after temperature correction applied, will all be 1.010, calibration to 20C.

The TILT values should be different in the same wort at different temperatures because the density of the liquid is different. Let the TILT values of 1.009, 1.010, 1.011 be x1, x2, x3. It’s not possible to have a function, f(x), so that f(x1) = (fx2) = f(x3) = 1010. Obviously, finding a function, f(x), so that f(x1) = 1.009, f(x2) = 1.010, f(x3) = 1.011 is possible. Applying the temperature correction, the correct Specific Gravity can be derived.

BrewPiLess for Glycol

BrewPi is derived from BrewPi v0.2.x, which is designed for fermentation chambers made by fridges. The latest BrewPi v0.4.x has evolved to be a general temperature control unit. The code is very different from v0.2.x, and porting v0.4.x might not be an easy job. Instead, I implemented two main features that might make glycol possible: fallback sensor and adjustable minimum time.

In addition to using binary for glycol or building with “EnableGlycolSupport” defined, there are setups and settings that must be tweaked.


  • Don’t use Fridge Sensor. The “fallback” feature will use the reading from Beer Sensor as Fridge reading.
  • (optional) Use second sensor as Room Sensor to monitor glycol temperature.
  • Beer Constant or Beer Profile mode is preferred.


  • minimum times: including minCoolTimeminCoolIdleTimeminHeatTimeminHeatIdleTime,and deadTime
    All except deadTime are self-explanatory. deadTime defines the minimum idle time between heating and cooling, and the waiting time at power-up. 10 seconds seems to be good for all of the values.
  • idleRangeHidleRangeL
    The values define the temperature range to stay in idle. That is, no action will be performed if the fridge temperature(from Beer Sensor) stays in this range. The default values are 1.0, so it will start cooling when the temperature reaches 21 degree if the set temperature is 20.
  • maxHeatTimeForEst & maxCoolTimeForEst
    After cooling or heating, the algorithm expects the temperature to go lower or higher. Usually the temperature won’t go too far in glycol setup. Therefore, set a smaller value for these two, so that it won’t wait too long for detecting peaks.
  • PID settings. Kp, Ki, Kd
    If all of them are set to zero, the FridgeSet will be equal to BeerSet.
  • (optional) filter settings: fridgeFastFilt, fridgeSlowFilt, fridgeSlopeFilt, beerFastFilt, beerSlowFilt, beerSlopeFilt
    Even the data is from the same sensor, the temperature readings of beer and fridge sometimes differ. It is because that they use different filters. The temperature of fridge is volatile, while the beer temperature changes slowly. If you want them to be strictly the same, the filter parameters should be set to same same.

After setting, you can use “c” (single lower case c) to read back the setting for verification.

My testing

This is my initial test by filling 6 gallons of water in my newly purchased Spike CF10 with coil.


My test was conducted with a cooler with frozen PET bottles. The room temperature is  the temperature of water in the cooler.

I set all minimum times to 10 seconds, idleRangeH to 0.1. maxCoolTimeForEst to 30 seconds. PID parameters are left untouched. The result seems acceptable except that more PET bottles (or, a glycol chiller) are needed.

BrewPiLess v2.1 available

By using the word “available”, I mean that it is not well tested, and I don’t have enough confidence of it.

New Features

The major improvement of this version is about gravity stability and beer profile handling.

  • More flexible, and complicated, beer profile.  Detail@Github
    • New stable gravity condition by checking the gravity differences between current reading and up-to 72 hours ago.
    • Specifying gravity condition by apparent attenuation(%), which makes it easier to reuse beer profile. OG must be provided.
  • Fermentation progress indication
    • It is just a simple indication that the gravity change within last few hours is less than the specified gravity stable threshold.
  • Low pass filtered gravity reading
    • To filter out wrong readings by bumping, a simple low pass filter is applied, and filtered data is used in beer profile algorithm. The filtered data is shown in this version. (check Github for more detail.)
  • (LogViewer) Exporting data to CSV format

Bug Fixes

  • Wrong auxiliary temperature( temperature reading from iSpindel) display
  • beer profile related bugs
  • (Utility) iSpindel Calibration utility showing the same line for both polynomial.

Information of BrewPiLess v1.2.6 and V2.0

I used to think that BrewPi already has everything for fermentation temperature control and there isn’t much to be done. It had been true before release v1.2.5, in which the basic functions of BrewPi are implemented.

Well, there are always fresh ideas, and now I am working on gravity related features. Two main related feature are

  • gravity recording/logging
    • manual input
    • updated by other device, iSpindle.
  • gravity-based temperature schedule

The logging function is trivial but the gravity-based schedule is not. In my opinion, the way to specify beer profile in BrewPi is a good design, but I couldn’t figure out a way to extend it. Therefore, a new way to specify the schedule is created, and I would like to put it in version 2.0 because I regard it as a break through. The gravity logging will be available in version 1.2.6 with original time only beer profile.


My current design of new beer profile:


  • “days” specify the duration of the step. It’s different from “Day” in original beer profile
  • The condition to finish a rest step can be
    • longer than a specified time
    • less than a specified gravity
    • both conditions meet (time AND gravity)
    • either one meets (time OR gravity)
  • A “ramp” step is necessary in the transition of two rest steps.
    • this design allow specifying the speed of temperature change
  • For steps that use gravity as condition, the “days” field is still necessary
    • to draw the chart
    • under certain conditions, it can be used to derive current steps.
  • Changing the profile while beer profile is running will have undetermined result when gravity is involved.


The logging with manual input is available in “preview” branch. The input of iSpindle hasn’t been implemented yet. Currently, only manual input of gravity is available.

An issue I would like to highlight is that the gravity values are more concrete than temperature especially when it is manually input. In my option, a line between two gravity  values is meaningless, but it helps to track the values. It would be very difficult to find the points of gravity values without connected them by a line.

BrewPiLess Release 1.2.5

  • Showing temperature chart when it is not being recorded
    • The data is saved in a circular buffer good for around 2-3 hours.
  • Moving the temperature control to main page.
  • Temperature chart for beer profile editing
  • Fast loading setting for temperature management control page(now main page)
  • Reload the temperature chart after start/stop saving log
  • Showing name of current saving log, blank if not saving
  • Fix bugs of not showing room temperature in legend area


(The BrewPiLess is running “Beer Constant” mode, and the Beer profile displayed is the saved one. )

BrewPiLess Release 1.2.3

This release is to solve one issue.

Under certain circumstances, the log chart will not shown.



The cause is that the reading from SPIFFS returns zero. I suspect it has something to do with resources for file handle of SPIFFS. According to an advice I googled, I kept file handle opened and reused it to read the log. The solution is to close re-open the file when reading fails.

Release v1.2.2

The major enhancement is on the format of “remote logging”.

  • Add PUT method
  • Use printf-like format
  • Data Type.(Content-type)

The printf-like format and specification of content type provides maximum flexibility. You can use any format with your own “field name” or “variable name”. So far, form type ( and JSON format ( have been tested and verified. I hope to test XML format if I can find one.

You can find the example in at GitHub.