Ich hatte im Wintergarten immer das Problem, dass je nach Sonneneinstrahlung, und der damit verbundenen Erwärmung, der Abstand zwischen dem Bewässern der Pflanzen sehr stark schwankte. Also sollten die Pflänzchen sich am Besten selbst melden, wenn sie durstig sind.

Umgesetzt wurde das Projekt mit einem MEGA-328P Microprozessor, welcher 8 Analoge Eingänge zur Verfügung stellt. Als Sensoren dienen Fühler der Firma Seeedstudio ( -> Link ). Die Datenübermittlung an den Hausserver erfolgt mittels eines XBee-Moduls. Am Hausserver läuft ein kleines Java Programm, welches die Daten des XBee Moduls empfängt und in eine MySQL-Datenbank überträgt. Aus dieser Datenbank werden die Werte ausgelesen, ausgewertet und Visualisiert. Auf meinem Hausserver läuft alle 10 Minuten ein Programm welches diese Auswertung erledigt und im Fall von Trockenheit eine SMS, sowie eine Email an mich versendet.

Ein Problem, welches mit den Fühlern auftrat ist, dass das Kupfer auf diesen nach ca. 3-4 Wochen auf der Plus-Pol-Seite wegoxidiert sind. Eine Möglichkeit wäre die Kontakte zu vergolden. Ich habe jetzt allerdings testweise in den Plus-Pol einen Niro-Schrauben eingebaut (Bild), der als Messsonde dienen soll. Es wird sich zeigen, ob dieser seine Funktion länger erfüllen kann.

Interessant war, zu beobachten, dass die Substratfeuchte bei Erwärmung (Sonneneinstrahlung) deutlich zu steigen begann und am Abend wieder abklingt. Dies ergibt über die Zeitspanne von mehreren Tagen eine wellenförmige Abwärtsbewegung in der Grafik. Umso stärker die Erwärmung, desto ausgeprägter dieser Effekt, den ich auf die Oberflächenverdunstung zurückführe.

Programmcode für Arduino:

Programmcode anzeigen

byte DEBUG = 0;
 
int i;
 
// Includes und defines für Sleep-Modus
#include <avr /sleep.h>
#include </avr><avr /wdt.h>
 
#ifndef cbi
#define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))
#endif
#ifndef sbi
#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))
#endif
 
// Globale Variable Sleep Modus
volatile boolean f_wdt=1;
int sleepcount;
 
const byte XBee_Sleep_Pin = 2;  // Sleep Pin für Powersavemode XBee
 
void setup() {
 
  Serial.begin(9600); 
  Setup_Sleep();
 
  pinMode(13, OUTPUT);  
  pinMode(XBee_Sleep_Pin, OUTPUT);
 
  digitalWrite(XBee_Sleep_Pin, LOW);  // XBee aus Schlafmodus wecken  
 
  for (i=0;i&lt;10;i++) {          // Warteschleife, damit sich XBee verbinden kann
    digitalWrite(13, HIGH);   // set the LED on
    delay(50);              // wait for a second
    digitalWrite(13, LOW);    // set the LED off
    delay(50);              // wait for a second
  }
 
  //delay(15000);             // 5 Sekunden warten, bis XBee sicher da ist
}
 
 
 
 
void loop() {
 
  digitalWrite(XBee_Sleep_Pin, HIGH);  // XBee aus Schlafmodus wecken  -> Transistormodus, mit Widerständen LOW
 
  digitalWrite(13, HIGH);             // set the LED on  
  delay (18000);
 
  SendData("A0",A0);        // Fikus klein
  SendData("A1",A1);        // Bonsai
  SendData("A2",A2);        // Fikus groß
  SendData("A3",A3);        // Chilli
  SendData("A4",A4);        // Banane
 
 
  Serial.print("VCC=");
  Serial.print(readInternVcc());
  Serial.print(";EOL"); 
 
  delay (500);  
  digitalWrite(13, LOW);    // set the LED off  
  digitalWrite(XBee_Sleep_Pin, LOW);
 
  // Go to sleep
sleeploop_start:
  if (f_wdt==1) {  // wait for timed out watchdog / flag is set when a watchdog timeout occurs
    f_wdt=0;       // reset flag
    sleepcount++;
  }  
  if (DEBUG) { 
    Serial.print("Sleeping,"); 
    delay(10); 
  }
  system_sleep();
  if (DEBUG) Serial.println ("Wake Up");
  if (sleepcount < (300/8) ) goto sleeploop_start;  // Solange Zeit noch nicht abgelaufen nicht weiterspringen, sondern weiterschlafen -> Powersafe 300 = 5 Min
  sleepcount=0;  
  if (DEBUG) Serial.println("Nächste Messung...");  
 
}
 
void SendData(char *Bezeichnung, uint8_t Port) {
  long sensorValue = 0;
 
  int loops = 5;
  // read the value from the sensor:
  for (i=0;i<loops ;i++) {
    sensorValue += analogRead(Port);
    //delay(2);      // ADC beruhigen lassen-
  }
  sensorValue = round(sensorValue/loops);
 
 
  Serial.print(Bezeichnung);                       
  Serial.print("=");
  Serial.print(sensorValue);  
  Serial.print(";"); 
 
}
 
 
 
/************************************ Setup_SLEEP *********************************************************************/
void Setup_Sleep()
{
  // CPU Sleep Modes 
  // SM2 SM1 SM0 Sleep Mode
  // 0    0  0 Idle
  // 0    0  1 ADC Noise Reduction
  // 0    1  0 Power-down
  // 0    1  1 Power-save
  // 1    0  0 Reserved
  // 1    0  1 Reserved
  // 1    1  0 Standby(1)
 
  cbi( SMCR,SE );      // sleep enable, power down mode
  cbi( SMCR,SM0 );     // power down mode
  sbi( SMCR,SM1 );     // power down mode
  cbi( SMCR,SM2 );     // power down mode
 
  setup_watchdog(9);	// 9 = 8 sek. schlafen
} 
 
//****************************************************************  
// set system into the sleep state 
// system wakes up when wtchdog is timed out
void system_sleep() {
 
  cbi(ADCSRA,ADEN);                    // switch Analog to Digitalconverter OFF
 
  set_sleep_mode(SLEEP_MODE_PWR_DOWN); // sleep mode is set here
  sleep_enable();
 
  sleep_mode();                        // System sleeps here
 
    sleep_disable();                     // System continues execution here when watchdog timed out 
  sbi(ADCSRA,ADEN);                    // switch Analog to Digitalconverter ON
 
}
 
//****************************************************************
// 0=16ms, 1=32ms,2=64ms,3=128ms,4=250ms,5=500ms
// 6=1 sec,7=2 sec, 8=4 sec, 9= 8sec
void setup_watchdog(int ii) {
 
  byte bb;
  int ww;
  if (ii > 9 ) ii=9;
  bb=ii & 7;
  if (ii > 7) bb|= (1< &lt;5);
  bb|= (1<<WDCE);
  ww=bb;
  //Serial.println(ww);
 
 
  MCUSR &= ~(1<<WDRF);
  // start timed sequence
  WDTCSR |= (1<<WDCE) | (1<<WDE);
  // set new watchdog timeout value
  WDTCSR = bb;
  WDTCSR |= _BV(WDIE);
}
 
 
//****************************************************************  
// Watchdog Interrupt Service / is executed when  watchdog timed out
ISR(WDT_vect) {
  f_wdt=1;  // set global flag
}
 
 
 
 
 
// Liefert Spannung in Millivolts retour, 5000 = 5V, 3300 = 3.3V
// http://code.google.com/p/tinkerit/wiki/SecretVoltmeter
 
long readInternVcc() {
  long result;
  // Read 1.1V reference against AVcc
  ADMUX = _BV(REFS0) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1);
  delay(2); // Wait for Vref to settle
  ADCSRA |= _BV(ADSC); // Convert
  while (bit_is_set(ADCSRA,ADSC));
  result = ADCL;
  result |= ADCH<&lt;8;
  result = 1126400L / result; // Back-calculate AVcc in mV
  return result;
}
VN:F [1.9.22_1171]
Rating: 4.0/5 (1 vote cast)
VN:F [1.9.22_1171]
Rating: 0 (from 0 votes)
Messung der Substratfeuchte von Pflanzen, 4.0 out of 5 based on 1 rating

QR Code