Examensarbete 15 hp Att gå från PLC till mikrokontrollerbaserad lösning vid styrning av reningsverksprocess 2011-06-07 Ämne: Elektroteknik Nivå: Grundnivå Kurskod: 2ED13E
Organisation/ Organization Författare/Author(s) Linnéuniversitetet, Institutionen för datavetenskap, fysik och matematik Linnaeus University, School of School of Computer Science, Physics and Mathematics Dokumenttyp/Type of Document Handledare/tutor Examinator/examiner Examensarbete/Diploma Work Anders Haggren Titel och undertitel/title and subtitle Att gå från PLC till mikrokontrollerbaserad lösning vid styrning av reningsverksprocess Transition from a PLC to a microcontroller based solution controlling a wastewaterplant Sammanfattning (på svenska): Syftet var att undersöka om det gick att byta ut PLC mot en lösning baserad på mikrokontroller samt att ge ett exempel på hur en sådan lösning skulle kunna se ut för ett reningsverk i Kompakt-serien från BAGA Water Technology AB. Lösningen är baserad kring Arduino Mega. Arduino Mega är ett Arduino kort baserat på mikrokontrollen Atmel ATmega 1280. Arduino är en plattform baserad på öppen källkod, bestående av en fysisk hårdvara och en programmeringsmiljö att skriva mjukvara till den fysiska hårdvaran. För att kunna testa och demonstrera programmet, så gjordes en uppkoppling baserat på Arduino Mega och en LCDshield. Reningsverkets process är definierad som en tillståndsmaskin av Mealy-typ. Utifrån de tillstånden som bestämts, så bestämdes villkoren för övergång från ett tillstånd till nästa samt vilka variabler som skulle ändras i samband med tillståndsövergången. Programmeringen följde sen detta. Största delen av arbetet har bestått i att definiera processen och det därpå följande arbete med programmet. Slutsatsen som jag kan dra av arbetet är att det är möjligt att ersätta PLC i ett BAGA reningsverk med en lösning som är baserad på mikrokontroller. Kostnaden per producerad enhet blir lägre med en egenutvecklad lösning baserad på mikrokontroller. Det bör dock tänkas på hur lång produktserie som ska byggas, eftersom det kan bli en oekonomisk lösning om serien blir för kort, på grund av de högre utvecklingskostnaderna jämfört med lösning baserad på PLC. Nyckelord: Arduino, PLC, mikrokontroller, reningsverk Abstract (in English) The aim was to investigate if it was possible to move from a sollution based on PLC to a micro controller based for wastwater plants in the Kompakt serie from Baga Water Technology AB. The solution is based on the Arduino Mega. The Arduino Mega is built around the Atmel ATmega 1280 microcontroller Arduino is a platform based on open source, consisting of a physical hardware and a programming environment to write software to the physical hardware. To test and demonstrate software, a demonstration board based on Arduino Mega, and a LCD shield, was built. The wastewaterplant process was defined as a state machine of Mealy type. Based on the states, the conditions for transition from one state to the next was defined and coding process followed. The large part of the work has been defining the process and the following coding. The conclusion I can draw from the work is that it is possible to replace the PLC in a BAGA sewage treatment plant with a solution based on a microcontroller. Cost per unit is lower with a proprietary solution based on microcontroller but the development cost for the hardware is greater than for a PLC based sollution. Therefor one should take in mind the length of the product serie. Key Words: Arduino, PLC, microcontroller, wastewaterplant Utgivningsår/Year of issue Språk/Language Antal sidor/number of pages 2011 Svenska/Swedish 14 Internet/WWW http://www.lnu.se
Sammanfattning Syftet med arbetet var att undersöka om det gick att byta ut PLC mot en lösning baserad på mikrokontroller samt att ge ett exempel på hur en sådan lösning skulle kunna se ut för ett reningsverk i Kompakt-serien från BAGA Water Technology AB. Lösningen är baserad kring Arduino Mega. Arduino Mega är ett Arduino kort baserat på mikrokontrollen Atmel ATmega 1280. Arduino är en plattform baserad på öppen källkod, bestående av en fysisk hårdvara och en programmeringsmiljö att skriva mjukvara till den fysiska hårdvaran. För att kunna testa och demonstrera programmet, så gjordes en uppkoppling baserat på Arduino Mega och en LCDshield. Reningsverkets process är definierad som en tillståndsmaskin av Mealy-typ. Utifrån de tillstånden som bestämts, så bestämdes villkoren för övergång från ett tillstånd till nästa samt vilka variabler som skulle ändras i samband med tillståndsövergången. Programmeringen följde sen detta. Största delen av arbetet har bestått i att definiera processen och det därpå följande arbete med programmet. Slutsatsen som jag kan dra av arbetet är att det är möjligt att ersätta PLC i ett BAGA reningsverk med en lösning som är baserad på mikrokontroller. Kostnaden per producerad enhet blir lägre med en egenutvecklad lösning baserad på mikrokontroller. Det bör dock tänkas på hur lång produktserie som ska byggas, eftersom det kan bli en oekonomisk lösning om serien blir för kort, på grund av de högre utvecklingskostnaderna jämfört med lösning baserad på PLC. Nyckelord: Arduino, PLC, mikrokontroller, reningsverk
Abstract The aim was to investigate if it was possible to move from a sollution based on PLC to a micro controller based for wastwater plants in the Kompakt series from Baga Water Technology AB. The solution is based on the Arduino Mega. The Arduino Mega is built around the Atmel ATMEGA 1280 micro controller Arduino is a platform based on open source, consisting of a physical hardware and a programming environment to write software to the physical hardware. To test and demonstrate software, a demonstration board based on Arduino Mega, and an LCD shield, was built. The wastewaterplants process was defined as a state machine of Mealy type. Based on the states, the conditions for transition from one state to the next was defined and coding process followed. The large part of the work has been defining the process and the following coding. The conclusion I can draw from the work is that it is possible to replace the PLC in a BAGA sewage treatment plant with a solution based on a microcontroller. Cost per unit is lower with a proprietary solution based on microcontroller but the development cost for the hardware is greater than for a PLC based sollution. Therefor one should take in mind the length of the product serie. Key Words: Arduino, PLC, microcontroller, wastewaterplant
Förord Då jag tidigare varit intresserad av att programmera mikrokontrollers från Atmel men upplevt tröskeln för hög, var det med glädje jag upptäckte Arduino. Med den energin jag vunnit, kände jag att det var dags att ta tag i mitt länge väntande examensarbete. Efter ett tags funderande kom jag på att detta kanske skulle kunna ersätta en PLC i större reningsverksautomationer. Efter kontakt med min arbetsgivare, Baga Water Technology AB, fick jag ok att börja. Detta arbete har alltså inte varit på uppdrag av min arbetsgivare utan bara med stöd och uppmuntran från Baga Water Technology AB. Jag hoppas att detta arbete kan ge åtminstone någon inspiration att skapa något kreativt med Arduino. För det finns hur mycket intressanta tillbehör som helst. Jag vill tacka min handledare Anders Haggren på LNU för stöd och hjälp, men framför allt att han direkt vid vår första kontakt erbjöd sig att handleda mig.
Innehållsförteckning 1. Introduktion... 1 1.1 Bakgrund... 1 1.2 Syfte och mål... 1 1.3 Avgränsningar... 1 2. Teori... 2 2.1 Reningsverk... 2 2.1.1 Slamavskiljning... 2 2.1.2 Kemisk rening... 3 2.1.3 Biologisk rening... 3 2.2 Arduino... 4 2.2.1 Arduino Mega 128... 4 2.2.2 Arduino sketch... 4 2.2.3 Arduino shields... 5 3. Metod... 6 3.1 Val av hårdvara... 6 3.2 Processtyrning... 6 3.3 Demonstrationsplattform... 6 3.4 Programmering... 6 4. Resultat... 7 4.1 Processens olika tillstånd... 7 4.2 Demonstrationsplattformen... 9 4.2.1 Digitala ingångar... 9 4.2.2 Digitala utgångar... 9 4.2.3 Analoga ingångar... 10 4.3 Programkod... 10 4.3.1 Inkluderade bibliotek... 10 4.3.2 Variabler... 10 4.3.3 Funktioner... 10 4.3.4 setup()... 10 4.3.5 loop()... 11
5. Diskussion... 12 5.1 Framtida arbete... 13 6. Referenser... 14 7. Bilagor... 15
1. Introduktion För att kunna sänka kostnaden för reningsverks automatik, ska jag undersöka om det är möjligt att få samma funktion med en lösning baserad på mikrokontroller, som vid användande av PLC (Programmable Logic Controller). 1.1 Bakgrund Avloppsrening är en komplicerad process med många insignaler från nivågivare och sensorer samt utsignaler till pumpar och ventiler. Processen styrs normalt med en PLC. En fördel med att använda PLC är att det är snabbt att utveckla prototyper och göra justeringar, både logiskt och i hårdvara innan produkten är färdig. Om reningsverkets automatik ska gå från prototypstadium till serieproducerad produkt, hur skulle det då kunna se ut? Är det möjligt att lämna PLC och gå över till en lösning baserad på mikrokontroller? 1.2 Syfte och mål Syftet är att undersöka om det går att byta ut PLC mot en lösning baserad på mikrokontroller samt att ge ett exempel på hur en sådan lösning skulle kunna se ut. Det ska alltså inte vara någon färdig produkt, utan vara en demonstration på mikrokontrollerns möjligheter. Denna demonstration kommer att bygga på Arduinoplattformen och vara avsedd för reningsverk i Kompakt-serien från BAGA Water Technology AB. Se exempel på ett reningsverk i Kompakt-serien från BAGA Water Technology AB i bilaga 1 1.3 Avgränsningar Demonstrationen ska på inga sätt ses som någon färdig produkt utan bara demonstrera att det är möjligt att skapa motsvarande lösning, som med PLC, fast baserad på mikrokontroller. 1
2. Teori 2.1 Reningsverk Rening av avloppsvatten i ett reningsverk i Kompakt-serien från BAGA Water Technology AB, se figur 1, sker i stora drag som följer: Avloppsvattnet rinner eller pumpas in i reservoaren, som är den första tanken i reningsverket. Avloppsvattnet pumpas därifrån satsvis vidare till slamavskiljaren för slamavskiljning. Vattnet kan vid inpumpning förfällas, dvs. flockningsmedel inblandas i vattnet. Vid start av varje cykel, pumpas avslammat vatten in i bioreaktorn. När vätskenivån i bioreaktorn når bräddavloppet, så bräddar det biologiskt behandlade vattnet ut ur reaktorn till en efterfällningstank kallad polersteg. I polersteget är det än en gång möjligt att bland in flockningsmedel i vattnet, var efter vattnet pumpas till recipient. (Alla parametrar och händelser är inte angivna av sekretesskäl.) Figur 1 Reningsverk av typ Kompakt från BAGA Water Technology AB 2.1.1 Slamavskiljning Slamavskiljningen sker genom sedimentering. Detta är ett passivt steg som förlitar sig 2
på att vattenströmmarna i tanken är så svaga, att partiklarnas sjunker till botten som slam. Det sedimenterade slammet i slamavskiljaren pumpas regelbundet över till en slamsilo. 2.1.2 Kemisk rening Med tillsats av olika fällningskemikalier, kan mindre partiklar, som annars inte hade gått att avskilja från vattnet genom sedimentering, fås att aggregera och falla ner som slam. Avskiljande av fosfor ur vattnet är ytterligare en anledning till att tillsätta fällningskemikalier. Tillsättning av flockningsmedel vid slamavskiljning, innan biologisk process, kallas förfällning. Tillsättning av flockningsmedel i ett polersteg, efter biologisk process, kallas efterfällning.(1) 2.1.3 Biologisk rening I det biologiska steget sker rening med hjälp av bakterier. Bakterier hjälper till att bryta ner mindre partiklar i vattnet. Detta sker i omväxlande syrefattiga och syrerika miljöer. Ammoniumkväve är ett av de ämnena som reduceras i det biologiska steget. Ammoniumkväve är tillsammans med fosfor de två ämnena, förutom biologiska och kemiska syreförbrukare, som Naturvårdsverket kan kräva rening av i ett avloppsreningsverk.(2-3) 3
2.2 Arduino Arduino is an open-source electronics prototyping platform based on flexible, easy-to-use hardware and software. It's intended for artists, designers, hobbyists, and anyone interested in creating interactive objects or environments..arduino.cc/en Arduino är en open-sorce plattform bestående av en fysisk hårdvara och en programmeringsmiljö att skriva mjukvara till den fysiska hårdvaran. Hårdvaran består av enkla mikrokontrollerbestyckade kretskort med digitala och analoga in- och utgångar. Arduino passar bra till produktutveckling eftersom programmeringen sker i ett C liknande språk, istället för assembler, och inga egentliga kunskaper om mikroprocessorns hårdvara behövs. Det finns en uppsjö med officiella Arduinokort, men alla som så önskar, kan utveckla och producera kompatibla kort utan att behöva betala royalty till Arduino. (4) 2.2.1 Arduino Mega 128 Arduino Mega är ett Arduino kort baserat på mikrokontrollen Atmel ATmega 1280. Det är detta kort som arbetet är baserat kring. Kortet har totalt 54 digitala anslutningar. Vid programmering är det möjligt att bestämma, för var och en av dem, om de ska användas som in eller utgångar. 14 av de digitala anslutningarna kan vid användning som utgångar pulsbreddsmoduleras och på så sätt simulera analoga utgångar. De digitala utgångarna kan belastas upp till 40 ma, dvs de kan utan problem driva en lysdiod (ca 20 ma) eller t.ex. en optokopplare (5 20 ma). Kortet har också 14 analoga ingångar och fyra seriella hårdvaruportar. För att lätt kunna ansluta kortet till dator, PC eller Mac, för att enkelt kunna överföra program skrivna i programmeringsmiljön, har den en USB-anslutning. USB-anslutingen kan också fungera som spänningsmatning åt kortet om ingen annan extern spänningsmatning är tillgänglig. Mikrokontrollern, Atmel ATmega1280, har 128 KB flashminne för programkod. Fyra KB av flashminnet är dock upptagna av bootloader. Variabler eller konstanter som ska behållas i minnet även efter ett spänningsfall kan lagras i mikroprocessorns EEPROM á fyra KB. För Arduinos officiella specifikation, se bilaga 2 och för Arduino Mega schema, se bilaga 3 2.2.2 Arduino sketch Kod skrivet för ett Arduinosystem kallas sketch. En sketch består av biblioteksinkludering, deklarerande av variabler och funktioner, ett anrop av setupfunktion och huvudloopen. Bibliotek som inkluderas kan vara för att till exempel styra en display, skriva i EEPROM eller använda TCP/IP. Variabler som ska användas globalt i en sketch måste deklareras. Även egenskrivna funktioner som ska anropas 4
deklareras. Funktionen setup() körs en gång innan huvudloopen tar vid. I setupfunktionen definieras om en anslutning till kortet ska vara in- eller utgång. Här initieras även variabler vid behov. Saker som bara ska göras en gång, så kallade runonce, placeras med fördel här. 2.2.3 Arduino shields Arduinokort är konstruerade så att det är möjligt att stapla flera kort ovan på varandra. Dessa kort som staplas på ett Arduinokort med mikrokontrollern kallas shields. Detta är konstruerat så att samtliga ut- och ingångarna på processorkortet är tillgängliga på alla shields. 5
3. Metod 3.1 Val av hårdvara Arbetet började med att räkna ut behovet av in- respektive utgångar för att därefter kunna bestämma vilket Arduinokort som skulle behövas. Det totala antalet in- och utgångar för styrningen av reningsverkets process blev 19 st. Dessa fördelades på sju digitala ingångar, 1 analog ingång, och 11 digitala utgångar. För att kunna styra en display så behövdes det ytterligare 6 digitala utgångar. Detta gjorde att valet föll på, det för tillfället, mest avancerade kortet Arduino Mega. 3.2 Processtyrning Efter visst överläggande bestämdes att processen skulle byggas som en tillståndsmaskin. Eftersom utsignalerna är beroende av både nästkommande tillstånd och på insignalerna så är den av Mealy-typ. Här efter bestämdes de olika tillstånden som maskinen skulle bestå av och vilka krav på insignaler som skulle sättas upp för övergång till nästa tillstånd och vilka utgångar som skulle aktiveras eller avaktiveras. 3.3 Demonstrationsplattform För att kunna testa och demonstrera programmet, så gjordes en uppkoppling baserat på Arduino Mega och en LCD-shield enligt bilaga 4 och bilaga 5. Båda bilagorna är ritade i Frizing 0.5.2b. Ett open-source verktyg för att rita och designa elektronik. 3.4 Programmering Utifrån de tillstånden som bestämts under 3.2, så bestämdes villkoren för övergång från ett tillstånd till nästa samt vilka variabler som skulle ändras i samband med tillståndsövergången. Programmeringen följde sen detta dokument. Resulterande programkod finns i bilaga 6. Koden är skriven i Arduino 0021. 6
4. Resultat 4.1 Processens olika tillstånd För att kunna styra processen som en tillståndsmaskin, måste processen delas upp i olika tillstånd samt vilka in- och utsignaler som är aktuella för de olika tillstånden. Utifrån den erfarenhet som jag har från Baga Water Technology AB har jag definierat tillstånden enligt tabell 1. Processen är bestämd till sju tillstånd. Processens starttillstånd är alltid tillstånd 0 (vila). Under detta tillstånd så pumpas, i intervaller, luft in i botten av bioreaktorn. Processen kvarstår i detta tillstånd till dess att det finns tillräckligt med vatten i reservoaren för att starta en överpumpning till slamavskiljaren. När tillräckligt med vatten finns i reservoaren sker en övergång till tillstånd 1 (Fyller SA) och någon av pumparna i botten av reservoaren startar. Pumparna startar växlande, beroende på vilken pumpning i ordningen det är. Pumpen pumpar avloppsvattnet till slamavskiljaren samtidigt som det finns möjlighet att dosera flockningsmedel. Pumpningen pågår till dess att antingen slamavskiljaren anses vara uppfylld eller att det saknas tillräckligt med vatten i reservoaren. I detta tillstånd fortsätter luftning enligt tillstånd 0. Om det saknas vatten i reservoaren återgår processen till tillstånd 0 (vila). Om slamavskiljaren anses vara uppfylld går processen vidare till tillstånd 2 (Fyller BR). I och med att vi nått tillstånd 2 anses reningsprocessen ha startat och räknaren för antalet renade cykler ökas därför med ett. I tillstånd 2 pumpas avslammat vatten in i bioreaktorn. Volymen vatten som pumpas över bestäms av diametern på tanken och hur mycket vatten nivån sänks. Vattennivån mäts i verkligheten med en trycknivågivare och simuleras med en vridpotentiometer. Under detta tillstånd pumpas luft in i botten av bioreaktorn. När bioreaktorn fylls med vatten bräddar vatten vidare till ett polersteg. När bestämd mängd vatten pumpats från slamavskiljaren till bioreaktorn stannar pumpen och processen går vidare till tillstånd 3 (Återfyllning av SA). I tillstånd 3 återfylls slamavskiljaren, under förutsättningen att det finns vatten i reservoaren, och vattnet i polersteget efterfälls och sedimenteras. Under detta tillstånd pumpas luft in i botten av bioreaktorn. När vattnet i polersteget har stått stilla och sedimenterat den inställda tiden, så sker övergång till tillstånd 4. I tillstånd 4 pumpas klarfasen (det klara vattnet) ut till recipient. Under detta tillstånd pumpas luft in i botten av bioreaktorn. När klarfasen är utpumpad till recipient fortsätter processen till tillstånd 5 (slampumpning av polersteg och slamavskiljare). Under tillstånd 5 pumpas slam från polersteget till slamavskiljaren och slam från slamavskiljaren till slamsilo. Under detta tillstånd pumpas luft in i botten av bioreaktorn. Slampumpen i polersteget stängs av när frånslag sker på den nedre nivåvippan i polersteget. Slampumpen i slamavskiljaren stängs av när bestämd pumptid uppnåtts. Under detta tillstånd pumpas luft in i botten av bioreaktorn. När slampumpningen är klar och luftning av bioreaktorn har pågått under inställd tid, går processen vidare till tillstånd 6 (slamsedimentering i bioreaktor). I tillstånd 6 pumpas ingen luft in i bioreaktorn och bildat slam sedimenterar till botten. När inställd tid uppnåtts går processen vidare till tillstånd 7 (slampumpning av bioreaktor) Det sedimenterade slammet i bioreaktorn pumpas i detta tillstånd till slamavskiljaren. Pumpningen avslutas när trycknivågivaren i slamavskiljaren indikerar att önskad slamvolym är uppnådd eller att max pumptid är uppnådd. Processen går nu vidare till tillstånd 0. 7
Tabell 1. Definitionen på processens olika tillstånd. Tillståndsnummer Tillståndsnamn (vad som står i LCD) Beskrivning av tillståndet 0 Vilar (Rening klar) Om det inte finns något vatten i reservoaren att rena, befinner sig reningsverket i vila. 1 Fyller SA Uppfyllning av slamavskiljaren om dess nivå är under normal och där efter återgång till tillstånd 0 eller vidare till tillstånd 2. Detta tillstånd tar hand om de tillfällen då inte slamavskiljaren är helt uppfylld. Tex vid första start av reningsverket. 2 Fyller BR Uppfyllning av bioreaktorn från slamavskiljaren och start av reningsprocessen. 3 Aterfyll SA Återuppfyllning av slamavskiljaren med förfällning, eventuell efterfällning och omrörning i polersteg samt fortsatt rening i bioreaktor. 4 Tommer PS Utpumpning av fällt och sedimenterat vatten i polersteget till recipient. 5 Slamp. PS+SA Sedimenterat slam i polersteget pumpas till slamavskiljaren och sedimenterat slam från slamavskiljaren pumpas till slamsilo. 6 Slamsed. BR Luftpumpen stoppas och slam tillåts sedimentera i bioreaktorn. 8
7 Slampump BR Sedimenterat slam pumpas över till slamavskiljaren. 4.2 Demonstrationsplattformen Demonstrationsplattformen består av en Arduino Mega med ett Arduino LCD&Keypad shield från dfrobot.com. se bilaga 7 och bilaga 8. De digitala anslutningarna är valbara om de ska vara ingångar eller utgångar i mjukvaran. Analoga ingångar ger värde från 0 till 1023 vid avläsning. De analoga utgångarna är inga egentliga analoga utgångar, utan simulerar en analog signal med pulsbreddsmodulering. Det blir alltså ingen äkta analog signal. 4.2.1 Digitala ingångar De digitala ingångarna växlas mellan 0 resp. 1 genom vippbrytare av på-på -typ, kopplade mot ingången och 5 V respektive signaljord. Till varje använd ingång, är anoden på en röd lysdiod kopplad. Katoden är kopplad till signaljord via ett förkopplingsmotstånd á 220 Ohm, som begränsar strömmen genom lysdioden. Från reservoaren är nivågivarna för startnivå och högnivå kopplade mot ingång 23 resp. 25. Från bioreaktorn är tryckgivaren för sidkanalfläkten ansluten till ingång 33. Från polersteget är tre nivåer anslutna till ingångarna, 35, 37 och 39. För flockningsmedelsdoseringen, indikeras slut på flockningsmedel via ingång 41. Jag har valt att använda udda nummer till ingångar och jämna för utgångar, för att enkelt kunna avgöra om det är en ingång eller utgång. 4.2.2 Digitala utgångar De digitala utgångarnas logiska läge indikeras med gröna lysdioder. Lysdioderna är kopplade mellan utgång och signaljord, med ett förkopplingsmotstånd á 220 Ohm, så att de lyser när det är logisk etta och är släckta vid logisk nolla på respektive utgång. Reservoarens två pumpar är anslutna till utgångarna 22 och 24. Matarpumpen i slamavskiljaren styrs via utgång 26 och slampumpen via utgång 28. Bioreaktorns slampump är ansluten till utgång 30 och sidkanalfläktarna via utgång 32. I polersteget är matarpumpen och slampumpen anslutna till 34 resp. 36. Magnetventilen för recirkulationen är ansluten till 38. Flockningsmedelsdoseringen via doserpumparna styrs via anslutning 40 och 42. 9
4.2.3 Analoga ingångar För att simulera trycknivågivaren mot en analog ingång så används en vridpotentiometer på 10 kohm, där glidkontaktens anslutning anslöts till en analog ingång och kolbanans ändar till 0 V respektive 5 V. Det simulerade värdet från trycknivågivaren visas på displayen för övervakning av slamavskiljarens fyllnadsgrad. 4.3 Programkod Programkoden återfinns i bilaga 6 4.3.1 Inkluderade bibliotek I min sketch, bilaga 6, inkluderas biblioteken EEPROM.h och LiquidCrystal.h på sidan 1. EEPROM.h behövs för skrivning ska kunna ske till mikrokontrollerns EEPROM. Variabler skrivna i mikrokontrollerns EEPROM är tillgängliga även efter att spänningsfall eller reset av systemet. Eftersom antalet reningscykler räknas och värdet måste behållas även om spänningen skulle falla, så inkluderas detta bibliotek. I demonstrationsplattformen ingår även en display och för att kunna styra den, inkluderas LiquidCrystal.h. 4.3.2 Variabler De variabler som deklarerats är in- och utgångar, växlande gång för pumparna i reservoaren, variabler för cykelräknaren med skrivning i EEPROM, variabler för tidstyrning samt trycknivågivaren och de volymer som följer med den. Alla variabler som har deklarerats gällande tid är i millisekunder. Variabler återfinns på sidorna 1-5 i bilaga 6. 4.3.3 Funktioner En funktion för att räkna antal utförda reningscykler skapades och är definierat som antalcyklerplusplus(). Vid anrop av denna funktion ökas cykelräknarens värde med ett och en uppdatering sker av dess värden sparade i EEPROM. Funktionen antalcyklerplusplus() återfinns på sidan 8 i bilaga 6. 4.3.4 setup() De deklarerade variabler, som är in- eller utgångar, blir här definierade som ingångar eller utgångar. Utgångarna styr sidkanalfläkt, pumpar och ventil. Ingångarna tar emot 10
signaler från flottörvippor (digitala ingångar) eller trycknivågivare (analog ingång). Initiering av den seriella kommunikationen sker också här. Den seriella kommunikationen är till för att kunna felsöka systemet på ett behändigt sätt. De variabler som behöver initieras, blir det i denna dela av en sketch, vilket också innefattar displayen grundutseende. Variabeln state sätts här till 0 vilket gör att processen alltid startar i tillståndet vila. Setup() återfinns på sidorna 5-9 4.3.5 loop() Denna del är en implementering av processens olika tillstånd enligt 4.1 och återfinns på sidorna 9-22 i bilaga 6 Delar av programkoden är till, enbart för att kunna felsöka systemet. Vid driftsstörning av ett befintligt reningsverk eller vid driftsättning av ett nytt reningsverk kan detta underlätta. Varje iterering av loop inleds med en avläsning av den analoga ingången för trycknivågivaren. Värdets sparas i variabeln tng_sa av typ int. På detta sätt behöver inte det analoga värdet läsas in mer än en gång per iteration. Den procentuella fyllnadsgraden av slamavskiljaren beräknas med utgång från tng_sa, för att kunna presenteras i displayen och sparas i sa_fill. Eftersom variabeln state initierades till 0 kommer varje uppstart av automatiken börja med att reningsverket är i vila och därför uppfylla kriteriet för att gå in i den första if-satsen, tillstånd 0. I tillstånd 0 finns alternativen, beroende på ingående värden, att antingen gå vidare till tillstånd 1, uppfyllning av slamavskiljaren, tillstånd 2, uppfyllning av bioreaktorn eller att stå kvar i tillstånd 0 och omväxlande bubbla vattnet i bioreaktorn. Vid uppfyllande av ett nytt tillstånds krav, så uppdateras texten i displayen med aktuellt tillstånd, starttiden för det nya tillståndet sparas i variabeln T_statestart och utgångar ändrar värden, för att stanna eller starta pumpar samt öppna eller stänga ventiler. Till sist ändras variabeln state till det nya tillståndets nummer. Utgångar ändras innan övergång till det nya tillståndet för att undvika onödiga uppdateringar av utgångar och där på följande belastning av CPU. Nedan följer förklaring av vissa delar av övriga programmet. I tillstånd 1 fylls slamavskiljaren med vatten från reservoaren, om dess nivå är under normal nivå. Motsvarande inpumpning sker i tillstånd 3 men då som följd av att det pumpats ut vatten ur slamavskiljaren. Tillstånd 1 är till för de tillfällen då slamavskiljarens nivå är låg vid start. Detta kan vara vid driftsättning av reningsverket eller efter en driftstörning. Pumparna som pumpar in vatten från reservoaren går med växlande gång och på så sätt slits pumparna jämnare. Detta sköts genom att kontrollera ifall variabeln pump_gang är jämn eller udda. Under inpumpningen av vatten doseras även flockningsmedel med doserpumpen DP_FF. Inpumpningen pågår så länge som det finns vatten i reservoaren eller till dess att nivån i slamavskiljaren har nått normal nivå. Om vattnet i reservoaren tar slut sker återgång till tillstånd 0 och om nivån i slamavskiljaren når normal nivå sker övergång till tillstånd 2. I tillstånd 3 sker en tidstyrd flockningsmedelsdosering och omrörning i polersteget. 11
5. Diskussion Syftet med arbetet vara att undersöka om det gick att ersätta en PLC i ett reningsverk i Kompakt-serien från BAGA Water Technology AB med en lösning baserad på mikrokontroller. Anledning till övergång till mikrokontroller är en kostnadsfråga. Att valet av plattform föll på Arduino beror på att jag tidigare tittat på möjligheten att programmera mikroprocessorer från Atmel men uppfattat det som allt för svårt och omständigt. Det var antingen assembler som gällde som programmeringsspråk eller så var det kostsamma program som skulle inköpas för att kunna programmera i C eller liknande språk. Efter att delvis både ha programmerat PLC med grindar, funktionsblock och strukturerad text samt nu Arduino med ett C-liknande språk inser jag vilka fördelar som verkligen finns med att använda C istället för grindar och funktionsblock. Med C som programmeringsverktyg går allt att anpassa till den specifika situationen. Samtidigt kan det vara snabbare och enklare att komma igång med traditionell PLCprogrammering med block, om det inte finns någon tidigare erfarenhet av att programmera. Slutsatsen som jag kan dra av arbetet är att det är möjligt att ersätta PLC i ett BAGA reningsverk med en lösning som är baserad på mikrokontroller. Jag definierade processen som en tillståndsmaskin av Mealy-typ istället för en tidsstyrd processdefinition, som annars är normalt. På det viset blev det lätt att programmera processen eftersom varje tillståndsbyte är väl definierad. I kravet för tillståndsbyte, går naturligtvis även tiden att lägga in som variabel. Fördelar med att bygga en egen hårdvaruplattform för automatisering av reningsverk, baserat på mikrokontroller jämfört med PLC, är att de begränsningarna som finns i den annars valda PLC-leverantörens utbud av komponenter, inte begränsar konstruktionen. Kanske är det bara fantasin som sätter gränsen vid en egen konstruktion? Vidare så är kostnaderna för komponenter betydligt lägre, vid konstruerande av en egen plattform, jämfört med om PLC används. Som jämförelse kan nämnas, att om det behövs kommunikation via gsm eller gprs till och/eller från reningsverkets automatik, så kostar ett gsm-modem (M3GSM) och en anslutningsmodul till modemet (M3MOD), för en PLC av märket Crouzet, tillsammans över 6000 kronor, vid köp av minst 5 st. Detta ska jämföras med att en GSM-modul (GM862QUD730-009) till en mikrokontrollerbaserad lösning kan fås för 655 kronor vid köp av minst 10 st. Alla priser är hämtade från ELFAs hemsida 2011-05-08 och exklusive moms. Samtidigt så ska man vara medveten om, att kostnaden för utvecklingen av hårdvaran som behövs för att kunna utnyttja de billigare komponenterna tillkommer. Och att när väl hårdvaran är framtagen, så är det inte precis gjort i en handvändning att ändra på konstruktionen. Det är alltså av stor vikt att lägga ner tid och tanke innan konstruktionen låses för produktion, så att det inte upptäcks behov i efterhand som lösningen inte kan uppfylla. Utvecklingstiden för en mikrokontrollerbaserad lösning är därför längre och dyrare och det krävs en längre produktionsserie för att räkna hem kostnaderna än för en PLC-baserad lösning. 12
Vad driftsäkerheten och tillförlitlighet anbelangar, så gäller nog det vanliga ordspråket, att man får vad man betalar för. D.v.s., om konstruktionen byggs med billiga delar, så kvittar det (med största sannolikhet) om den byggs med billiga elektronikkomponenter vid konstruktion av en egen produkt eller med billiga PLC-komponenter. Erfarenheten från BAGA är att de egenutvecklade produkterna, konstruerade från elektronikkomponentnivå, är mer tillförlitliga än de byggda med PLC, och detta till ett lägre pris per enhet. 5.1 Framtida arbete För att överföra detta arbete till kommersiell produkt behövs anpassning till 24 Volt för digitala ingångar, någon slags anpassning för trycknivågivare då de vanligaste analoga givarna på den kommersiella marknaden är tvåtrådsgivare med en utsignal på 4-20 ma och något slags drivdon för pumpar på utgångarna, t.ex. med en optokopplare och triac. 13
6. Referenser 1. Grundkurs i Kemisk fällning 1, Bengt Hansen, Vattenspegeln nr 1/1997 utgiven av Kemira Kemwater AB 2. Grundkurs i Kemisk fällning 3, Bengt Hansen, Vattenspegeln nr 3/1997 utgiven av Kemira Kemwater AB 3. Naturvårdsverkets författningssamling NFS 2006:7, ISSN 1403-8234 4. SFS, förordning 1998:899 5. Arduino FAQ, http:// http://arduino.cc/en/main/faq, 2011-04-18 Övriga källor: Arduino Starter Kit Manual A Complete Beginners Guide to the Arduino, Mike McRoberts Earthshine Design, http://www.earthshinedesign.co.uk, 2011-04-18 Arduino Programming Notebook, Brian W Evans Fritzing www.frizing.org, 2011-04-18 14
7. Bilagor Bilaga 1: Principskiss, reningsverket Kompakt-40 från BAGA Water Technology AB Bilaga 2: Officiell specifikation för Arduino Mega Bilaga 3: Elschema för Arduino Mega referens design Bilaga 4:, Kopplingsbordsvy över demonstrationsplattform Bilaga 5: Elschema för demonstrationsplattform Bilaga 6: Programkod Bilaga 7: Foto på LCD&Keypad shield Bilaga 8: Elschema för LCD&Keypad shield 15
Bilaga 1 1
Bilaga 2 Arduino Mega Overview The Arduino Mega is a microcontroller board based on the ATmega1280 (datasheet). It has 54 digital input/output pins (of which 14 can be used as PWM outputs), 16 analog inputs, 4 UARTs (hardware serial ports), a 16 MHz crystal oscillator, a USB connection, a power jack, an ICSP header, and a reset button. It contains everything needed to support the microcontroller; simply connect it to a computer with a USB cable or power it with a AC-to-DC adapter or battery to get started. The Mega is compatible with most shields designed for the Arduino Duemilanove or Diecimila. Schematic & Reference Design EAGLE files: arduino-mega-reference-design.zip Schematic: arduino-mega-schematic.pdf 1
Summary Microcontroller ATmega1280 Operating Voltage 5V Input Voltage (recommended) 7-12V Input Voltage (limits) 6-20V Digital I/O Pins 54 (of which 14 provide PWM output) Analog Input Pins 16 DC Current per I/O Pin 40 ma DC Current for 3.3V Pin 50 ma Flash Memory 128 KB of which 4 KB used by bootloader SRAM 8 KB EEPROM 4 KB Clock Speed 16 MHz Power The Arduino Mega can be powered via the USB connection or with an external power supply. The power source is selected automatically. External (non-usb) power can come either from an AC-to-DC adapter (wall-wart) or battery. The adapter can be connected by plugging a 2.1mm center-positive plug into the board's power jack. Leads from a battery can be inserted in the Gnd and Vin pin headers of the POWER connector. The board can operate on an external supply of 6 to 20 volts. If supplied with less than 7V, however, the 5V pin may supply less than five volts and the board may be unstable. If using more than 12V, the voltage regulator may overheat and damage the board. The recommended range is 7 to 12 volts. 2
The power pins are as follows: VIN. The input voltage to the Arduino board when it's using an external power source (as opposed to 5 volts from the USB connection or other regulated power source). You can supply voltage through this pin, or, if supplying voltage via the power jack, access it through this pin. 5V. The regulated power supply used to power the microcontroller and other components on the board. This can come either from VIN via an on-board regulator, or be supplied by USB or another regulated 5V supply. 3V3. A 3.3 volt supply generated by the on-board FTDI chip. Maximum current draw is 50 ma. GND. Ground pins. Memory The ATmega1280 has 128 KB of flash memory for storing code (of which 4 KB is used for the bootloader), 8 KB of SRAM and 4 KB of EEPROM (which can be read and written with the EEPROM library). Input and Output Each of the 54 digital pins on the Mega can be used as an input or output, using pinmode(), digitalwrite(), anddigitalread() functions. They operate at 5 volts. Each pin can provide or receive a maximum of 40 ma and has an internal pull-up resistor (disconnected by default) of 20-50 kohms. In addition, some pins have specialized functions: Serial: 0 (RX) and 1 (TX); Serial 1: 19 (RX) and 18 (TX); Serial 2: 17 (RX) and 16 (TX); Serial 3: 15 (RX) and 14 (TX). Used to receive (RX) and transmit (TX) TTL serial data. Pins 0 and 1 are also connected to the corresponding pins of the FTDI USB-to-TTL Serial chip. External Interrupts: 2 (interrupt 0), 3 (interrupt 1), 18 (interrupt 5), 19 (interrupt 4), 20 (interrupt 3), and 21 (interrupt 2). These pins can be configured to trigger an interrupt on a low value, a rising or falling edge, or a change in value. See the attachinterrupt() function for details. PWM: 0 to 13. Provide 8-bit PWM output with the analogwrite() function. SPI: 50 (MISO), 51 (MOSI), 52 (SCK), 53 (SS). These pins support SPI communication, which, although provided by the underlying hardware, is not 3
currently included in the Arduino language. The SPI pins are also broken out on the ICSP header, which is physically compatible with the Duemilanove and Diecimila. LED: 13. There is a built-in LED connected to digital pin 13. When the pin is HIGH value, the LED is on, when the pin is LOW, it's off. I 2 C: 20 (SDA) and 21 (SCL). Support I 2 C (TWI) communication using the Wire library (documentation on the Wiring website). Note that these pins are not in the same location as the I 2 C pins on the Duemilanove or Diecimila. The Mega has 16 analog inputs, each of which provide 10 bits of resolution (i.e. 1024 different values). By default they measure from ground to 5 volts, though is it possible to change the upper end of their range using the AREF pin and analogreference() function. There are a couple of other pins on the board: AREF. Reference voltage for the analog inputs. Used with analogreference(). Reset. Bring this line LOW to reset the microcontroller. Typically used to add a reset button to shields which block the one on the board. Communication The Arduino Mega has a number of facilities for communicating with a computer, another Arduino, or other microcontrollers. The ATmega1280 provides four hardware UARTs for TTL (5V) serial communication. An FTDIFT232RL on the board channels one of these over USB and the FTDI drivers (included with the Arduino software) provide a virtual com port to software on the computer. The Arduino software includes a serial monitor which allows simple textual data to be sent to and from the Arduino board. The RX and TX LEDs on the board will flash when data is being transmitted via the FTDI chip and USB connection to the computer (but not for serial communication on pins 0 and 1). A SoftwareSerial library allows for serial communication on any of the Mega's digital pins. The ATmega1280 also supports I2C (TWI) and SPI communication. The Arduino software includes a Wire library to simplify use of the I2C bus; see the documentation on the Wiring website for details. To use the SPI communication, please see the ATmega1280 datasheet. 4
Programmi ng The Arduino Mega can be programmed with the Arduino software (download). For details, see the reference and tutorials. The ATmega1280 on the Arduino Mega comes preburned with a bootloader that allows you to upload new code to it without the use of an external hardware programmer. It communicates using the original STK500 protocol (reference, C header files). You can also bypass the bootloader and program the microcontroller through the ICSP (In-Circuit Serial Programming) header; see these instructions for details. Automatic (Soft ware) Reset Rather then requiring a physical press of the reset button before an upload, the Arduino Mega is designed in a way that allows it to be reset by software running on a connected computer. One of the hardware flow control lines (DTR) of theft232rl is connected to the reset line of the ATmega1280 via a 100 nanofarad capacitor. When this line is asserted (taken low), the reset line drops long enough to reset the chip. The Arduino software uses this capability to allow you to upload code by simply pressing the upload button in the Arduino environment. This means that the bootloader can have a shorter timeout, as the lowering of DTR can be wellcoordinated with the start of the upload. This setup has other implications. When the Mega is connected to either a computer running Mac OS X or Linux, it resets each time a connection is made to it from software (via USB). For the following half-second or so, the bootloader is running on the Mega. While it is programmed to ignore malformed data (i.e. anything besides an upload of new code), it will intercept the first few bytes of data sent to the board after a connection is opened. If a sketch running on the board receives one-time configuration or other data when it first starts, make sure that the software with which it communicates waits a second after opening the connection and before sending this data. The Mega contains a trace that can be cut to disable the auto-reset. The pads on either side of the trace can be soldered together to re-enable it. It's labeled "RESET- EN". You may also be able to disable the auto-reset by connecting a 110 ohm resistor from 5V to the reset line; see this forum thread for details. USB Overcurrent Protection The Arduino Mega has a resettable polyfuse that protects your computer's USB 5
ports from shorts and overcurrent. Although most computers provide their own internal protection, the fuse provides an extra layer of protection. If more than 500 ma is applied to the USB port, the fuse will automatically break the connection until the short or overload is removed. Physical Characteristics and Shield Compatibilit y The maximum length and width of the Mega PCB are 4 and 2.1 inches respectively, with the USB connector and power jack extending beyond the former dimension. Three screw holes allow the board to be attached to a surface or case. Note that the distance between digital pins 7 and 8 is 160 mil (0.16"), not an even multiple of the 100 mil spacing of the other pins. The Mega is designed to be compatible with most shields designed for the Diecimila or Duemilanove. Digital pins 0 to 13 (and the adjacent AREF and GND pins), analog inputs 0 to 5, the power header, and ICSP header are all in equivalent locations. Further the main UART (serial port) is located on the same pins (0 and 1), as are external interrupts 0 and 1 (pins 2 and 3 respectively). SPI is available through the ICSP header on both the Mega and Duemilanove / Diecimila.Please note that I 2 C is not located on the same pins on the Mega (20 and 21) as the Duemilanove / Diecimila (analog inputs 4 and 5). Photo of the Arduino Mega by SpikenzieLabs. 6
Bilaga 3 1
Bilaga 4 1
Bilaga 5 1
Bilaga 6 #include <EEPROM.h> //#include <LCD4Bit_mod.h> //LCD4Bit_mod lcd = LCD4Bit_mod(2); #include <LiquidCrystal.h> //displayinitiering // select the pins used on the LCD panel LiquidCrystal lcd(8, 9, 4, 5, 6, 7); /* Examensarbete kandidatnivå av Att ersätta en PLC med ett Arduino Mega och "lite" kringutrustning. */ //VARIABLER FÖR RENINGSVERKET IN OCH UT //RESERVOAR //UT int P1_Res int P2_Res = 22 ; // pinnummer för Matarpump 1 i reservoar = 24 ; // Matarpump 2 i reservoar //IN 1
int NG_Res_Start = 23 ; //Nivågivare i reservoar, startnivå int NG_Res_Larm = 25 ; //Nivågivare i reservoar, larmnivå int pumpgang = 0; //Variabel för växlande gång av pumparna i reservoaren //SLAMAVSKILJARE //UT int P1_SA int SP_SA = 26 ; // Matarpump 1 i slamavskiljare till bioreaktor = 28 ; // SlamPump i SlamAvskiljare //IN int TNG_SA = 10 ; //Trycknivågivare i slamavskiljare //BIOREAKTOR(ER) //UT int SP_BR1 = 30; // SlamPump i Bioreaktor 1 int SKF_BR1 = 32; // Sidkanalfläkt i biorektor 1 //IN int TG_SKF_BR1_OK = 33; // tryckgivare sidkanalfläkt BR1 //POLERSTEG //UT int P1_PS int SP_PS = 34 ; // Matarpump 1 i polersteg = 36 ; // SlamPump i PolerSteg int Recirk_PS = 38 ; // Magnetventilstyrning för att recirkulera vatten för omrörning vid efterfällning //IN int NG1_PS int NG2_PS = 35 ; // Nedre nigågivare i polersteg = 37 ; // Övre nigågivare i polersteg 2
int NG3_PS = 39 ; // Högnivålarm i polersteg //KEMDOSERING //UT int DP_FF int DP_EF polersteg = 40 ; // Doserpump förfällning i slamavskiljare = 42 ; // Doserpump simultanfällning i bioreaktor/efterfällning i //IN int NG_Flock_ln = 41 ; // Nivågivare i flockningsmedelskärl // Variabel för att specificera var i reningscykeln programmet är unsigned int state; // Variabler för cykelräknaren int a = 1; int b = 2; int c = 3; int d = 4; int A; int B; int C; int D; int antalcykler; EEPROM. // adress för skrivning av EEPROM // adress för skrivning av EEPROM // adress för skrivning av EEPROM // adress för skrivning av EEPROM // Värdet på adress a i EEPROM // Värdet på adress b i EEPROM // Värdet på adress c i EEPROM // Värdet på adress d i EEPROM // Antal körda cykler sedan start eller senaste överskrivning av // Variabler för tider unsigned long T_cykelstart ; //Tidpunkt för cykelstart i ms 3
unsigned long T_statestart; unsigned long T_SA_uppf; unsigned long T_bubbelstart; unsigned long T_bubbel = 180000; Ska initieras unsigned long T_slamsed = 30000; Ska initieras //Tidpunkt för state-start //Tidpunkt då SA åter är uppfylld. //Tidpunkt då sidkanalfläktar startar. //Tid för bubbel vid rening i ms. //Tid för slamsedimentering i BR i ms. unsigned long T_bubbel_vila = 10000; Ska initieras //Tid för bubbling vid vila i ms. unsigned long T_icke_bubbel_vila = 10000; //Tid för icke bubbling vid vila i ms. Ska initieras unsigned long T_sp_SA = 30000; Ska initieras unsigned long Tmax_sp_BR = 30000; i ms. Ska initieras unsigned long Tmax_sp_PS = 30000; ms. Ska initieras unsigned long T_PS_inblandning = 30000; polersteget //Gångtid för slampump i SA //Maxtid för slampumpning från br till SA //Maxtid för slampumpning från ps till SA i //Tid för inblandning av flockningsmedel i unsigned long Tmax_PS_utpumpning = 30000; recipient i ms. Ska initieras unsigned long Tmax_SP_PS = 30000; i ms. Ska initieras //Maxtid för utpumpning från PS till //Maxtid för slampumpning från PS till SA unsigned long T_DP_FF = 10000; flockningsmedel vid förfällning unsigned long T_DP_EF = 10000; flockningsmedel vid efterfällning unsigned long T_PS_sedimentering = 30000; //Gångtid för doserpump för //Gångtid för doserpump för //Tid för sedimentering i polersteget // Variabler för trycknivågivaren int tng_sa; int tng_statestart; int tng_sa_cykelstart; //Aktuellt trycknivågivarvärde i SA //Trycknivågivarens värde i SA vid start av state. //Trycknivågivarens värde i SA vid start av cykel. 4
int tng_sa_normal = 900; inpumpning från Res Ska initieras. int tng_sa_br = 100; (vatten) Ska initieras int tng_sp_br_sa = 20; Ska initieras //int tng_sp_sa_ss = 20; Ska initieras //Trycknivågivarens värde i SA efter avklarade //Tryckskillnad som pumpas till BR från SA //Tryckskillnad som pumpas till SA från BR. (slam) //Tryckskillnad som pumpas från sa till ss. //variabler för display med 5 tangenter + reset int adc_key_val[5] =30, 150, 360, 535, 760 ; int NUM_KEYS = 5; int adc_key_in; int key=-1; int oldkey=-1; void setup() // initiering av seriell kommunikation till GUI Serial.begin(1200); //initiering av state till vila/puff state = 0; Serial.print(state); Serial.print("\t"); Serial.println(tng_sa); T_cykelstart = millis(); T_statestart = millis(); 5
// initiering av display // lcd.init(); lcd.begin(16, 2); // start the library lcd.clear(); lcd.setcursor(0, 0); //line=1, x=0 lcd.print("baga RVBKomp T"); lcd.setcursor(0,1); //line=2, x=0 lcd.print("vilar "); // Skriv i LCD lcd.setcursor(15,0); //line=2, x=15 lcd.print("0"); // run once för cykelräknaren if (EEPROM.read(d) == 255) EEPROM.write(a,0); EEPROM.write(b,0); EEPROM.write(c,0); EEPROM.write(d,0); // initiering av cykelräknaren efter reset eller strömavbrott A=EEPROM.read(a); B=EEPROM.read(b); C=EEPROM.read(c); D=EEPROM.read(d); antalcykler = A + (B*256) + (C*256*256) + (D*256*256*256); //Reservoar 6
pinmode(p1_res, OUTPUT); pinmode(p2_res, OUTPUT); pinmode(ng_res_start, INPUT); pinmode(ng_res_larm, INPUT); //SLAMAVSKILJARE pinmode(sp_sa, OUTPUT); pinmode(p1_sa, OUTPUT); pinmode(tng_sa, INPUT); //BIOREKTOR1 pinmode(sp_br1, OUTPUT); pinmode(skf_br1, OUTPUT); pinmode(tg_skf_br1_ok, INPUT); //POLERSTEG pinmode(sp_ps, OUTPUT); pinmode(p1_ps, OUTPUT); pinmode(ng1_ps, INPUT); pinmode(ng2_ps, INPUT); pinmode(ng3_ps, INPUT); pinmode(recirk_ps, OUTPUT); //KEMDOSERING pinmode(dp_ff, OUTPUT); pinmode(dp_ef, OUTPUT); pinmode(ng_flock_ln, INPUT); 7
//Här under definieras funktioner som anropas i loop() void antalcyklerplusplus() A = A + 1; if (A == 255) A = 0; B=B+1; if (B == 255) B = 0; C=C+1; if (C == 255) C = 0; D=D+1; if (D == 255) D = 0; antalcykler = antalcykler + 1; 8
EEPROM.write(a,A); EEPROM.write(b,B); EEPROM.write(c,C); EEPROM.write(d,D); Serial.println("antalcyklerplusplus körd"); void loop() tng_sa = analogread(tng_sa); // Vattennivån i SA läses av Serial.print("state "); Serial.print(state); Serial.print("\t"); Serial.println(tng_sa); int sa_fill = int(float(float(tng_sa) / float(1024) * float(100))); Serial.print(tng_sa); Serial.print("\t"); Serial.print(sa_fill); Serial.print("\t"); lcd.setcursor(14, 1); //line=2, x=14 lcd.print(" "); lcd.setcursor(14, 1); //line=2, x=14 lcd.print(sa_fill,dec); if(state == 0) // *************Vila************* 9
Serial.print("state "); Serial.print(state); Serial.print("\t"); Serial.println(tng_sa); if((digitalread(ng_res_start) == HIGH) && (tng_sa < tng_sa_normal)) // lcd.clear(); lcd.setcursor(0,1); //line=2, x=0 lcd.print("fyller SA "); // Skriv till LCD lcd.setcursor(15,0); //line=2, x=15 lcd.print("1"); T_statestart = millis(); // Sätter starttid för state 1 state = 1; // Går vidare till state 1 (uppfyllning av SA) if((digitalread(ng_res_start) == HIGH) && (tng_sa >= tng_sa_normal)) digitalwrite(skf_br1,high); T_bubbelstart = millis(); // Start av sidkanalfläktar // Tidpunkt då sidkanalfläktar startar. // lcd.clear(); lcd.setcursor(0,1); //line=2, x=0 lcd.print("fyller BR "); // Skriv till LCD lcd.setcursor(15,0); //line=2, x=15 lcd.print("2"); antalcyklerplusplus(); // Uppdatera cykelräknaren tng_statestart = tng_sa; // Sätter startnivån för state 2 tng_sa_cykelstart = tng_sa; // Sätter startnivån för reningscykeln 10
digitalwrite(p1_sa,high); digitalwrite(skf_br1,high); bioreaktor // Startar P1 i SA för att fylla upp BR // Startar sidkanalfläkten för syresättning av T_cykelstart = millis(); // Sätter starttid för ny cykel T_statestart = millis(); // Sätter starttid för state 2 state = 2; rening) // Går vidare till state 2 (uppfyllning av BR och start av if(digitalread(ng_res_start) == LOW) //Inget vatten i RES if((millis() - T_statestart <= T_bubbel_vila) ) // Ska det (fortfarande) bubbla digitalwrite(skf_br1,high); // Starta sidkanalfläktar if(((millis() - T_statestart >= T_bubbel_vila) ) && ((millis() - T_bubbel_vila - T_icke_bubbel_vila) <= T_statestart ) ) // Ska det sluta bubbla? digitalwrite(skf_br1,low); // Stänger av sidkanalfläktar if( ( (millis() - T_bubbel_vila - T_icke_bubbel_vila) >= T_statestart ) ) // Dags at starta om vilocykeln? T_statestart = millis(); om en vilocykel. // Sätter ny starttid för state 0 (vila), dvs startar if(state == 1) //Uppfyllning av SA om dess nivå är under normal och där efter återgång till state 0 (vila) eller vidare till state 2 (rening) 11
// *** Denna state tar hand om de tillfällen då inte SA är uppfylld. Tex vid första start av RV Serial.print("state "); Serial.print(state); Serial.print("\t"); Serial.println(tng_sa); if((tng_sa < tng_sa_normal) && (digitalread(ng_res_start) == HIGH)) // if ((pumpgang % 2) == 0) //växlande gång digitalwrite(p1_res,high); if ((pumpgang % 2) == 1) //växlande gång digitalwrite(p2_res,high); digitalwrite(dp_ff,high); förfällning // Slår på doserpump för if((tng_sa > tng_sa_normal) && (digitalread(ng_res_start) == HIGH)) // Är SA uppfylld? digitalwrite(p1_res,low); // Stäng av pumpar i reservoar digitalwrite(p2_res,low); digitalwrite(dp_ff,low); //lcd.clear(); lcd.setcursor(0,1); //line=2, x=0 lcd.print("fyller BR "); // Skriv till LCD lcd.setcursor(15,0); //line=2, x=15 lcd.print("2"); 12
antalcyklerplusplus(); // Uppdatera cykelräknaren tng_statestart = tng_sa; // Sätter startnivån för state 2 digitalwrite(p1_sa,high); BR digitalwrite(skf_br1,high); syresättning av bioreaktor T_bubbelstart = millis(); tng_sa_cykelstart = tng_sa; reningscykeln pumpgang = pumpgang +1; pumpgang T_cykelstart = millis(); // Startar P1 i SA för att fylla upp // Startar sidkanalfläkten för // Tidpunkt då sidkanalfläktar startar. // Sätter startnivån för // Uppdatera pumpräknaren // Sätter starttid för ny cykel T_statestart = millis(); // Sätter starttid för state 2 state = 2; och start av rening) // Går vidare till state 2 (uppfyllning av BR if((digitalread(ng_res_start) == LOW)) startnivå i RES // Om nivån sjunker under digitalwrite(p1_res,low); // Stäng av pumpar i reservoar digitalwrite(p2_res,low); digitalwrite(dp_ff,low); förfällning // Stäng av doserpump för //lcd.clear(); lcd.setcursor(0,1); //line=2, x=0 lcd.print("vilar "); // Skriv i LCD lcd.setcursor(15,0); //line=2, x=15 lcd.print("0"); pumpgang = pumpgang +1; pumpgang // Uppdatera pumpräknaren 13
T_statestart = millis(); // Sätter starttid för state 0 Serial.print("state "); Serial.print(state); Serial.print("\t"); Serial.println(tng_sa); state = 0; // Går tillbaka till state 0 (vila) if(state == 2) //uppfyllning av BR och start av rening Serial.print("state "); Serial.print(state); Serial.print("\t"); Serial.println(tng_sa); if(tng_statestart - tng_sa_br > tng_sa) // Om uppfyllning av BR är klar digitalwrite(p1_sa,low); fyllt upp BR // Stannar P1 i SA efter att ha if(digitalread(ng_res_start) == HIGH) Res om det finns vatten i Res // Återfyllning av SA från //lcd.clear(); lcd.setcursor(0,1); //line=2, x=0 lcd.print("aterfyll SA "); // Skriv till LCD lcd.setcursor(15,0); //line=2, x=15 lcd.print("3"); 14
if ((pumpgang % 2) == 0) // växlande gång digitalwrite(p1_res,high); if ((pumpgang % 2) == 1) // växlande gång digitalwrite(p2_res,high); digitalwrite(dp_ff,high); förfällning digitalwrite(skf_br1,high); syresättning av bioreaktor (om den skulle ha stannat...) digitalwrite(recirk_ps,high); och inblandning av flockningsmedel i polersteg) digitalwrite(p1_ps,high); polersteget digitalwrite(dp_ef,high); polersteget pumpgang = pumpgang +1; pumpgang // Slår på doserpump för // Startar sidkanalfläkten för // kopplar om för recirkulation // Startar matarpumpen i // Startar doserpumpen i // Uppdatera pumpräknaren T_statestart = millis(); // Sätter starttid för state 3 state = 3; // Går vidare till state 3 else if((digitalread(ng_res_start) == LOW)) //lcd.clear(); lcd.setcursor(0,1); //line=2, x=0 lcd.print("renar "); // Skriv till LCD lcd.setcursor(15,0); //line=2, x=15 lcd.print("3"); digitalwrite(skf_br1,high); syresättning av bioreaktor (om den skulle ha stannat...) digitalwrite(recirk_ps,high); och inblandning av flockningsmedel i polersteg) digitalwrite(p1_ps,high); // Startar sidkanalfläkten för // kopplar om för recirkulation // Startar matarpumpen i 15
polersteget digitalwrite(dp_ef,high); polersteget // Startar doserpumpen i T_statestart = millis(); // Sätter starttid för state 3 state = 3; // Går vidare till state 3 if(state == 3) //återuppfyllning av SA med ff, dosering och omrörning i polersteg samt fortsatt rening i bioreaktor Serial.print("state "); Serial.print(state); Serial.print("\t"); Serial.println(tng_sa); if(millis() - (T_DP_FF > T_statestart)) digitalwrite(dp_ff,low); förfällning // Slår av doserpump för if(tng_sa > tng_sa_normal digitalread(ng_res_start) == LOW) T_SA_uppf=millis(); digitalwrite(p1_res,low); reservoaren // Stänger av pumparna i digitalwrite(p2_res,low); 16
if(millis() - T_DP_EF > T_statestart) digitalwrite(dp_ef,low); efterfällning // Slår av doserpump för if(millis() - T_PS_inblandning > T_statestart) digitalwrite(recirk_ps,low); efterfällning och sedimenterar slam // Slår av omrörning för if(millis() - T_PS_inblandning - T_PS_sedimentering > T_statestart && (tng_sa > tng_sa_normal digitalread(ng_res_start) == LOW)) //lcd.clear(); lcd.setcursor(0,1); //line=2, x=0 lcd.print("tommer PS "); // Skriv till LCD lcd.setcursor(15,0); //line=2, x=15 lcd.print("4"); digitalwrite(p1_ps,high); polersteget digitalwrite(p1_res,low); reservoaren // Startar matarpumpen i // Stänger av pumparna i digitalwrite(p2_res,low); T_statestart = millis(); // Sätter starttid för state 4 state = 4; // Går vidare till state 4 if(state == 4) // Utpumpning av fällt sedimenterat vatten till recipient 17
Serial.print("state "); Serial.print(state); Serial.print("\t"); Serial.println(tng_sa); if( (millis() > (T_statestart + Tmax_PS_utpumpning)) (digitalread(ng2_ps)==low)) //lcd.clear(); lcd.setcursor(0,1); //line=2, x=0 lcd.print("slamp. PS+SA"); // Skriv till LCD lcd.setcursor(15,0); //line=2, x=15 lcd.print("5"); digitalwrite(p1_ps,low); polersteget digitalwrite(sp_sa,high); digitalwrite(sp_ps,high); // Stänger av matarpumpen i // Startar slampumpen i SA // Startar slampumpen i PS T_statestart = millis(); // Sätter starttid för state 5 state = 5; // Går vidare till state 5 if(state == 5) Serial.print("state "); Serial.print(state); Serial.print("\t"); Serial.println(tng_sa); 18
if(digitalread(ng1_ps) == LOW (millis() > T_statestart + Tmax_SP_PS)) digitalwrite(sp_ps,low); // Stänger av slampumpen i PS if(millis() > T_statestart + T_sp_SA ) digitalwrite(sp_sa,low); // Stänger av slampumpen i SA if(millis() > T_bubbelstart + T_bubbel) digitalwrite(skf_br1,low); bioreaktorn // Stänger av sidkanalfläkten i if ( (digitalread(ng1_ps) == LOW (millis() > T_statestart + Tmax_sp_PS)) && (millis() > T_statestart + T_sp_SA) && (millis() > T_bubbelstart + T_bubbel) ) // Om alla tre if-satser ovan är uppfyllda //lcd.clear(); lcd.setcursor(0,1); //line=2, x=0 lcd.print("slamsed. BR "); // Skriv till LCD lcd.setcursor(15,0); //line=2, x=15 lcd.print("6"); T_statestart = millis(); // Sätter starttid för state 6 state = 6; // Går vidare till state 6 19
if(state == 6) Serial.print("state "); Serial.print(state); Serial.print("\t"); Serial.println(tng_sa); if(millis() > T_statestart + T_slamsed ) //lcd.clear(); lcd.setcursor(0,1); //line=2, x=0 lcd.print("slampump BR "); // Skriv till LCD lcd.setcursor(15,0); //line=2, x=15 lcd.print("7"); tng_statestart = tng_sa; digitalwrite(sp_br1,high); slampumpning till SA // Startar slampumpen i BR för T_statestart = millis(); // Sätter starttid för state 7 Serial.print(state); Serial.print("\t"); Serial.println(tng_sa); state = 7; // Går vidare till state 7 if(state == 7) Serial.print("state "); 20
Serial.print(state); Serial.print("\t"); Serial.println(tng_sa); if ( millis() > T_statestart + Tmax_sp_BR tng_sa > (tng_statestart + tng_sp_br_sa )) digitalwrite(sp_br1,low); för slampumpning till SA // Stänger av slampumpen i BR T_statestart = millis(); // Sätter starttid för state 0 //lcd.clear(); lcd.setcursor(0,1); //line=2, x=0 lcd.print("rening klar "); // Skriv till LCD lcd.setcursor(15,0); //line=2, x=15 lcd.print("0"); state = 0; // Går vidare till state 0 21
Bilaga 7 1
Bilaga 8 1