Bioreaktor Eigenbau
Die Hefe ist ein zentraler Bestandteil des Brauens und hat einen erheblichen Einfluss auf den Geschmack und die Aromen des Bieres. Daher spielt die Lagerung und Vermehrung von Bierhefe auch bei Hobbybrauern eine entscheidende Rolle, um eine Gewisse Qualität des Endproduktes erzielen zu können. Durch das Lagern und Vermehren in einer kontrollierten Umgebung, kann die Verfügbarkeit hochwertiger und lebendiger Hefekulturen sichergestellt werden.
Ein selbstgebauter Bioreaktor bietet hier die Möglichkeit, die Umgebung und Bedingungen zu kontrollieren, in denen die Hefe wächst und sich vermehrt. Dadurch können optimale Wachstumsbedingungen geschaffen werden und die Hefepopulation im Reaktor gesund und aktiv gehalten werden. Zusätzlich wird auch der Zustand der Organismen überwacht und an den Betreiber des Reaktors weitergegeben.
Die folgende Bauanleitung zeigt Schritt für Schritt, wie der Bioreaktor entworfen und gebaut wird. Von den Materialien, die benötigt werden, bis hin zur Montage, Programmierung und Inbetriebnahme der Anlage – hier sind alle wichtigen Informationen zusammengestellt.
Inhalt
2.2.1. Installieren von benötigten Bibliotheken
2.2.2. Aufsetzen des Programms
2.2.3. Kalibrieren des pH-Moduls
2.2.4. Einstellen der Variablen für den Reaktorbetrieb
1. Komponentenliste
1.1. Elektronikkomponenten
Bezeichnung |
Stk. |
Stückpreis |
Quelle |
Arduino Uno Rev3 |
1 |
24,00 € |
|
220 Ohm Widerstand |
3 |
0,48 € |
|
LED grün |
1 |
0,13 € |
Vossloh Schwabe LD 20 5MM GN LED bedrahtet Grün Rund 5 mm 40 mcd 60 ° 20 mA 2.2 V kaufen (conrad.de) |
LED gelb |
1 |
0,11 € |
Kingbright LD 20 GB 5MM LED bedrahtet Gelb Rund 5 mm 20 mcd 60 ° 20 mA 2.1 V kaufen (conrad.de) |
LED rot |
1 |
0,11 € |
Vossloh Schwabe WU-8-53HD LED bedrahtet Rot Rund 5 mm 14 mcd 60 ° 20 mA 2.25 V kaufen (conrad.de) |
Jumper-Kabel |
1 |
3,29 € |
|
Kippschalter |
1 |
2,79 € |
|
Steckplatine klein |
1 |
4,79 € |
|
pH-Meter mit Sensormodul |
1 |
40,71 € |
|
Universal Netzteil |
2 |
15,89 € |
|
Schlauchpumpe |
1 |
21,29 € |
|
Relais |
1 |
3,99 € |
1.2. Hardware
Bezeichnung |
Stk. |
Stückpreis |
Quelle |
M12 Verbindungsmuttern |
1 |
6,80 € |
|
Silikonschlauch 3mm Innendurchmesser 4m Länge |
1 |
18,23 € |
https://www.amazon.de/dp/B08CPZ5Q96?psc=1&ref=ppx_pop_dt_b_product_details |
Silikonschlauch 15mm Innendurchmesser 0,3m Länge |
1 |
20,02 € |
https://www.amazon.de/dp/B07SXGNTSF?psc=1&ref=ppx_pop_dt_b_product_details |
PH-Messgerät |
1 |
13,89 € |
|
Kühlschrankthermometer |
1 |
6,89 € |
|
PH-Sensormodul |
1 |
40,71 € |
|
O-Ringe Lebensmittelecht |
2 |
3,62 € |
10 x Lebensmittelecht Silikon O Ring Dichtringe 8 - 30 mm Schnurstärke 2,4 mm | eBay |
Gewindeeinsatzset |
1 |
29,99 € |
1.3. Werkzeuge
-3D-Drucker
-Lötkolben
-Elektronik Werkzeug kit
-Akkuschrauber
2. Steuerung
2.1. Zusammenbau Steuerung
2.1.1. Einbau Gehäuse
Der Einbau der Elektronik Komponenten erfolgt in 2 separate Gehäuse. CAD-Dateien für beide Gehäuse sind bereitgestellt, und können mittels 3D-Drucker hergestellt werden. Nach erfolgreichem Druck werden M3-Gewinde Einsätze an allen vorgesehen Stellen, mit einem Lötkolben und entsprechendem Aufsatz, eingeschmolzen. Diese Gewindeeinsätze dienen später zur Befestigung der Elektronik-Komponenten und des Deckels.
Abbildung 1: Arduino Gehäuse
Das erste Gehäuse beinhaltet das pH-Sensormodul, ein Breadboard (gelb dargestellt), einen Kippschalter, 3 LEDs und den Arduino selbst. Die Komponenten werden wie in Abbildung 1 dargestellt arrangiert und befestigt. Alle drei LEDs sollten dabei in ihren vorgesehenen Öffnungen festgeklebt werden.
Abbildung 2: Pumpengehäuse Draufsicht
Abbildung 3: Pumpengehäuse 3D-Ansicht
Im zweiten Kasten werden das Relais, wie in Abbildung 2 schematisch dargestellt, angeschraubt. Die Dosierpumpe wird auf den Säulen in Gehäuse befestigt, wobei die Löcher auf der Vorderseite des Kastens zur Ausführung der beiden Anschlussnippel gedacht sind. Alle Steuerleitungen werden durch eine kleine Runde Öffnung gelegt, die Stromversorgungsleitung durch eine rechteckige Öffnung in den Schaltkasten geleitetet. Letztere wird zur zusätzlichen Sicherheit mit einer M3-Schraube festgeklemmt.
2.1.2. Verkabelung
Abbildung 4: Verkabelung Steuerung
Nach korrekter Verkabelung können die Deckel beider geschlossen werden.
2.2. Programmierung Steuerung
2.2.1. Installieren von benötigten Bibliotheken
Um das Programm auf den Arduino übertragen zu können, muss in einem ersten Schritt die „Arduino IDE“ installiert werden. Diese stellt die Bedienoberfläche für den Mikrocontroller dar und kann mit folgendem Link heruntergeladen werden: https://support.arduino.cc/hc/en-us/articles/360019833020-Download-and-install-Arduino-IDE
Mit diesem Programm kann der zur Verfügung gestellte Code bearbeitet, und Messdaten in Echtzeit analysiert werden. Um den Code einzusetzen, müssen jedoch vorerst ein paar „Bibliotheken“ installiert werden. Bibliotheken ermöglichen es dem Benutzer umfangreichen und komplizierten Code simpel in das Programm mit einzubinden. Die für dieses Projekt benötigten Bibliotheken sind:
-Wire
-SimpleTimer
-QuickMedianLib
Der Bibliotheksmanager befindet sich in der IDE unter dem Reiter „Sketch“ à „Include Library“ à „Manage Libraries“ (Abbildung 5). In der sich öffnenden Suchzeile kann die entsprechende Bibliothek gesucht und installiert werden. Damit ist Sie automatisch für das Programm verfügbar.
Abbildung 5: Bibliotheken
2.2.2. Aufsetzen des Programms
Nach anschließen des Arduinos an den Computer per USB-Kabel, muss in der Arduino IDE lediglich der verwendete USB-Port ausgewählt werden, und das Programm mit betätigen des rot umrandeten Pfeils auf den Mikrocontroller übertragen werden (Abbildung 6).
Abbildung 6: Bedienoberfläche
2.2.3. Kalibrieren des pH-Moduls
Das pH-Modul gibt an die Steuerung nicht den pH-Wert der Hefe weiter, sondern lediglich ein Signal, welches sich auf eine Spannung abhängig von dem pH-Wert bezieht. Diese Spannung wird von dem Arduino gemessen und im Programm in den tatsächlichen pH-Wert umgerechnet. Da die Umrechnung von der Spannung in pH-Wert zwischen einzelnen Geräten variieren kann und das Modul nicht kalibriert geliefert wird, müssen zwei einmalige Kalibrierungsmessungen vorgenommen werden. Die Daten werden in den Zeilen 9 – 12 des Programms einmalig eingegeben und dienen der korrekten Umrechnung.
Es wird empfohlen, zwei Lösungen, eine saure und eine basische, mit bekanntem pH-Wert (am besten pH 4 und pH 10) vorzubereiten und zu Messen. Hierfür können Kalibrierlösungen verwendet werden (z.B. GAIN EXPRESS pH-Puder Kalibrierlösung 4.00 7.00 10.00pH Set : Amazon.de: Haustier).
Sind beide Lösungen vorbereitet, hält man das pH-Meter in eine der Lösungen, wartet ca. 5 min, liest den ganz linken Wert des Arduino IDE Serial Plotters ab (Siehe Abbildung 7). Dieser Wert entspricht der gemessenen Spannung bei aktuellem pH-Wert. Der Serial Monitor lässt sich über den Befehl strg + Shift + M oder im Reiter „Tools“ öffnen.
Abbildung 7: Ablesen der Spannung im Serial Monitor
Der pH-Wert der Lösung wird in Zeile 11 eingefügt und der abgelesene Wert wird
in Zeile 12 hinter „float cal_u1 = “ eingefügt.
Dieser Vorgang wird mit der zweiten Lösung wiederholt und in den Zeilen 13
& 14 eingefügt.
Die Kalibrierung ist nur einmalig notwendig und muss lediglich wiederholt
werden, falls das pH-Meter oder die pH-Modulplatine ersetzt werden sollte.
11 |
float cal_ph_1 = 4.04; // pH-Wert der ersten Kalibrierungsmessung |
12 |
float cal_u_1 = 0.85; // Spannung des pH-Meters bei erster Kalibrierungsmessung |
13 |
float cal_ph_2 = 9.97; // pH-Wert der zweiten Kalibrierungsmessung |
14 |
float cal_u_2 = 2.67; // Spannung des pH-Meters bei zweiter Kalibrierungsmessung |
2.2.4. Einstellen der Variablen für den Reaktorbetrieb
Abhängig davon, wie der Reaktor betrieben werden soll, ob primär zur Vermehrung der Hefe oder zur Lagerung / Konservierung, dienen die folgenden Variablen der Steuerung des Reaktors und sollten dementsprechend angepasst werden. Eine weitere Variable um die Aktivität der Hefe zu regulieren ist die Kühlschranktemperatur, welche über den Regler im Kühlschrank gesteuert wird.
Generell wird empfohlen, zu Beginn mit niedrigerer Temperatur und reduzierter Fütterung zu starten, um ein Überquellen des Reaktors bei zu viel Hefeaktivität zu vermeiden.
In den folgenden Programmzeilen wird angegeben, wie viel Sekunden zwischen den einzelnen Fütterungsintervallen liegen (Zeile 15) und wie viel Milliliter Speise dem Reaktor bei Ansteuerung der Pumpe zugegeben werden soll (Zeile 16).
15 |
float anz_mot = 3600; // Sekunden zwischen Motoransteuerungen 3600 |
16 |
float mot_vol = 3; // Fördervolumen des Motors pro Ansteuerung im ml |
In den Zeilen 17 & 18 wird die Ober- und Untergrenze definiert, ab welcher die Steuerung über die LEDs Feedback gibt, dass die Hefe ihren gewünschten PH-Bereich über- oder unterschritten hat. Leuchtet die gelbe LED ist die Hefe zu basisch, leuchtet die rote LED ist sie zu sauer. In beiden Fällen sollte die Hefe nach fachmännischer Beurteilung entweder entsorgt, oder zeitnah zum Brauen verwendet werden.
17 |
float ph_untergrenze = 3; // sinkt der pH--Wert unter diese Grenze leuchtet die rote LED |
18 |
float ph_obergrenze = 6; // steigt der pH-Wert über diese Grenze leuchtet die gelbe LED |
Da die ausgegebene Spannung des PH-Sensormoduls, welche im Programm den PH-Wert darstellt, über kurze Zeiträume schwankt, und diese unablässigen Schwankungen nicht für die Steuerung störend sind, wird im Programm mit einem Median des PH-Wertes gearbeitet. Damit werden Schwankungen eliminiert, und die Anzeige flüssiger. Die Dauer, über welche der Median gebildet wird, lässt sich in den Zeilen 32 und 33 einstellen, wobei es wichtig ist, dass in beiden Zeilen der gleiche Wert eingegeben wird.
32 |
int anz_med = 60; //Anzahl der Messungen pro Median |
33 |
float ph_act59[60]; // hier auch Anzahl der Messungen pro Median eintragen |
Während die obigen Zeilen zur Einstellung der Variablen im Reaktorbetrieb je nach Betriebssituation verändert werden können und sollten, läuft der Kern des Programms, der sich in der „void loop ()“ -Schleife befindet automatisiert ab, und sollte ohne Expertise nicht abgeändert werden.
Nach dem Kalibrieren des pH-Meters und der Eingabe der
Betriebsvariablen wird das neue Programm gespeichert und erneut auf den Arduino
hochgeladen.
Somit ist die Steuerung bereit für den Betrieb und kann eingesetzt werden.
3. Anhang
3.1. Programm Arduino
#include <Wire.h> |
|
2 |
// #include <Adafruit_GFX.h> |
3 |
// #include <Adafruit_SSD1306.h> |
4 |
#include <SimpleTimer.h> |
5 |
#include <QuickMedianLib.h> |
6 |
|
7 |
# define PIN_TASTER 8 |
8 |
|
9 |
SimpleTimer timer; |
10 |
// Anpassbare Variablen |
11 |
float cal_ph_1 = 4.04; // pH-Wert der ersten Kalibrierungsmessung |
12 |
float cal_u_1 = 0.85; // Spannung des pH-Meters bei erster Kalibrierungsmessung |
13 |
float cal_ph_2 = 9.97; // pH-Wert der zweiten Kalibrierungsmessung |
14 |
float cal_u_2 = 2.67; // Spannung des pH-Meters bei zweiter Kalibrierungsmessung |
15 |
float anz_mot = 3600; // Sekunden zwischen Motoransteuerungen 3600 |
16 |
float mot_vol = 3; // Fördervolumen des Motors pro Ansteuerung im ml |
17 |
float ph_untergrenze = 3; // sinkt der pH--Wert unter diese Grenze leuchtet die rote LED |
18 |
float ph_obergrenze = 6; // steigt der pH-Wert über diese Grenze leuchtet die gelbe LED |
19 |
float startdelay = 129600000; |
20 |
|
21 |
int phval = 0; |
22 |
unsigned long int avgval; |
23 |
int buffer_arr[10],temp; |
24 |
|
25 |
int led_green = 5; //Pin 5 fuer LED gruen |
26 |
int led_yellow = 4; //Pin 4 fuer LED gelb |
27 |
int led_red = 3; //Pin 3 fuer LED rot |
28 |
int motor = 10; //Pin 10 fuer Motorsteuerung |
29 |
|
30 |
float ph_act; //Variable fuer pH-Wert Messung |
31 |
float ph_act_med; //Median des pH-Werts |
32 |
int anz_med = 60; //Anzahl der Messungen pro Median |
33 |
float ph_act59[60]; // hier auch Anzahl der Messungen pro Median eintragen |
34 |
|
35 |
int lauf_var1 = 0; |
36 |
int lauf_var2 = 0; |
37 |
int lauf_var3 = 0; |
38 |
float calibration_value_1; |
39 |
float calibration_value_2; |
40 |
|
41 |
void setup() |
42 |
{ |
43 |
calibration_value_1 = (cal_ph_1 - cal_ph_2) / (cal_u_1 - cal_u_2); |
44 |
calibration_value_2 = cal_ph_1 - calibration_value_1 * cal_u_1; |
45 |
|
46 |
Wire.begin(); |
47 |
Serial.begin(9600); |
48 |
|
49 |
pinMode(PIN_TASTER, INPUT_PULLUP); |
50 |
|
51 |
pinMode(led_green, OUTPUT); |
52 |
pinMode(led_yellow, OUTPUT); |
53 |
pinMode(led_red, OUTPUT); |
54 |
pinMode(motor, OUTPUT); |
55 |
|
56 |
digitalWrite(led_yellow, HIGH); |
57 |
digitalWrite(led_red, HIGH); |
58 |
digitalWrite(led_green, HIGH); |
59 |
digitalWrite(motor, HIGH); |
60 |
delay(500); |
61 |
digitalWrite(motor, LOW); |
62 |
Serial.print(startdelay); |
63 |
//delay(startdelay); |
64 |
|
65 |
digitalWrite(led_yellow, LOW); |
66 |
digitalWrite(led_red, LOW); |
67 |
digitalWrite(led_green, LOW); |
68 |
//timer.setInterval(500L, display_pHValue); |
69 |
} |
70 |
|
71 |
void loop() |
72 |
{ |
73 |
|
74 |
bool zustandTaster = digitalRead(PIN_TASTER); |
75 |
|
76 |
//ganzes Programm wird ausgesetzt, falls Schalter aus ist |
77 |
if(zustandTaster == 1){ |
78 |
|
79 |
//timer.run(); // Initiates SimpleTimer |
80 |
for(int i=0;i<10;i++) { |
81 |
buffer_arr[i]=analogRead(A0); |
82 |
delay(30); |
83 |
} |
84 |
//Serial.print(analogRead(A0)); |
85 |
for(int i=0;i<9;i++){ |
86 |
for(int j=i+1;j<10;j++){ |
87 |
if(buffer_arr[i]>buffer_arr[j]){ |
88 |
temp=buffer_arr[i]; |
89 |
buffer_arr[i]=buffer_arr[j]; |
90 |
buffer_arr[j]=temp; |
91 |
} |
92 |
} |
93 |
} |
94 |
avgval=0; |
95 |
for(int i=2;i<8;i++) |
96 |
avgval+=buffer_arr[i]; |
97 |
float volt=(float)avgval*5.0/1024/6; |
98 |
ph_act = calibration_value_1 * volt + calibration_value_2; |
99 |
Serial.print("Spannung: "); |
100 |
Serial.print(volt); |
101 |
Serial.print(" "); |
102 |
|
103 |
//Medianbildung des ph-Werts |
104 |
ph_act59[lauf_var1]=ph_act; |
105 |
lauf_var1 = lauf_var1 + 1; |
106 |
if(lauf_var1>=anz_med){ |
107 |
lauf_var1 = 0; |
108 |
} |
109 |
|
110 |
ph_act_med = QuickMedian<float>::GetMedian(ph_act59, anz_med); |
111 |
|
112 |
// Reaktion auf Median |
113 |
if(ph_act_med>ph_obergrenze){ |
114 |
digitalWrite(led_green, LOW); |
115 |
digitalWrite(led_yellow, HIGH); |
116 |
digitalWrite(led_red, LOW); |
117 |
}else if(ph_act< ph_untergrenze){ |
118 |
digitalWrite(led_green, LOW); |
119 |
digitalWrite(led_yellow, LOW); |
120 |
digitalWrite(led_red, HIGH); |
121 |
}else { |
122 |
digitalWrite(led_green, HIGH); |
123 |
digitalWrite(led_yellow, LOW); |
124 |
digitalWrite(led_red, LOW); |
125 |
} |
126 |
|
127 |
//Ansteuerung Motor |
128 |
lauf_var2 = lauf_var2 + 1; |
129 |
if(lauf_var2>=anz_mot){ |
130 |
digitalWrite(motor, HIGH); |
131 |
lauf_var3 = lauf_var3 + 1; |
132 |
} |
133 |
if (lauf_var3>=mot_vol){ |
134 |
digitalWrite(motor, LOW); |
135 |
lauf_var2 = 0; |
136 |
lauf_var3 = 0; |
137 |
} |
138 |
|
139 |
} // if |
140 |
else{ |
141 |
digitalWrite(led_green, LOW); |
142 |
digitalWrite(led_yellow, LOW); |
143 |
digitalWrite(led_red, LOW); |
144 |
digitalWrite(motor, LOW); |
145 |
lauf_var2 = 0; |
146 |
lauf_var3 = 0; |
147 |
} |
148 |
|
149 |
Serial.print(0); //lower limit scale |
150 |
Serial.print(" "); |
151 |
Serial.print(14); //upper limit scale |
152 |
Serial.print(" ph_act: "); |
153 |
Serial.print(ph_act); //diplay current pH-value |
154 |
Serial.print(" ph_act_med: "); |
155 |
Serial.println(ph_act_med); //display pH-median |
156 |
|
157 |
|
158 |
delay(700); //repeate the program every 1sec; internal delay ~300ms} |
159 |
|
160 |
} |
4. Reaktor
4.1. Zusammenbau Reaktor