Control Software (Firmware)

User Interface

When the control software is first invoked, a window listing all of the available recipes is displayed. Recipe files are identified by a ".RCP" extension and are located in the "C:\SBS\RECIPES\" directory. The arrow keys are used to select the desired recipe.

In the upper right hand corner is the total elapsed time (in hours, minutes and seconds).

On the right hand side of the top row is the batch file name. The batch file name is the same as the recipe name.

In the center of the top row is the recipe name, "Marzen/Oktoberfest".

Along the bottom of the display are "hot" keys. The Quit key, F3, can be used to abort the brewing process. Power is turned off to all pumps, valves and electric heater elements. The Valve, Pump and Heater keys, F6, F7 and F8, respectively, allow the user to change the state (on, off, resume) of any valve, pump or heater at any time during the brewing process.

The Comment line along the lower left hand corner allows the user to enter comments within the batch file during the brewing process. The comments are dated and time-stamped and merged relative to the other log status messages.

The area between the Action line and the Comment line shows messages as they are written to the batch file.

The Action line is used for operator input. The computer will prompt the user to hit Enter after having lit/extinguished a burner, completed dough-in, dropped hops, … The computer beeps until the operator has acknowledged the prompt.

The sparge vessel graphic displays the target and actual sparge/dough-in water temperature, the power (as a percentage) applied to the sparge heater element and the target and actual sparge/dough-in water level.

The mash vessel graphic displays the target and actual dough-in water/mash wort temperature, the power (as a percentage) applied to the mash heater element, the target and actual time (in hours, minutes and seconds) of the current mash step and the level of dough-in water/wort (in gallons). The dough-in water/wort level is not actually measured, but rather calculated from the loss and gain of the sparge vessel and boil vessel, respectively.

The boil vessel graphic displays the actual flow rate (in gallons per hour). The top flow rate represents an "elapsed" value, the total number of gallons transferred divided by the total elapsed time. The lower flow rate represents a "delta" value, the total number of gallons transferred over the last 15 minutes. The boil vessel graphic displays the target (predicted) and actual time (in hours, minutes and seconds) of the boil. The boil vessel graphic displays the wort level (in gallons). The wort level is measured by a pressure transducer mounted in the bottom drain of the boil vessel.

Prioritized Electric Heater Elements

The sparge heater element is needed to heat and maintain the temperature of the sparge water at the same time the mash heater element is needed to increase and maintain the temperature of the mash. The sparge heater element draws approximately ? amps. The mash heater element drawers approximately ? amps. Power is provided to the brewing system via a 15 amp circuit. In order to avoid both heater elements being on at the same time, the mash heater element is given priority over the sparge heater element. If the mash temperature dictates that the mash heater element should be on, the sparge heater element is turned off.

Boil Time Prediction

There are two basic approaches to boiling wort. We normally boil wort based on time or volume (or some combination there of). If you boil based solely on time, it is simple to calculate when to drop hops to achieve the desired hop character, however, you have little control over the resulting volume. If you boil based solely on volume, it's difficult to determine when to drop the hops. Boil time prediction is used to calculate how long the boil will last in order to achieve the desired volume.

I have calculated the average evaporation rate for the boil vessel and propane stove. I use this value at the beginning of the boil to project the boil time based on the volume of wort measured using the wort level indicator (pressure transducer). Every 15 minutes, the wort volume is measured, the evaporation rate is recalculated and the remaining boil time is re-projected. Hops are dropped based on the projected boil time.


The state of the entire system,

is logged to a batch file once every minute. The graphical user interface provides a comment field to allow the user to integrate run-time comments into the batch file. The batch file name is the same as the recipe name with a three-digit numeric extension. The numeric extensions are assigned sequentially, starting with ".000".

[actual batch file]


The graphics package involves simple character manipulation (as opposed to addressing individual pixels). The DOS text mode has a resolution of 640 x 350 pixels. The standard font size is 8 x 14 pixels, or 25 rows by 80 columns. I chose an 8 x 9 pixel font which gave me 38 rows by 80 columns, or over 50% more addressable characters.

A font is simply a collection of characters, in this case 256 characters. Of which 52 are upper and lower-case letters, 32 are "recognizable" symbols (i.e. !@#$%^&*), 10 digits, and 32 are control characters. That accounts for about half of the symbols. I used a font editor to redefine some of the unused characters. For example, I redefined two characters to form a pair of flames which "flicker" when alternated. I redefined a character to depict "water". I redefined a pair of characters to form the lower left and right hand corners of the three vessels.

State Machine Design

The software is designed as a simple state machine. The state machine is driven by the graphics package. The graphics package continuously calls a keyboard exit function when it is not updating or monitoring the display for input. The keyboard exit function serves as somewhat of an interrupt service routine. With each invocation, the interrupt service routine,

  1. Displays the total elapsed time
  2. Writes the state of the system to a batch file every 60 seconds
  3. Notifies the user in the event the system requires input
  4. Animates the pump and fire graphics
  5. Queries the sparge vessel water and boil vessel wort levels and animates the graphics
  6. Queries the sparge and mash temperatures and updates the display
  7. Turns on the sparge and mash heater element and animates the graphics
  8. Invokes a single step of the state machine
  9. Turns off the sparge and mash heater elements

The entire brewing process is broken down into a series of 34 steps.

  1. Fill the sparge vessel with dough-in water
    1. Open the sparge water solenoid valve
  2. Have we reached the target dough-in water level?
  3. Dough-in water level reached
    1. Close the sparge water solenoid valve
    2. Turn on the sparge electric heater element
    3. Light the sparge stove
  4. Is the dough-in water temperature within the dough-in water temperature delta?
  5. Dough-in water temperature is within the dough-in water temperature delta
    1. Extinguish the sparge stove
  6. Has the dough-in water temperature reached the target dough-in temperature?

The state machine is implemented using a case-switch statement. Each step of the brewing process is represented by a case of the case-switch statement. One step of the brewing process (one state of the state machine) is executed every time the keyboard exit function is called.

switch (step) {
case 1:
step_profile = 0;
progress_indicator("Sparge Vessel Filling With Dough In Water");
case 2:
if (sparge_actual_water_level >= sparge_target_water_level) {
case 3:
progress_indicator("Dough In Water Level Reached");
progress_indicator("Applying Heat With Sparge Heater Element");
prompt("Light Sparge Burner");
progress_indicator("Applying Heat With Sparge Burner");

In step 4, you can see that if the sparge (dough-in) water temperature is not within the sparge burner temperature delta (5 ºF), the step is not increased.

case 4:
if ((sparge_target_temperature - sparge_actual_temperature) <= SPARGE_BURNER_TEMPERATURE_DELTA) {
case 5:
progress_indicator("Within Dough-In Water Temperature Delta");
prompt("Extinguish Sparge Burner"):
case 6:
if (sparge_actual_temperature >= sparge_target_temperature) {

A state may perform a series of actions and then increment the step such that the next state is executed the next time the keyboard exit function is called. A state may involve a decision in which the transition to the next state is conditional (a.k.a. dough-in water level reached?). A series of consecutive states may form a sub-process which is repeated as part of the entire brewing process. In this case, the step may actually be decremented in order to repeat the sub-process.

For example, each mash step can be thought of as a series of states,

case 16:
if (mash_actual_temperature > mash_target_temperature {
progress_indicator("Mash Step Temperature Reached");
progress_indicator("Begin Mash Step");
start_timer("MASHTARG", mash_time[step_profile]);
case 17:
update_timer("MASHACTL", start_time);
if ((end_time - start_time) / 60.0 >= mash_time[step_profile]) {
stop_timer("MASHTARG", "MASHACTL", &start_time);
progress_indicator("Mash Step Complete");
case 18:
if (step_profile < max_steps) {
mash_target_temperature = mash_temperature[step_profile];
progress_indicator("Increase To Mash Step Temperature");
step -= 2;
} else {
progress_indicator("Mash Complete");

The prompt function: writes the message to the action line and the batch log file; saves the current step; sets the step to IN_PROGRESS (0); and waits for user input. If the interrupt service routine is executed and the step is equal to IN_PROGRESS, the computer beeps. There is no "default" case. With the step set to IN_PROGRESS, the state machine doesn't execute a step. Once the user acknowledges the prompt, the step is restored and the state machine resumes the next time the keyboard exit function is invoked.

The progress_indicator function writes a message to the progress field and to the batch log file along with a time stamp.

Proportional Control

An important aspect of the control software design is the proportional control of the electric heater elements. This is accomplished by "pulsing" the heater elements on and off in proportion to the temperature delta. This will be detailed at a later time.