Software
Op de hardware / elektronica pagina heb je kunnen zien, dat er een behoorlijke hoeveelheid elektronica ontwikkeld is om de brouwinstallatie te automatiseren. Maar deze hardware is nutteloos zonder bijbehorende software, die een en ander controleert en bestuurt.Toen ik startte met het ontwerp van mijn systeem, was flexibiliteit een belangrijke voorwaarde. Ik kon een ontwerp maken op basis van een microcontroller, waarin ik embedded software plaatste, zodat je geen PC nodig had. Maar omdat ik toch verschillende PCs in mijn huis heb, is het wel net zo makkelijk om een PC te gebruiken voor het besturen van je brouwerij.
Op deze manier is het makkelijk om nieuwe functionaliteit toe te voegen. Als ik een nieuwe functie wil toevoegen aan de besturing, dan maak ik een update van het bestaande programma, ik test het en daarna installeer ik het op de PC in de brouwerij (via het netwerk).
Welke programmeertaal moet er gebruikt worden? Ik ben niet echt een voorstander van moderne programmeertalen zoals Java en C#/.Net (ik heb nog nooit MS programmeeromgevingen gebruikt en dat was ik nu ook maar niet van plan!).
Normaliter schrijf ik mijn programma's in the programmeertaal C, maar voor een programma onder Windows heb ik een programmeertaal nodig waarmee ik ook redelijk makkelijk een front-end GUI (windows, menus, muis etcetera) kan maken. Op zich is de taal C daar minder goed geschikt voor. De oplossing lag echter voor de hand: gebruik de programmeertaal C++ (object georiënteerd). Hiermee kun je ook je bestaande routines uit de taal C gebruiken en tegelijkertijd toch een mooi Windows programma maken.
En als je nu ook nog eens Borland's meer dan uitstekende C++ Builder gebruikt, dan is het programmeren hiervan echt een feest om te doen!
Oke, de configuratie is gekozen, de programmeertaal en omgeving zijn ook geselecteerd. Wat kunnen we nog meer doen?
Welnu, ik zou wat kunnen vertellen over de interne structuur van mijn brouwprogramma (die ik e-brew! gedoopt heb, hetgeen staat voor elektronisch brouwen).
Deze pagina bestaat dan ook uit de volgende paragrafen:
- 1. Overview / Architectuur
- 2. De Main Interrupt Loop
- 3. Het toestandsdiagram
- 4. Grafische User Interface (GUI)
1. Overview / Architectuur

Dit plaatje laat de software architectuur zien. Ik heb geprobeerd om de software zo modulair mogelijk te ontwerpen, zodat als ik ook hardware ga wijzigen, of overstap op andere / nieuwere ICs, ik relatief makkelijk de software kan wijzigen.
- De onderste laag met software routines is de I2C fysieke laag. Deze routines houden zich bezig met het lezen en schrijven van een byte van en naar de parallelle poort (waarmee de elektronica met de PC verbonden is). Directe toegang tot de parallelle poort is onder Windows 2000 en Windows NT/XP verboden. Je hebt hier een aparte device-driver voor nodig. Nu zijn er daarvan verschillende programma's gratis te downloaden. Ik heb de PortTalk driver gebruikt, die je gratis kunt downloaden van de website van BeyondLogic.
- De volgende laag met software routines is de I2C hardware laag. De routines in deze laag houden zich bezig met het zenden en ontvangen van bytes via de I2C bus, hierbij gebruik maken van de routines uit de I2C fysieke laag. De I2C bus kan, m.b.v. de routines uit deze laag, op twee manieren aangesproken worden. De eerste methode is via de PCF8584 I2C Bus controller, de tweede methode is via een mechanisme dat bekend staat als bit-banging (de I2C signalen worden dan direct vanaf de parallelle poort gegenereerd, de PCF8584 wordt dan niet gebruikt). Voor het brouwprogramma wordt alleen manier 1 gebruikt, dus gebruik makend van de PCF8584 (maar mocht ik ooit de PCF8584 niet meer willen gebruiken, dan kan ik eenvoudig overschakelen op de bit-banging manier).
- De I2C bus laag bevat de noodzakelijke routines voor de I2C bus zelf, zoals i2c_start(), i2c_init(), i2c_read() en i2c_write(). Deze routines maken gebruik van de routines uit de I2C hardware laag.
- De I2C device laag bevat alle routines voor de diverse ICs, die gebruikt worden. Op dit moment bevat deze laag routines voor de SAA1064 (LED-display), de LM92 digitale temperatuursensor, de MAX1238 AD-converter, de PCF8574 IO-chip en de PCF8591 AD-DA converter. Deze routines maken weer gebruik van de routines uit de I2C hardware laag.
- Er is een aparte software bibliotheek geschreven voor ondersteunende functies. Deze bibliotheek is geschreven in C en bevat routines voor o.a. de afhandeling van de log-file, het toestandsdiagram, de PID regelaar etcetera. Deze routines worden vanuit de applicatie/object laag aangeroepen.
- De applicatie/object laag is de hoogste niveau software laag. Het bevat alle C++ objecten die benodigd zijn om de totale brouwapplicatie te kunnen bouwen.
2. Main Interrupt Loop
De e-brew! applicatie vraagt strakke timingseisen, omdat er verschillende AD conversies gedaan moeten worden. Om ruis en andere onregelmatigheden zoveel mogelijk te minimaliseren, moeten die AD conversies op vaste momenten in de tijd gebeuren. Het zou heel mooi zijn om de beschikking te hebben over een real-time embedded operating systeem, maar Windows komt bij zoiets nog niet eens in de buurt. Om de 50 milliseconden iets uitvoeren, wordt al erg lastig. Gelukkig is er een klein C++ object, dat Animation Timer (TAnimTimer) heet, die zorg draagt voor een nauwkeurige timing, tot op milliseconde niveau (0.001 seconde). En dit is afdoende voor onze doeleinden.Door dit object op het Main Form te plaatsen van de e-brew! applicatie, en door gebruik te maken van de OnTimer() event ervan, kan een nauwkeurige timer interrupt verkregen worden. Wat er ook gebeurt in de e-brew! applicatie of in Windows (behalve een complete systeemcrash), de timer interrupt treedt iedere 50 milliseconden op (dit is 20 keer per seconde). Deze timer interrupt is dan ook de belangrijkste tijdbasis voor de e-brew! applicatie. Alles wat binnen het programma gedaan wordt, is gerelateerd aan deze 50 msec. interrupt!

Deze figuur laat een zogeheten structure chart zien van die timer interrupt (die hier t50msec2timer() genoemd is). Het laat zien wanneer en welke functies aangeroepen worden vanuit deze timer interrupt.
Deze timer interrupt wordt dus iedere 50 msec. aangeroepen. Maar het is niet erg zinvol en economisch om alle functies in diezelfde 50 msec. interrupt aan te roepen. Als voorbeeld hiervan de PID regelaar routine. Als deze 1 keer per 5 seconden aangeroepen wordt, dan is dat snel genoeg. Hetzelfde geldt voor de LED displays: als deze iedere seconde bijgewerkt worden met een nieuwe waarde, dan is dat meer dan snel genoeg.
Dit houdt dus in dat we deze timer interrupt routine kunnen verdelen in zogeheten timeslices. In iedere timeslice kan dan een bepaalde functie aangeroepen worden. Op deze manier wordt de werklast dus netjes verdeeld in de tijd.
Omdat we 20 interrupts aanroepen per seconde hebben, is het logisch om 20 timeslices te maken. In de structure chart zijn ze dan ook genummerd van TS1 tot en met TS12 (TS13 tot en met TS20 worden nog niet gebruikt). In timeslice TS1, wordt de functie get_analog_input() aangeroepen. Deze leest de waarde van het HLT volume van de AD-converter. In timeslice TS2 wordt dezelfde functie nog eens aangeroepen, maar dan om het MLT volume in te lezen. Enzovoorts.
Alleen de functie Generate_IO_Signals() wordt iedere keer aangeroepen. Deze functie verstuurt de binaire IO signalen naar de elektronica (bijv. het knipperen van de Alive LED, die 500 msec. aangezet wordt en dan weer 500 msec. uitgezet wordt).
Terug naar boven
3. Toestandsdiagram
Volgens de free online dictionary of Computing is een toestandsdiagram (state transition diagram, of STD) "een diagram die uit cirkels bestaat, die toestanden voorstellen. Ook bestaat zo'n diagram uit gerichte pijlen tussen die toestanden. Deze stellen de overgangen voor. Een of meerdere acties (outputs) kunnen gekoppeld worden aan zo'n overgang.".Kijkend naar de e-brew! applicatie, dan is een STD een centrale besturingsfunctie, die de verschillende fasen van het brouwproces coördineert. Een toestand kan zoiets zijn als 'maisch rust' of 'voorverwarmen'. Een overgang van de ene toestand naar de andere toestand wordt uitgevoerd wanneer de bijbehorende conditie WAAR is (bijv. de 'temperatuur is ok'). Wanneer een overgang naar een andere toestand uitgevoerd wordt, dan kan er ook een bijbehorende actie uitgevoerd worden. (bijv. 'zet pomp aan').
Samengevat: er zijn toestanden, overgangen tussen die toestanden, condities en acties. Deze zaken moeten gedefinieerd gaan worden voor de e-brew! applicatie.
Het eerste dat we moeten doen is een analyse maken van het brouwproces, om hieruit de unieke toestanden af te leiden. Voor het brouwprogramma kom ik uiteindelijk op de volgende toestanden uit:
- 00. Initialization: deze toestand wordt actief na het opstarten van het brouwprogramma. Het programma blijft in deze toestand zolang de brouwer de PID regelaar niet ingeschakeld heeft.
- 01. Wait for HLT temp.: in deze toestand heeft de brouwer de PID regelaar ingeschakeld en wordt het water in de HLT opgewarmd. Maar de inmaisch temperatuur is nog niet bereikt.
- 02. Fill MLT: De HLT temperatuur is OK, de pomp wordt aangezet. Hierdoor wordt de MLT gevuld met de ingestelde hoeveelheid water. In deze toestand dient de brouwer de gemalen mout toe te voegen aan de MLT.
- 03. Mash in progress: De MLT temperatuur heeft nog niet de vooraf ingestelde maischtemperatuur bereikt.
- 04. Mash timer running: De MLT temperatuur heeft de gevraagde maischtemperatuur bereikt. De maischrust timer is gestart, maar heeft nog niet zijn eindwaarde bereikt.
- 13. Mash preheat HLT: de maischrust is nog niet klaar, maar de HLT wordt alvast opgewarmd naar de volgende maischtemperatuur (de pomp wordt wel uitgezet in deze fase). Wanneer er een time-out optreedt van de maischrust timer, dan wordt de overgang gemaakt naar de toestand 03. Mash in progress, en de mash-index wordt met 1 verhoogd.
- 05. Sparging rest: deze toestand wordt actief wanneer alle maisch temperaturen en tijden afgehandeld zijn. Het maischen in voorbij, en het spoelen wordt gestart. Wanneer deze toestand voor het eerst actief wordt, (komende vanuit toestand 13. Mash preheat MLT), dan wordt er direct een overgang gemaakt naar de toestand 06. Pump from MLT to Boil. In alle andere gevallen blijft het toestandsdiagram in deze toestand voor een bepaalde tijd (20-25 minuten). Een overgang naar de toestand 09. Empty MLT wordt gemaakt wanneer het aantal keren spoelen van de mout overeenkomt met het vooraf ingestelde aantal (meestal 4-5 keer). Dit betekent dat we klaar zijn met spoelen.
- 06. Pump from MLT to Boil. Een deel van het wort wordt overgepompt van de maischketel (MLT) naar de kookketel. Wanneer het vooraf ingestelde volume is overgepompt, dan wordt de overgang gemaakt naar de toestand 07. Delay_xSec.
- 07. Delay_xSec., het toestandsdiagram blijft in deze toestand voor 1 seconde, om het systeem even tot rust te laten komen.
- 08. Pump from HLT to MLT. In deze toestand wordt nieuw vers water van 80 °C uit de warmwaterketel (HLT) naar de maischketel (MLT) gepompt. Wanneer het vooraf ingestelde volume is overgepompt, dan wordt een overgang gemaakt naar de toestand 05. Sparging Rest en wordt de spoel-index (sparging index, sp_idx) met 1 verhoogd.
- 09. Empty MLT. Nadat het vooraf ingestelde aantal keren spoelen uitgevoerd is, kom je in deze toestand terecht. Alle wort uit de maischketel wordt overgepompt naar de kookketel.
- 10. Boil. Wanneer gestart wordt met koken, komt het toestandsdiagram in deze fase terecht.
- 11. Empty Heat Exchanger. Deze toestand wordt niet meer gebruikt en zal waarschijnlijk verwijderd worden in een nieuwe versie van het brouwprogramma.
- 12. Chilling. Na het koken van het wort, wordt het wort, via de tegenstroomkoeler naar het gistvat gepompt.

De rode teksten in de figuur stellen de condities voor. Wanneer zo'n conditie WAAR wordt, dan wordt die overgang uitgevoerd. Tijdens deze overgang, wordt de bijbehorende actie (de groene tekst) uitgevoerd.
De tabel (rechter bovenhoek) laat zien welke kleppen in welke toestand open (1) of gesloten (0) zijn. Door op deze manier je ontwerp te maken kun je het gedrag van de verschillende kleppen goed definiëren. Het is altijd duidelijk in welke toestand een bepaalde klep open of gesloten is.
Er zijn nog heel wat meer details te vertellen over dit toestandsdiagram, maar het bovenstaande verhaal is hopelijk voldoende om een beeld te geven van de werking. Voor de volledigheid wordt nog opgemerkt dat het toestandsdiagram 1 keer per seconde uitgevoerd wordt (wordt aangeroepen vanuit de timer interrupt).
Terug naar boven
4. Grafische User Interface (GUI)
De timer interrupt en het toestandsdiagram vormen het hart en ziel van het brouwprogramma. Maar om dit flexibel aan te kunnen sturen en te controleren, is het van belang om een goede gebruikersinterface (Graphical User Interface of GUI) te realiseren. Dat is inmiddels gebeurd en deze paragraaf laat een aantal zaken daarvan zien. Zo zie je hier een screenshot van het hoofdscherm van de e-brew! applicatie:
Er is het nodige op te zien, wat ideaal is wanneer je aan het brouwen bent en je snel even bepaalde waarden wilt zien of controleren:
- HLT en MLT thermometers: Deze thermometers geven de actueel gemeten temperaturen aan. Een digitale versie wordt ook weergegeven (het plaatje laat een actuele temperatuur zien van 79.00 °C voor de HLT en 76.81 °C voor de MLT. De gewenste (referentie) temperatuur voor de HLT is 79 °C en voor de MLT is dat 78 °C (dit screenshot is genomen tijdens de laatste spoelfase van een brouwsessie, waar Thlt continu op 79 °C gehouden wordt).
- PID regelaar schakelpaneel: De PID regelaar kan met dit schakelpaneel aan- en uitgezet worden. Wanneer de PID regelaar uitgezet wordt, dan is de output altijd gelijk aan 0 %.
- Huidige toestand: Dit label geeft de actuele toestand weer van het toestandsdiagram. De huidige toestand in het screenshot is "05. Sparging Rest".
- Temperatuur van de elektronica: dit is de actuele temperatuur van de koelplaat van de vermogenselektronica (de triac). De thermometer kleurt rood wanneer de temperatuur te hoog wordt (de output van de PID regelaar wordt dan 0 %). De huidige temperatuur is hier 24 °C.
- Vermogensbalk: dit is de rode balk met de tekst "heating element". Het geeft de output van de PID regelaar aan. Hier is dat 32 %. De tekst "3000 W" is enigszins gedateerd en moet vervangen worden door 24 kW (vanwege de recent geïnstalleerde gas branders).
- De actuele volumes in de ketels: in het screenshot is dit 43.3 liter, 58.5 liter en 55.6 liter voor respectievelijk de warmwaterketel (HLT), de maischketel (MLT) en de kookketel. Ook hier geldt weer dat de teksten die de maximale volumes weergeven enigszins gedateerd zijn (ik weet het: er moet nodig een nieuwe versie van de software gemaakt worden!).
- De status van de pomp: drie opties zijn hier mogelijk: "Auto", "Pump Off (M)" en "Pump On (M)". Deze opties kunnen geselecteerd worden door met de rechter muis toets op de pomp te klikken. Wanneer de optie "Auto" geselecteerd is, dan zal het brouwprogramma (en dan met name het toestandsdiagram) de pomp in en uit schakelen. De brouwer kan deze automatische werking overrulen door een van de handmatige opties te kiezen (dat wordt dan aangegeven door een (M) bij het symbool van de pomp (zoals hier het geval is).
- De status van iedere elektrische klep: wederom zijn, voor iedere klep, drie opties mogelijk: "Auto", "Off (M)" en "On (M)". Ondanks dat er op dit moment nog geen elektrische kleppen aanwezig zijn in de brouwinstallatie, is de software daar al helemaal op voorbereid.
- De rode tekst in de linker onderzijde geeft specifieke debug informatie aan voor de PID regelaar. Met de weergegeven getallen kan de correcte werking van de PID regelaar nagegaan worden.
- De status balk: de status balk geeft wat algemene informatie weer, zoals bijv. het versienummer van het brouwprogramma.
4.1 De menu-balk van het e-brew! programma
De menu-balk van het brouwprogramma bevat de volgende menu items:- File -> Read Log File...: wanneer er een fout opgetreden is in de hardware of de software, dan kan met behulp van deze functie het systeem weer terug gebracht worden in de toestand net voor de crash.
- File -> Exit: afsluiten van het brouwprogramma, de I2C bus wordt gesloten en alle elektronica wordt uitgezet.
- Edit -> Mash Scheme...: met deze optie kunnen tot 10 temperatuur-tijd paren ingevoerd worden. Hiermee kunnen specifieke tijden en
temperaturen voor een maischschema ingevoerd worden.

- Edit -> Fix Parameters...: iedere variabele die van belang is, kan een waarde gegeven worden m.b.v. deze functie. Voorbeeld:
het brouwprogramma leest standaard de waarde van de HLT temperatuur van de digitale temperatuursensor. Stel nu dat de gebruiker
een bepaalde waarde voor deze temperatuur wil instellen (bijv. om iets te testen), waarbij het standaard inlezen dus overruled gaat
worden. Met behulp van deze functie kan een specifieke waarde ingesteld worden. Na vrijgeven van deze variabele neemt het brouwprogramma
de controle weer over voor deze variabele.

- View -> Check I2C Hardware Devices: voer deze optie uit wanneer je wilt kijken welke ICs er aanwezig zijn op de I2C bus. Het resultaat
wordt weergegeven op een schermpje, waarop de gevonden en niet gevonden ICs getoond worden.

- View -> Data Graphs: deze optie laat een continu lopende grafiek zien van enkele variabelen (zoals temperatuur en volume).
- View -> Mash/Sparge Progress: deze optie toont een scherm met de status van alle maisch- en spoel-timers. Hiermee kun je direct zien
hoe lang een bepaalde rust nog duurt. Dit screenshot is genomen tijdens de laatste spoelfase (alle maisch timers zijn al afgelopen en
de spoel index (sparging index, sp_idx) is gelijk aan 5. De spoeltimer is nu 855 en zal een time-out geven wanneer deze 1200 seconden bereikt.

- Help -> Contents...
- Help -> How to Use Help
- Help -> About...: laat het versienummer zien van het brouwprogramma.
- Options -> I2C Hardware Settings...: hiermee kunnen verschillende parameters ingesteld worden die te maken hebben met de hardware.

- Options -> PID Controller Settings...: hiermee kunnen verschillende parameters ingesteld worden die te maken hebben met de PID regelaar.

- Options -> Sparge & STD Settings...: hiermee kunnen verschillende parameters ingesteld worden die te maken hebben met het maischproces, het spoelproces
en het toestandsdiagram.

- Options -> Measurements...: hiermee kunnen verschillende parameters ingesteld worden die te maken hebben met de verschillende meetwaarden, zoals
welk signaal op welke AD-converter staat. Ook details m.b.t. softwarematige filtering van het signaal kunnen hier ingesteld worden.

Terug naar boven