Thursday, 3 April 2014

Automatic Brew Success!

Yesterday I decided to run another test. No changes to the code, just a complete re-run of the last brew so we could see how we go. I am pleased to announce that it turned out to be a success! No interaction was required to produce a fermentable wort from the first push of the "brew" button!

Heres a pretty lame video of the hop-dropper doing its thing for the boil. No hops were ejected on this "drop cycle" though. You can also see the rolling boil of the wort created by PWM of the Solid State Relays. The "hop sock" is something that is getting phased out soon. It will be a stainless perforated "hop sieve".

Code and Brew Log

There were a few minor programming issues that I came across when I went through the brew log. This log is the diag information sent back over the serial port so I can monitor technical things going on in the program.
Message passing: I created a generic message which has a very basic frame with information such as "source task", "destination task", etc and also a void pointer to the payload. This way, any payload size and datatype can be sent as a message. This may be dangerous in some respects, but I havent had issues with the payload side of things yet. The issues were with the source and destination elements. I found that the boil task kept receiving a message to turn on the elements at 55% at the transition of a step. Some steps explicitly turn off the boiler, so it seemed erratic and intermittent at the start. A quick path test of the boil task uncovered that if the message was received from the "brew task" then it would choose a duty cycle of 55% no matter what the payload contained. This was fine as it's what I want when boiling the wort in automatic mode. The problem I uncovered was the brew_reset() function also used the "source" as brew_task. Bingo. The reset function is called in between steps as a helper function to stop certain devices (such as boiling).
The path test of this code enabled me to optimise the module better and clean things up a lot. The minor bug has been removed so we wont have to rely on the level sensor to stop the boil when not called for!

The Result + Automatic Brew 2 (Another Success)

So here it is, about a week later and we're drinking a really nice DARK beer! A few parameter tweaks were made and we ran the machine for the second trial in automatic. It went off perfectly. This test saw better volumes and a more accurate temperature profile. I hold confidence in a very fine IPA in a weeks time. 
I just need some candidates to help me knock a few over!

Auto Brew 2 - Result

Ok, so its been a while and I will say that both brews were extensively tested by a panel of -- lets say -- tasters :-). The consensus was that the  IPA was pretty well amazing, but didn't last long! 
They both had a very clean profile with no off flavours or colours. 
Repeatability is now the focus. I will put together a basic recipe that we can use as a base, and make a couple consecutively. It will be interesting to see the brew-log and the results in the flavours.

+ A New Addition

I finally got the hop sieve cut and rolled, and Waz tigged it up, so it's ready to go for the next beer! 
Here's a quick look

Wednesday, 2 April 2014

Motorized Ball Valves

The initial build incorporated Viton diaphragm solenoid valves for the fluid control. Although quite cheap, they come with some added extras... I had a tiny piece of silver insulation tape catch in the valve seat which caused a slow leak from the HLT (Hot Liquor Tank). Yep, the water is filtered with a ceramic filter before the tank, but the foreign object must have been from when we installed the new stainless tanks and insulated them. This leak caused a potentially awesome beer to turn out to be mid-strength and just average. Some would say that it still had more flavour than any dark beer you can buy off the shelf here is Australia!

So I sourced some cheap motorized ball valves and installed one the other night. Its just mounted temporarily at the moment  (hence the cable tie). It comes with a motor connection in which the user changes the polarity dependent on  direction. Opened/Closed feedback is via contacts that sink to ground.
I hacked the old code from the original three-way valve and we were away. Its not that exciting so I didn't take a video.
The new 3-way Motorized Ball-valve

Wednesday, 19 February 2014

Initial Build of MKIV

After a lot of convincing, I have finally started my own blog.
This blog is about the design, build and running of an automated brewery at my home. It has been a bit of a journey with much of the credit to be given to a friend of mine, Zizzle, who helped me embark on my very first automated brewery about 7 years ago. Things have changed since then. There has been many hurdles as well as a large amount of learning by making mistakes. I admit this openly and Im proud to say that I have learned more by making those mistakes.

So here's how this version started: After some lengthy discussions and a couple of hand-drawn pictures on some beer coasters (not really), a friend of mine, Warrick, created a 3D model of the frame along with all necessary components, and then whipped it together.
Model showing basic design and location of main components - Warrick Velt

Yep, the garage is a mess, but things change
Layout drawings were made of the main cabinet components. I was lucky to have been given 2 cabinets which I used to house the wiring for the machine. Not ideal, but beggars cant be choosers when its a self funded project. The top cabinet housed most of the power circuitry including the heating SCR's and a variable speed drive. The bottom panel houses the micro-controller and interface circuitry.
Upper (power) panel
Both panels before wiring

One of the major changes that I made in this version of the machine was to have all field wiring connect with plugs and sockets. This was a time consuming and expensive exercise, but the convenience that it created was worth my while. The following images show some components added to the frame. You can also see the big red emergency stop button. I wired a Pilz Safety relay which disconnects all of the power circuits in case of emergency. This proved very handy during testing.

The lid on the mash tun (the only vessel on the lower level) is raised and lowered by a 24V motor/gearbox. There is also a motor mounted on the lid that drives the stirring mechanism to stir the mash. 

After some testing and discussions surrounding the vessels, Warrick and I decided to go with stainless vessels, so we outlayed yet more money. The plus is that the liquid only ever flows through silicon hose or is stored in stainless vessels. This is much easier to clean and withstands the harshness of the wort.

Stainless + insulation.

Additions that came later in the piece were:

  1.  Ceramic inlet water filter - to filter as much chlorine and other impurities out of the town-supply water 
  2. Heat exchange style chiller - to chill the boiling wort down to prevent loss in hop flavour and added bitterness
  3.  A pump to assist the extraction of boiling wort from the Boiler - to ensure consistent flow through chiller for repeatability.  

Mash tun with pump, recirculation valves, and camlok hose connections
allow for easy removal and cleaning

This shows an actual mash in the "recirculation" step.  
Duct Covers on.

DC power supplies, interface boards and plug/socket connections

This is the current Mash-Pump and valve set-up. The valve combination will  be replaced by a motorised ball-valve. 

Latest image showing the major components

Saturday, 1 February 2014

Programming the STM32 Development Board with FreeRTOS in Eclipse

The STM32 Development board 

The development board used for this project is readily available. By no means is it new technology, but it does the job for a very good price. You can pick these boards up for under $50 on Ebay or through many other online electronics stores. The actual MCU on this board is the STM32F103VE.

Development Environment

I was thinking of how to start this post for a while as I really didn't want to conjure up all  of the info I used to build the tool-chain for the stm32 board. After gathering some inner strength I decided to just search the old faithful Google and see if I could find a solution that was straightforward and step-by-step.
In saying this, Zizzle does have an Ubuntu virtual image with the tools already built which you can access from here.
I just stumbled across this document which provides a very comprehensive walk-through on setting up an SMT32 development environment.
Either of these two should get you talking to an ST board pretty quick.
Here's a SS of Eclipse with the STM32 code etc etc.


Ok so I had previously programmed ATMEGA micro-controllers, which was my first step into C Programming in general. My role as industrial electrician taught me about programming via PLC's using ladder logic, function block diagrams, and statement list programming. 
In addition to the steep learning curve of micro-controllers and C programming, I enrolled in a Bachelor of Engineering course in which I studied part time (I will finish in November 2014). 
THEN... I get told about this operating system called FreeRTOS which would make multitasking a breeze and the world would become so much easier.... ha! Read on...

I HAD to learn this... had to. 

So, I used Zizzle's Virtual-box image, and dabbled in a bit of the FreeRTOS API functions. In short, I got very confused and created more bugs than you could imagine. This was the best thing for me... I was back in the deep end. I bought the Cortex M3 FreeRTOS programming manual and reference manual from the FreeRTOS site. And that's when things made more sense. 

One step was forward, then I would take two steps back... this went on for a long time before I started to get it. I was introduced to the world of binary semaphores, task priorities, and many more strange things that I had "heard" of before.  As a side note, I will say that much of the theory that I was learning at university was starting to become clearer.


Zizzle and myself worked on hacking a driver we found on the net so it would work on the dev boards we had. This took a fair bit of reading, time, and patience. Most of the credit should go to Zizzle as he did incorporate the text interface that we use now as well as the menu system which I am sure he hacked from a version he wrote for an Atmega128 controller previously.  Here's a pic of the display working with text and some basic graphics.

So this was the starting point for the Brew Machine code!

Applet coding.

Zizzle had created a sample applet in his source code which I used as a starting point for my coding of Manual Operation. The idea was to get each and every component to a working state manually and make a few beers this way to test components. I created tasks that would handle calls to the LCD so that it didn't clog up the actual code that handled the functionality (start/stop/change values etc).
I used semaphores to handle the display applet so that the touch handler wouldnt hand back control to the menu until the display had finished updating.
I found that working with FreeRTOS helped me learn quickly about the importance of understanding 'context switching' and how can play a large role in introducing bugs into the system.
The following image shows some of the crane code:

DS1820 Temperature Sensors

As an exercise, I rewrote the driver to handle the one wire bus that talks to the DS1820 temp sensors. I had a little bit of exposure to this driver whilst using the Atmega128, so I found it interesting writing it for a different micro-controller. A permanent task was created to send a convert command to the temp sensors every second and wait for each result. 

I2C I/O Expansion

I started to run out of I/O as we added a few extra valves and sensors. I bought an I2C relay board online for around $40 which handles 10A 240V over the contacts. I coded a driver for the I2C using the stm libraries to handle calls to the bus. I also introduced a basic error checking mechanism where it would read what was written to the device, and if the values werent the same, it would resend. If the bus returned a failure, it would reset the bus and try again. This functionality hasnt yet failed for me whilst running the machine. I am aware of other error checking methods, but time is my smallest resource whilst Im studying and have a full time job! 

Auto Brew

The auto code was part-hack and part-new design. This is mainly for the fact that code-reuse is a helpful and friendly tool which I have learnt during coding. I incorporated a multi-tasking approach to the original auto code.

The concept is as follows:
  1. User presses "brew" in the menu system.
  2. Application opens brew applet and passes key handler there. The key handler handles calls to each of the buttons shown in the image above (LCD Display). The three buttons on the right hand side are "view changing" buttons which change whats shown on the display. The three buttons on the bottom are functional. They start/stop the brew or change the brew step.
  3. Upon pressing "brew", a task is created which handles the brew steps. These brew steps are ADT's holding information such as: start time, elapsed time, and pointers to their functions in which provides the functionality of that step.
  4. Some steps are able to be run in conjunction with each other such as "grind grains" and "close valve x", therefore a messaging system was created where the brew task receives messages when tasks have been completed. These messages hold information such as "task source" and a integer which equates to a message code such as COMPLETE or FAIL etc. The brew task can then send start multiple steps and simply wait until they send a message back upon completion. It then updates is "complete" flag in its ADT.
  5. Other steps do require all previous steps to be complete, for example the Mash - where all ingredients have been added to the mash tun. This is where the brew task has to check to see if the next step requires this. If so, then the brew task sits and waits until all "completed" flags have been set in the previous steps and then invokes the next step. As soon as this task has been called, the brew task can then check the following task before invoking it. This allows the brew "designer" to tailor the brew to their liking.

This code is still under testing and there are many "better" ways to do things. Thorough code testing is definitely required. Functionality testing has proven to be reliable, although a single brew can take around 4 hours, so repeated tests are very rare. 
The image below shows the brew steps in the brew data structure.

The following videos show a few of the sequences during the brewing process.
Video #1 shows a test sequence with no multitasking. It was created before the stirring motor was mounted. 

Auto Testing Video #1

Video #2 shows a sequence where the stirrer gets lowered into the grain incrementally. This is so that the stirring arms can break into the grain and turn at the same time whilst lowering.

Auto Testing Video #2