Brewing Chamber - Prototype
An Arduino controlled beer experimenting chamber.
It brews 2.5 litres of beer at a time, which is good for testing recipes, and only been a small batch you can go a bit crazy in flavour combinations. It has a water proof thermometer so you can monitor its exact temperature of the fermentation. The pressure of the carboy is regulated by a Pressure Sensor and a Solenoid Valve, a desired maximum pressure can be set that will trigger the solenoid valve to open and the let the pressure release back down to the desired minimum pressure. The purpose to this would be to firstly control the pressure at which the fermentation occurs. There has been small amount of research looking at the effects of brewing under a pressurised system and the effects that has on the fermentation and potentially resulting in a cleaner yeast attenuation, as some of the theories talk about how it could potentially decrease esters.
which I found in an article that talked about how brewing under pressure could actually reduce the amount of esters and other undesired flavours to be produced as a result of the cleaner yeast attenuation.
There's a good run down of brewing under pressure on Homebrew Stack Exchange: http://homebrew.stackexchange.com/questions/9750/w...
At this point I am collecting the data of the rate at which the pressure increases, it get's released at a safe 15 psi as I don't trust my set-up to handle much pressure, but it doesn't really matter too much as I am wanting to measure the speed at which it reaches the desired maximum pressure, and with the intention to maintain a relative pressure range.
The fermentor is in the wooden box so that a more consistent temperature can be reached. The potential to heat or cool the brew could later easily be included into the project.
Parts
I actually used a Freetronics Eleven, the Arduino Uno equivalent. I find them easier to source in New Zealand and they have the preferred/common Micro-B USB.
Parts for the Electronics:
1x Arduino Uno
1x 12v DC Solenoid Valve
1x RGB LED Stripe (approx. 30cm)
1x Dallas Waterproof Thermometer DS18B20
1x Push Button
3x Transistors TIP31CG (RGB LEDs) (TIP120 would work here too)
1x Transistor TIP22G (Solenoid)
1x Resistor 1k (Solenoid)
1x Resistor 5k (Dallas)
1x Resistor 10k (Button)
1x Diode IN5404, IN4004 also works. (Solenoid)
3x Connector plugs: 3pin; 4pin; 6pin (or 5pin).
1x 5cm by 4cm Prototyping Board
1x Food Safe Heat Shrink (Dallas)
Parts for the Chamber:
2x "Found crates"
1x Linseed Oil
1x Black spray paint
1x Coconut Fibre
1x Glass Sheet
Planning the Size of the Fermentor
I used what materials I could get for the budget I was limited to. I got the 3 litre carboy for $5, the crates I acquired...for free. So I just made a simple box to house everything.
Soldering
I made a mistake on here, I accidentally soldered the negative of the solenoid directly to ground instead of going to the transistor, that's what happens when you work late at night. The diode was technically in the right place, but I just figured it would be safer, easier and out of the way if it was directly on the solenoid.
Schematics will be posted soon.
Final Touches to the Interior
Here I spray painted the interior black, this was only where the electronics will sit. Underneath I have attached the RGB LEDs, they will be just out of sight whilst giving ambient light onto the brew bottle. I placed the RGD LEDs into a loop of clear plastic tubing, it wasn't so much to protect it rather to diffuse the the light, I even frosted it up by using some fine sand paper on it.
The Magic (code)
I linked the Arduino to Processing via the Serial, with the intention of having the Processing sketch show the data over time so we can see how the beer is progressing.
This can interface with a Processing sketch via serial communication.
#include <OneWire.h>
#include <DallasTemperature.h>
#include <Wire.h>
#include <Adafruit_MPL3115A2.h>
// //// Power by connecting Vin to 3-5V, GND to GND
//// Uses I2C - connect SCL to the SCL pin, SDA to SDA pin
//// See the Wire tutorial for pinouts for each Arduino
//// http://arduino.cc/en/reference/wire
Adafruit_MPL3115A2 baro = Adafruit_MPL3115A2();
float pascals;
float altm;
float chamberTemp;
float pressure = 0;
float idealPressure = 14.45; //This case PSI. depends on which measurement of pressure, i.e. pascals; psi; etc float maxPressure = 14.81; // psi int clicks = 0;
// Data wire is plugged into port 2 on the Arduino
#define ONE_WIRE_BUS 2
#define TEMPERATURE_PRECISION 9
// Setup a oneWire instance to communicate with any OneWire devices (not just Maxim/Dallas temperature ICs) OneWire oneWire(ONE_WIRE_BUS); // Pass our oneWire reference to Dallas Temperature.
DallasTemperature sensors(&oneWire);
int numberOfDevices; // Number of temperature devices found
DeviceAddress tempDeviceAddress; // We'll use this variable to store a found device address
float yeastTemp;
float idealTemp = 24;
float tempTol = 1.1;
boolean heating = false;
boolean lastHeatState;
// ************* PINS 'n Wires *************
// SCL is on White Wire
// SDA is on faint Yellow Wire
// Dallas Temperature Sensor is on Pin 2. Yellow Wire
const int solenoid = 4; // Solenoid on Pin 4. Brown wire
const int buttonPin = 6; // Push Button Pin. Purple Wire
const int bluePin = 9; // Blue Wire
const int greenPin = 10; // Green Wire
const int redPin = 11; // Red Wire
// Other:
// +5v is on long Red Wire
// Gnd is on long Black Wire
// Vin (input 12vDC) is on long faint Yellow Wire
// *********************************
int redValue;
int greenValue;
int blueValue = 0;
int endTime;
void setup() { Serial.begin(9600);
baro.begin(); // Initiate barometric pressure sensor, which also has on board temperature sensor
Wire.begin(); // Initiate OneWire library, required for communication with the barometric pressure sensor.
dallasSetup(); // This initiated the Dallas Waterproof Digital Thermometer
pinMode(solenoid, OUTPUT);
pinMode(buttonPin, INPUT);
pinMode(redPin, OUTPUT);
pinMode(greenPin, OUTPUT);
pinMode(bluePin, OUTPUT);
// Serial.print("Initiated*");
}
void loop() {
int startTime = millis();
baroRun();
// Barometric Pressure/Altimeter
dallasRun();
Serial.print("send"); // Start of signal, 'send' will be excluded, it will act as a buffer
Serial.print(pascals);
Serial.print("a");
Serial.print(chamberTemp);
Serial.print("b");
Serial.print(yeastTemp);
Serial.print("c");
String rgb_s = String(redValue) + ", " + String(greenValue) + ", " + String(blueValue);
Serial.print(rgb_s);
Serial.print("_"); // End of signal '_' redValue = 33; greenValue = 16; blueValue = 100; setRGB(redValue, greenValue, blueValue);
}
void control() {
if (pressure >= maxPressure) { // was idealPressure
digitalWrite(solenoid, HIGH); // releases the solenoid valve allowing gas(CO2) to escape through the Airlock setRGB(redValue, greenValue, blueValue);
}
if (pressure <= idealPressure) {
// alternative code to using releaseCount. May replace minPressure as it may never get there, testing required. digitalWrite(solenoid, LOW);
// Closes solenoid valve
setRGB(0, 0, 0); } }
void testControl() {
if (clicks < 10) {
digitalWrite(solenoid, HIGH);
// Serial.println("Solenoid has opened");
setRGB(redValue, greenValue, blueValue);
}
else if (clicks > 10) {
digitalWrite(solenoid, LOW);
// Serial.println("Solenoid has closed");
setRGB(0, 0, 0);
}
clicks++; if (clicks >= 20) clicks = 0;
}
void baroRun() {
if (! baro.begin()) {
Serial.print("Couldnt find sensor.");
digitalWrite(solenoid, HIGH);
// Serial.println("Solenoid has opened");
return;
}
pascals = baro.getPressure(); // returns pascals
pressure = pascals / 6894.75729; //pressurePSI = pascals / 6894.75729; // Converts Pascals to PSI
pascals = round(pascals); // Rounds number so there is no decimal when it gets sent to processing via the Serial chamberTemp = baro.getTemperature(); // returns celcius
}
void setRGB(int r, int g, int b) {
analogWrite(redPin, r);
analogWrite(greenPin, g);
analogWrite(bluePin, b);
}
void dallasRun() {
// call sensors.requestTemperatures() to issue a global temperature
// request to all devices on the bus
// Serial.print("Requesting temperatures...");
sensors.requestTemperatures(); // Send the command to get temperatures
// Serial.println("DONE");
// It responds almost immediately. Let's print out the data
//printTemperature(tempDeviceAddress);
// Use a simple function to print out the data
yeastTemp = sensors.getTempC(tempDeviceAddress);
//Serial.print(yeastTemp);
}
void dallasSetup() {
// Start up the library
sensors.begin();
// Grab a count of devices on the wire
numberOfDevices = sensors.getDeviceCount();
// locate devices on the bus
//Serial.print("Locating devices...");
//Serial.print("Found ");
//Serial.print(numberOfDevices, DEC);
//Serial.print(" devices.");
// report parasite power requirements
// Serial.print("Parasite power is: ");
//if (sensors.isParasitePowerMode()) //Serial.println("ON");
//else //Serial.print(" OFF");
// Loop through each device, print out address
for (int i = 0; i < numberOfDevices; i++) {
// Search the wire for address
if (sensors.getAddress(tempDeviceAddress, i)) {
//Serial.print("Found device ");
// Serial.print(i, DEC);
//Serial.print(" with address: ");
//printAddress(tempDeviceAddress);
//Serial.println();
//Serial.print("Setting resolution to "); //Serial.print(TEMPERATURE_PRECISION, DEC);
// set the resolution to TEMPERATURE_PRECISION bit (Each Dallas/Maxim device is capable of several different resolutions)
sensors.setResolution(tempDeviceAddress, TEMPERATURE_PRECISION);
//Serial.print("Resolution actually set to: ");
//Serial.print(sensors.getResolution(tempDeviceAddress), DEC); //Serial.println(); } else { // Serial.print("Found ghost device at "); // Serial.print(i, DEC); // Serial.print(" but could not detect address. Check power and cabling"); } }
}
// function to print a device address void printAddress(DeviceAddress deviceAddress) { for (uint8_t i = 0; i < 8; i++) { if (deviceAddress[i] < 16) Serial.print("0"); Serial.print(deviceAddress[i], HEX); } }