Mål
Ett automatiserat odlingssystem för växter där plantorna vattnas automatiskt. Plantorna skall dessutom inte odlas i jord utan med hydrokultur i ett så kallat "Ebb and Flow" system. Detta för att öka produktionen och kvalitén på plantorna. Plantorna kommer ges artificiellt ljus av en 180 watt LED-lampa med 10 spektrum i det röda och blå området. Hydrokultur
Hydrokultur, eller hydroponic som det heter på engelska, är en teknik som utvecklades bland annat av NASA för att odla växter på rymdstationer med högre effektivitet ur både plats, tid och vattenåtgångssynpunkt. Det finns i princip tre olika sätt att odla utan jord: hydroponics, aquaponics och aeroponics. I det förstnämnda befinner sig växterna under vatten (eller rättare sagt näringslösning) en del av tiden och i luft en del av tiden, i det sist nämnda hänger växternas rötter i en vattendimma eller i ett vattensprej. Aquaponics är samma som hydroponics fast istället för näringslösning använder man en tank/damm med fiskar och får på så sätt ett eget kretslopp.
Sedan finns det olika underkategorier till hydroponics tex "Deep Water Culture" och "Ebb and Flow". I DWC (Deep Water Culture) hänger rötterna konstant ner i näringslösningen och luftpumpar används för att tillsätta luft till rötterna via bubbling. Ebb and Flow som jag kommer bygga denna gången går ut på att man översvämmar växterna regelbundet och sedan låter dem torka en stund innan man upprepar. I mitt fall kommer jag köra 13 minuter under vatten och 7 minuter torka för att sedan upprepa processen. Detta upprepas hela dagen men stängs av innan det blir mörkt.
Växtmedium
Att man inte kan använda jord är lätt att förstå då rötterna inte skulle ha tid att torka ut utan ruttna. Därför finns det olika material som man kan använda. Växtmediet är dött och används bara för att hålla plantan på plats, inte för att ge näring eller dyl som jord gör. Vanliga medium är sten, lekakulor eller stenull.
Vid odling i jord vill jag minnas att jag sett siffror på att rötterna får runt 20% luft. Med hjälp av jord uppblandad med perlit eller kokosfibrer kan man komma upp i 30%. Hydroponics ger cirka 80% medan aeroponics ger 99% eller mer. Mer luft ger snabbare tillväxt och friskare plantor. Med hydroponics kan man räkna med åtminstone dubbla tillväxthastigheten som med jord. Aeroponics kan vara cirka 30% snabbare än hydroponics.
Tillvägagångssätt
Här är en film på hur jag byggde mitt system.
https://www.youtube.com/watch?v=A_E90ihuPwo Elektroniken som används är en PIC12F629 som timerstyrning. Genom en knapptryckning kan man välja tre olika intervaller, vattningsperioden 20 minuter, 60 minuter eller 180 minuter. Här är koden som jag programmerade PIC;en med.
Kod: Markera allt
/*
* Author: Daniel Andersson, DA-Robotteknik
*
* Connect:
* Water pump to GP0
* LED to GP1
* Switch to GP2 (active low)
*
* Created on den 4 januari 2015, 12:50
*/
#include <xc.h>
// CONFIG
#pragma config FOSC = INTRCIO // Oscillator Selection bits (INTOSC oscillator: I/O function on GP4/OSC2/CLKOUT pin, I/O function on GP5/OSC1/CLKIN)
#pragma config WDTE = OFF // Watchdog Timer Enable bit (WDT disabled)
#pragma config PWRTE = OFF // Power-Up Timer Enable bit (PWRT disabled)
#pragma config MCLRE = ON // GP3/MCLR pin function select (GP3/MCLR pin function is MCLR)
#pragma config BOREN = OFF // Brown-out Detect Enable bit (BOD disabled)
#pragma config CP = OFF // Code Protection bit (Program Memory code protection is disabled)
#pragma config CPD = OFF // Data Code Protection bit (Data memory code protection is disabled
#define _XTAL_FREQ 4000000 // 4MHz clock (used for delays)
#define __delay_ms(x) _delay((unsigned long)((x)*(_XTAL_FREQ/4000.0)))
#define __delay_us(x) _delay((unsigned long)((x)*(_XTAL_FREQ/4000000.0)))
#define TIME_1ms (_XTAL_FREQ/4000.0)
// Define pinnumbers
#define sw GP2
#define pump GP0
#define led GP1
// Define timeconstants
#define TCYCLE_SHORT 1200 // 20 minutes
#define TCYCLE_MEDIUM 3600 // 1 hour
#define TCYCLE_LONG 20800 // 3 hours
#define TIME_ON 600 // 10 minutes
#define SW_PRESS 0 // Switch active low
unsigned int wateringPeriod; // How many seconds between watering? (24-bit)
unsigned int onTime; // How many seconds should each watering cycle be active?
unsigned int halfSeconds; // 24-bit to store elapsed time since last watering
// Check adress 0 in EEPROM, if set to 123 a time intervall should have been saved on adress 2
unsigned char tCycleIsSaved(){
EEADR = 0x00;
EECON1 |= 0b00000001; // Sett RD to start read
return (EEDATA == 123);
}
// Read the value last saved on adres 1 in EEPOROM
unsigned int tCycleRead(){
unsigned char value;
EEADR = 0x01;
RD = 1; // Sett RD to start read
value = EEDATA;
if (value == 0)
return TCYCLE_SHORT;
else if (value == 1)
return TCYCLE_MEDIUM;
else if (value == 2)
return TCYCLE_LONG;
else
return TCYCLE_MEDIUM;
}
// Save an value in adres 1 in EEPROM and set adr 0 to 123
void tCycleSave(unsigned int value){
// Write the value
EEADR = 0x01;
if (value == TCYCLE_SHORT)
EEDATA = 0;
else if (value == TCYCLE_MEDIUM)
EEDATA = 1;
else if (value == TCYCLE_LONG)
EEDATA = 2;
else
EEDATA = 1;
//EEIF = 0;
WREN = 1; // Write enable
GIE = 0; // Disable interrupts during write..
EECON2 = 0x55; // Required sequence. Se datasheet.
EECON2 = 0xAA; // Required sequence. Se datasheet.
WR = 1;
__delay_ms(10);
//EEIF = 0;
// Write the checkvalue to adres 0
EEADR = 0x00;
EEDATA = 123;
EECON2 = 0x55; // Required sequence. Se datasheet.
EECON2 = 0xAA; // Required sequence. Se datasheet.
WR = 1;
__delay_ms(10);
//EEIF = 0;
// Re enable interrupts
GIE = 1;
WREN = 0; // Write disable
}
// Blink LED X number of times
void blinkLed(unsigned char x){
while(x > 0){
x --;
led = 1;
__delay_ms(500);
led = 0;
__delay_ms(500);
}
}
// Switch pressed.
// Change the time delay between watering
void swPressed(){
switch (wateringPeriod){
case TCYCLE_SHORT:
wateringPeriod = TCYCLE_MEDIUM;
tCycleSave(TCYCLE_MEDIUM); // Save to EEPROM
blinkLed(2);
break;
case TCYCLE_MEDIUM:
wateringPeriod = TCYCLE_LONG;
tCycleSave(TCYCLE_LONG); // Save to EEPROM
blinkLed(3);
break;
case TCYCLE_LONG:
wateringPeriod = TCYCLE_SHORT;
tCycleSave(TCYCLE_SHORT); // Save to EEPROM
blinkLed(1);
break;
}
}
// Main function...
void main(){
//init GPIO pins
TRISIO = 0b00001100; // Switch and MCLRE as input
CMCON = 0b00000111; // Disable comparator
GPIO = 0b00000000; // Set all GPIO pins low
onTime = TIME_ON; // in seconds
// Check if eeprom contains info about intervall time
if (tCycleIsSaved()){
wateringPeriod = tCycleRead(); // Get last saved time from eeprom
led = 1;
__delay_ms(2000);
led = 0;
}
else {
tCycleSave(TCYCLE_MEDIUM); // First time controller is started after programming
wateringPeriod = TCYCLE_MEDIUM;
blinkLed(10);
}
halfSeconds = (wateringPeriod-onTime)*2; //Start the first cycle 10 seconds after startup
// Enable global and peripheral interrupts to use timers..
GIE = 1;
PEIE = 1;
// Set up timer 0 (used for delay between watering)
TMR1GE = 0; // Don't use the gate input
T1CKPS1 = 1; // 1:8 prescale
T1CKPS0 = 1;
T1OSCEN = 0; // No external osc
TMR1CS = 0; // Use Fosc/4
TMR1H = 11; // Preload with 3036 (11 and 220) to get Tint = 0.5s
TMR1L = 220;
TMR1ON = 1;
TMR1IE = 1;
while(1){
if(sw == SW_PRESS) // Look for switch press
swPressed();
}
}
void interrupt tc_int(void){ // interrupt function
// Timer 1 used for watering period
// Interrupts every half second and increase the half-seconds counter variable
if(TMR1IF && TMR1IE)
{
TMR1H = 11; // Preload with 3036 (11 and 220) to get Tint = 0.5s
TMR1L = 220;
halfSeconds ++;
if(halfSeconds > 2*(wateringPeriod - onTime)){ // Delay passed, start pump
pump = 1; // Watering cycle started
if (halfSeconds > 2*wateringPeriod){ // Watering cycle ended
halfSeconds = 0; // Clear time counter
}
} else {
pump = 0; // Turn of pump
}
TMR1IF = 0; // clear the interrupt flag
}
}
/ Daniel