Arduino für Gewächshaus, Garten oder Growbox
20 Schritt:Schritt 1: Arduino für Garten, Gewächshaus oder Growbox: Ein- und Ausgänge Schritt 2: Arduino für Gewächshaus, Garten oder Growbox: PSU Schritt 3: Arduino für Garten, Gewächshaus oder Growbox: Humiditity und Temperatur Schritt 4: Arduino für Gewächshaus, Garten oder Growbox: LDR Schritt 5: Arduino für Garten, Gewächshaus oder Growbox: Bodenfeuchtigkeit Schritt 6: Alternative Bodenwiderstandsmessung Schritt 7: Arduino für Gewächshaus, Garten oder Growbox: der Pegel / Niveauschalter Schritt 8: Arduino für Gewächshaus, Garten oder Growbox: eine Alternative Niveauschalter Schritt 9: Der Wasserbehälter Schritt 10: Arduino für Gewächshaus, Garten oder Growbox: eine Alternative Schwimmerschalter Schritt 11: Arduino für Garten, Gewächshaus oder Growbox: Summer Schritt 12: Arduino für Gewächshaus, Garten oder Growbox: Solid State Relais Schritt 13: Arduino für Gewächshaus, Garten oder Growbox: Der LCD- Schritt 14: Arduino für Gewächshaus, Garten oder Growbox: Construction Schritt 15: Arduino für Gewächshaus, Garten oder Growbox: Die Software Schritt 16: Arduino für Gewächshaus, Garten oder Growbox: Die Software: Code Schritt 17: Arduino für Gewächshaus, Garten oder Growbox: Die Software: Sonderzeichen Schritt 18: Arduino für Gewächshaus, Garten oder Growbox: mögliche Erweiterungen Schritt 19: Aktualisierte Software Schritt 20: Verwenden von Zeitgebern, Sensoren lesen
Ich habe mit Attiny Chips für Bewässerungsaufgaben in meinem Garten, aber mit Plänen, um ein Gewächshaus zu bauen, schien ein Arduino, um den Weg zu gehen, da es mehrere Ports sein. Ich weiß, es gibt viele "Garduino 'type Projekte bereits, darunter auch solche, die den Zustand Ihrer Anlagen Twitter, aber ich wollte nur etwas einfach, ja, wie funktioniert ein anal retentive Asperger tun in einem solchen Fall: selbst etwas zu bauen.
Keine Verwendung von natürlich für eine Arduino Uno verbringen 23-25 Euro und dann noch einen Schutzschild für Geräte erweitern: schien ein bisschen übertrieben und so habe ich verschiedene "Arduino" alreday, beschloss ich, nur den Chip zu bekommen, einen Kristall eingebaut und 2 Kondensatoren + einige weitere Sachen und bauen die ganze Sache auf einem Archer Experimentierboard, die ich vor 20 Jahren gekauft, aber im Leerlauf war die ganze Zeit (Radioshack partno 276-168). Die Archer Experimentierboard verfügt Inseln mit 3 Löchern und 2 Gäste-Tracks (VCC und GND) schlängelt dazwischen. Natürlich kann es auch auf den regulären Streifenplatte durchgeführt werden, perfboard oder man kann eine Leiterplatte für sie zu machen.
Am Ende habe ich beschlossen, ich brauchte, um die folgenden Funktionen haben
- messen Temperatur messen Luftfeuchte messen Feuchte des Bodens messen Wasserstand in einem Behälter Maßnahme Licht, im Grunde, um festzustellen, ob es hell ist oder Tag schalten Sie ein Fan zu wechseln eine Pumpe schaltet ein Heizelement schaltet eine Lampe
Liste der Materialien
Prozessor
Atmega 328 hier auf Bootloader sich verbrennen oder kaufen Sie ein vorprogrammiertes
1x 28 Pins IC Fuß schmaler (oder 2 x 14 Pins ic Fuß)
16MHz Kristall
2x 22 nF (oft trägt '223' Aufdruck)
1x 10 k (braun-schwarz-orange)
1x 100 nF (oft trägt '104' Aufdruck)
1x PCB momentanen Make-Schalter
perfboard Dies ist, was ich , weil ich, dass etwa im Leerlauf zur schon seit Jahren
HINWEIS: eine attraktive Alternative ist eine billige Arduino Klon wie die Pro mini oder Pro Micro , die für ein paar Dollar in zB Dealextreme.com hatte werden können
Anzeige
16x2LCD CG046-3007 A00, aber andere tun wird .
1602 I2C Modul
PSU
1x 7805, isoliert
1x 1N4001
2x 100uF (16 V de 25 Volt)
1x 1 k Widerstand (braun-schwarz-rot)
1x LED
1x Netzteil-Anschluss
Peripheriegeräte
1x LDR
1x DHT11 Feuchtigkeitssensor (zB von d ealextreme)
1x machen Taster
1x Umschalter
1x Summer (ich benutze das CMB-06 , eine ansteuerbare Summer) (2,99 €), sondern verwenden andere Summer Sie haben oder sind bequem mit zum Beispiel dieses hier
1x NPN-Transistor (egBC547)
1x 330 Ohm (orange-rot-braun)
2x 10k (braun-schwarz-rot)
Halbleiterrelais
4x330 Ohm (orange-rot-braun)
4xLED
4x8pin dil Fuß
4x39MF22 SSR
4x2pin Schraubverbinder (Netzspannung)
1x 5pin female Printheader
1x 5-Pin Stiftleiste 90 Grad Winkel
Alternative: kaufen eine fertige 4-Kanal-mechanisches Relais für fast den gleichen Preis wie lose Teile für die SSR, wie dieser einen , oder eine noch billigere .
Bits und Schrauben
ein paar andere Farbe Drähte, einige Druckschriften, vier 3 mm Schrauben und Muttern, etwa 2,5 mm Schrauben und Muttern, 4 Abstandhalter
Lötzinn, Lötkolben.
Ich habe Cinch-Stecker für den Anschluss verwendet ... aber eigentlich diese schwer zu löten sind.
Gehäuse
Ich benutze zwei Gehäuse:
einen für den Prozessor und die meisten der Peripherie (I mit einem Kunststoff-Box, die Schrauben enthalten: 9x12x4.5 cm)
eine für die SSR (Ich habe ein Tic-Tac Pfefferminzspender Das größere für 100 Münzstätten: 8.5x2x5 cm)
Schritt 1: Arduino für Garten, Gewächshaus oder Growbox: Ein- und Ausgänge
-
Bevor ich beschreiben die Konstruktion werde ich die einzelnen Punkte zu diskutieren:
Prozessor
Ein Atmel 328 mit einem Arduino Bootloader verwendet. Das macht für einfache Anpassung und Hochladen des Programms. Es wird ein "Bare Bones" Setup ohne USB-Eingang, sondern einfach mit den TTL-Rx und Tx-Signale auf einem Kopfball. Erwägen Sie einen günstigen Arduino Pro Mini, pro Mikro- oder Nano Arduino
PSU
Einfach ein 7805-Schaltung aus einer wallwart zugeführt. Keine 3,3 Volt erforderlich sein,
Feuchte- und Temperatursensor
A DHT11 Sensor liefert das. Es ist ein 3-Pin-Sensor, von denen die Daten leicht von der Arduino gelesen werden. Es gibt eine Bibliothek zur Verfügung.
Schalter
Einfach als Eingang zu lesen, um verschiedene Funktionen in der Software eingestellt
Licht
Ein LDR durch einen Analog-Anschluss zu lesen. Es ist im Grunde gibt es zu bestimmen, ob es Tag oder Nacht ist. Dies ermöglicht eine extra leicht, wenn die Tage zu kurz oder, um bestimmte Funktionen zu unterschiedlichen Tages- und vielleicht durchführen (wie unterschiedliche Tag- und Nachttemperatur, keine Bewässerung in der Nacht etc)
Bodenfeuchtesensor
Dieser Sensor, durch einen Analog-Anschluss ausgelesen werden Informationen über die Feuchtigkeit der Erde zu geben und das Signal des Prozessors ist es Zeit, zu bewässern. Es gibt eine ganze Wissenschaft auf DIY Bodenfeuchtesensoren. Ich werde nur mit werden die klassischen "2 Nägel" -Ansatz. Die Software und die Hardware für den Strom durch den Sensor zu ermöglichen, ausgeschaltet werden, wodurch die Verzögerung Korrosion.
Niveausensor
Dieser Sensor überprüft, ob der Wasserbehälter ist immer noch voll. Eine einfache Schwimmerschalter genügt
Summer
verwendet werden, um Signale zu geben, zB wenn der Wasserbehälter leer ist. Ich benutze einen alten CMB-06, die einen Auslöser hat, dh es kann mit einem kleinen Strom ausgelöst wird, während es seine Hauptstrom direkt von den Stromversorgungsleitungen zu erhalten.
Halbleiterrelais
Ich benutze 4 Halbleiterrelais, einen Ventilator, eine Pumpe, eine Heizung und die Beleuchtung einzuschalten. Die Halbleiterrelais werden vom Prozessor Ausdruck der Sicherheitsvorkehrungen getrennt.
Schritt 2: Arduino für Gewächshaus, Garten oder Growbox: PSU
-
Das Netzteil ist ein Standard-Schaltung bauen um eine 7805 Menschen, die sich auskennen in der Elektronik werden wahrscheinlich keine Probleme mit ihm. Für den weniger erfahrenen. Ich habe eine etwas umfangreicher Zeichnung.
Im Hinblick auf die Polarität der LED: normalerweise LEDs mit 2 Beinen: ein kurzer und ein langer Weg. Die kurze ist usuall y die Kathode, die mit Masse verbindet. Der lange Schenkel ist die Anode, die mit der positiven Spannung verbindet.
Mit der Serienwiderstand 1k, erhält der LED ca. 3,5 mA, während LED kann einige 15 mA zu nehmen. Sie sehen, dass die meisten LEDs sind schon ziemlich hell mit einem 1k Serienwiderstand
Schritt 3: Arduino für Garten, Gewächshaus oder Growbox: Humiditity und Temperatur
-
Fo rmeasuring der Luftfeuchtigkeit und Temperatur I verwendet einen billigen DHT11 Modul Es kommt in verschiedenen Formen, aber wenn die bare Modul hat 4 Beine, es kommt in der Regel auf einer kleinen Leiterplatte mit nur 3-polig, oder 4 Pins, in der man nicht angeschlossen ist. Es gibt verschiedene Bibliotheken für die DHT11 vom Arduino verwendet werden. Eine gute Bibliothek jedoch ist die eine von Ladyada .
Normalerweise ist es ziemlich gut angedeutet, was die Versorgungsleitungen und die Signalleitungen sind.
Da einige Bibliotheken nehme die Signalleitung angeschlossen ist, um digitale Stift 2 Arduino ist, dass das, was ich in diesem Entwurf, gefolgt
Hinweis: nachdem es ihn für eine Weile, fand ich die DHT11 ziemlich unzuverlässig. Die Temperatur kann 4 Grad zwischen zwei aufeinanderfolgenden reaadings schwanken und hat eine Tendenz, zu hoch zu sein. Der DHT22 ist eine genauere Sensor (so wurde mir gesagt), aber es ist teurer.
Ich weiß nicht, wie genau die DHT11 ist in Bezug auf die Luftfeuchte ... aber man könnte sich dafür entscheiden, den DHT11 zu halten, aber fügen Sie eine BMP180 für genauere Temperatur. Das gibt Ihnen Atmosphärendruck als auch. Es ist ein I2C Sensor so ist es leicht zu fügen.
Schritt 4: Arduino für Gewächshaus, Garten oder Growbox: LDR
-
Ich verwende eine LDR, um die Lichtstärke zu bestimmen. LDR einen Spannungsteiler bildet zusammen mit einer 15-K-Widerstand. Wenn es dunkel wird, geht der Widerstand des LDR und damit die Spannung über dem 15-K-Widerstand sinkt. Wenn es hell ist, ist der Widerstand des LDR niedrig, und daher die Spannung über dem 15-K-Widerstand hoch ist.
LDR die haben in der Regel eine große Auswahl variieren. Der, den ich habe, ist rund 300 k in der Dunkelheit und 300 Ohm bei Tageslicht. Wie ich bin nur daran interessiert, ein rohes Licht, Dämmerung, Nacht Lesung, beschloß ich den Widerstand des LDR, was ich genannt Dämmerung. Das war 15 k. Daher Wahl eines 15 k Widerstand im Spannungsteiler liefert das breiteste Angebot.
Einlegen der LDR in einer klaren Gehäuse (eine Pille Flasche) verbunden ist über einen dünnen Draht mit dem Arduino Vcc und analoge Pin 1 (dh auf einer Atmega 328 Pin 21). Das 15-K-Widerstand auf der Leiterplatte.
Ein guter Weg, um den Wert für die Pull-Down-Widerstand zu bestimmen, ist die Axel Benz Formel .
Da wir nur an einem Tag und Nacht Unterschied gibt, ist der Pull-up-Widerstand nicht so kritisch
Schritt 5: Arduino für Garten, Gewächshaus oder Growbox: Bodenfeuchtigkeit
-
Bodenfeuchte wird im allgemeinen durch den Widerstand zwischen zwei Stiften in der Erde gemessen. Im Allgemeinen werden zwei Arten von Sensoren verwendet: zwei Nägeln oder Stiften in der Erde stecken oder 2 Stangen in Gips umhüllt im Boden gesetzt.
Beide Methoden haben ihre Vor- und Nachteile. Die (galvanisiert) Nägel in den Boden in unterschiedlichen Abständen gesetzt werden, beeinflussen den Widerstand, aber sie sind einfach und billig und reagiert schnell auf Änderungen in der Feuchtigkeit. Der Gips-Verfahren stellt sicher, dass die Stäbe in einem festen Abstand, aber die Reaktion auf Änderungen in der Feuchtigkeit langsamer sind.
Beide Typen sind der Korrosion im Erdboden, einem Prozess, der durch die Elektrolyse aufgrund der aktuellen Sende durch den Sensor beschleunigt wird, jedoch sind die Gipsstäbe umhüllt weniger korrosionsanfällig, da sie nicht direkt auf den Boden ausgesetzt ist.
Doch freies Stangen wahrscheinlich muss jedes Jahr aufgrund von Korrosion ersetzt werden, wird der Gips Sensor müssen auch wegen Auflösen des Gipses ersetzt.
Die Korrosion der Stäbe kann durch Begrenzung der Elektrolyse, indem nur einen Strom durch die Stangen bei der Messung verschoben werden.
Das ist das, was ich in dieser Gestaltung gewählt: Der Transistor wird durch einen hohen Grad von einem digitalen Stift geöffnet. Die emmitter wird dann hochgezogen (etwa 4,7 Volt). Diese Spannung wird dann an den Sensor (die beiden Stifte im Boden) und der Spannung über die 10-K-Widerstand zugeführt wird, dann durch einen Analog Stift gelesen. Der Transistor ist im Grunde jede Art von billigen NPN-Transistor-Signal, wie eine BC107 oder BC547. Ich habe eine VN147 eine 30 Jahre alte "Universal NPN 'Transistor, aus keinem anderen Grund, die ich hatte, dass herumliegen und ich irgendwie wie der Dreiecksform hat
Der Sensor und der Widerstand in Wirklichkeit ein regelmäßiges Spannungsteiler, in dem die Spannung über R2 gibt einen Hinweis auf den Widerstand des Sensors und damit die Feuchtigkeit des Bodens.
Widerstand der Boden nicht nur Feuchtigkeit, sondern auch mit der Art des Bodens ab. Im allgemeinen meinen Boden unter feuchten Bedingungen macht einen Widerstand von etwa 10 k zwischen den Sensorstifte, aber auch dann, wenn die Stifte würde kurzgeschlossen werden, wird der Maximalstrom von etwa 0,5 mA sein. Es ist daher möglich, lassen Sie den Widerstand und füttern den Sensor direkt von einer Digitalstift (der Lage ist, 40 mA), aber ich fühle mich glücklicher mit etwas Schutz der Arduino Pins.
Die 5V1 Zener-Diode zwischen dem analogen Stift und der Erde ist, um den Chip vor hohen Spannungen, die aufbauen kann, wenn eine lange Schlange an der Sonde wird verwendet, zu schützen. Es ist optional.
Die Software verfügt über eine Routine, die die Spannung über den Widerstand 10 k 5 mal gelesen wird und dann einen Mittelwert.
Einige Tech-Zeug über Bodenfeuchte
Bei Verwendung eines Mess wie das hier, die Sie messen Widerstand oder Leitfähigkeit, je nachdem, wie Sie wollen ihn ansehe.
Die Leitfähigkeit ist in der Tat nicht der beste Weg, um Feuchtigkeit des Bodens als Wasser selbst ist nicht wirklich ein guter Leiter zu messen, was Sie tatsächlich messen ist die Menge an gelösten Ionen in Ihrer Anlage-Bett. Ein nicht so feuchten Boden mit vielen Ionen kann Ihnen eine höhere Leitfähigkeit als Lektüre für einen nassen Boden mit weniger Ionen.
Messen Sie Ihre Ionen ist natürlich eine nützliche Sache zu, wie es gibt Informationen darüber, ob Ihr Boden aufgebraucht ist und ob vielleicht ist es Zeit, Dünger hinzuzufügen.
Wenn Sie eine zuverlässige Messung der Feuchtigkeit von Ihren Boden, dann eine kapazitive Messung ist zuverlässiger: Wasser beeinflusst das Dielektrikum eines Kondensators viel mehr als Ionen zu tun.
Ein Kondensator in Ihrem Boden klingt mit zwei Metallplatten in Ihrem Boden, in dem der Boden zwischen ihnen ist das Dielektrikum. Das ist durchaus möglich, jedoch ist es auch möglich, die Platten des Kondensators sind nebeneinander anstatt einander zugewandt sind. Das eröffnet die Möglichkeit, sie auf einem Stück PCB ätzen. Offensichtlich werden die Platten aus dem Boden isoliert, sonst würden Sie nur werden wieder Messung der Leitfähigkeit / Widerstand. Das hat den zusätzlichen Vorteil, dass es keine Boden Korrosion sein.
Also, wenn Sie haben, dass eingerichtet wurde, gibt es zwei Möglichkeiten der Messung: Sie gerade messen konnte die Kapazität Ihrer DIY Boden Kondensator, wie der Arduino ist durchaus in der Lage, das zu tun. Das Problem ist aber, wenn Sie ein Kabel, das von diesem Sensor zu Ihrem arduino, ist, dass in der Tat eine Streukapazität, die Sie messen auch. Die Art, wie Ihr Kabel eingeschleift können Ihre Lesung sowie jemand nähert Ihrem Kabel beeinflussen. Verwendung Koax helfen, aber es ist immer noch am besten, um die Messung in der Nähe Ihres diy Kondensator zu tun.
Eine andere Möglichkeit ist, daß der Kondensator in einem Schaltkreis, dessen Ausgangssignal auf den Wert des Kondensators, wie etwa einen Kondensator gesteuerten Oszillators in Abhängigkeit zu verwenden. Dies kann mit einem Schmitt-Trigger durchgeführt, wie im Bild oben gezeigt wird, werden.
Die Frequenz dieses Oszillators ist:
f = 1,2 / (RxC)
Eine wechselnde Menge an Wasser in den Boden wird das Dielektrikum des Kondensators und damit der Wert des Kondensators und damit die Frequenz aus dem Oszillator kommenden beeinflussen. Diese Frequenz kann durch die Arduino mit dem messenden Frequenzmess Bibliothek des Arduino.
Der Wert des Widerstandes hängt von Ihrer Situation. Wählen Sie eine, die eine gute Auswahl an Ihre Frequenz gibt. Das Arduino Bibliothek unterstützt frequncies zu 8 MHz.
Wenn Ihr Kondensator 10nF und Ihren Widerstand 100kOhm, würde die Frequenz 1200 Hz liegen. Sie erhalten ein Taschenrechner finden Sie hier .
Die FreqCounter.cpp Datei für digitale Stift 5 als Eingabe codiert und verwendet sowohl Timer-Interrupts T1 und T2
Sollten Sie sich für kapazitive Messung der Luftfeuchtigkeit, anstatt die verschiedenen Frequenzzähler-Bibliotheken verwenden, können Sie auch "PulseIn '. Ein Beispiel davon ab, wie das zu tun kann im nächsten Schritt zu finden.
Schritt 6: Alternative Bodenwiderstandsmessung
-
In der vorigen Seite habe ich über die Vor-und Nachteile der Messung der Bodenfeuchte, entweder als Widerstandsmessung oder als kapazitiver Mess gesprochen.
Im Hinblick auf die Widerstandsmessung mit Gleichstrom mit den Bodensonden als Spannungsteiler Einspeisung in ein analoges Tor ist die einfachste Lösung, aber schiebt einen Gleichstrom durch die Sonden zu schnellem detoriation infolge der Elektrolyse führt.
Das kann man entgegenwirken, indem nur Putting Macht auf den Sonden im Moment der Messung und die Messfläche, ein paar Mal pro Tag sagen zu begrenzen.
Eine weitere Option ist jedoch mit AC.
Die vorgestellte Schaltung sieht vor, dass. Das Ausgangssignal eine Frequenz ist, die auf dem Widerstand des Sensors abhängt.
Der + Eingangsleistung kann so niedrig wie 3,5 Volt und so hoch wie 15 Volt betragen, so dass die 5 Volt des Arduino ist perfekt. Der CMOS LMC555 Timer arbeitet in seiner direkten Feedback-Modus, mit einer Rechteckwellenausgang von Pin 3 Laden oder Entladen des 0,1 uF Filmkondensator durch die Festwiderstände in Serie / parallel mit den leitenden Messfühler.
Das 2,2 uf unpolaren Kondensatoren in Reihe mit den Sonden zu gewährleisten, daß selbst die geringe Leckströme von Niveau CMOS-Chips nicht durch die Sonden zu fließen. Die Kondensatoren, von denen einer auf jeder Seite der Sonden auch sicherzustellen, daß diese Schaltung galvanisch getrennt von anderen Sensoren, die in der gleichen wässrigen Umgebung sein könnten.
R1 und R2 begrenzt den Bereich im Falle eines Kurzschlusses oder extrem trockenen Boden. R2 hat auch eine andere Funktion, als es jede geringfügige DC bauen sich mit den Kondensatoren in Reihe mit der Sonde, die den Oszillator Stopp machen könnte entlädt.
Die Ausgangsfrequenz von auf der '555 mit offenem Kollektor DIS Ausgangsstift übertragen. Dieser Pin ist synchron mit der Ausgabe und wird eine Rechteckwelle, deren Frequenz / Impulsbreite kann durch die Arduino (zB durch eine Timer-Interrupt oder durch 'PulseIn') gemessen werden, zu produzieren. R3 ist erforderlich, da die DIS (Entladung) Stift des 555 ist ein offener Kollektor.
Als dem von der Zeitgeberschaltung 555 ändert sich linear im Verhältnis zu der Frequenz der Schwingung aufgrund der Lade- und Entladezyklen des zeitbestimmenden Kondensators gezogen, kann der Versorgungsstrom als ein analoges Signal verwendet werden, um an einen Analog-Digital-Wandler zu senden. Daher kann ein 1k Widerstand in einer der Versorgungsleitungen (typischerweise die Grnd) Das aktuelle entwickelt eine Spannung über den Widerstand 1 kOhm gesetzt werden, um ein Spannungssignal zu geben, wenn gewünscht.
Das Bild oben zeigt eine Funktion, um die Frequenz (in der Tat die Pulsbreite) zu messen. Das folgende Programm tut das gleiche.
Ich benutze Wert von 500 000 US-anstelle von 1 000 000 US (= 1 Sekunde) für den Bereich, weil ich will, um die Signalperiode (T) zu erhalten, nicht Pulslänge (tpuls). Mit Tastverhältnis von 50%, T = 2 * tpuls. Allerdings, wenn Sie sich für das wahre Frequenz sind, dass es nicht für die Bestimmung der Bodenfeuchte Rolleint pin = 7; unsigned langer Dauer; Leere setup () { pinMode (pin, INPUT); Serial.begin (115200); } Leere Schleife () { Dauer = pulseIn (pin, HIGH); Serial.print ("Time"); Serial.print (Dauer); Serial.print ("us"); Serial.print (500 / Dauer); Serial.print ("kHz"); Serial.print (500000 / Dauer); Serial.println ("Hz"); Verzögerung (500); }
Natürlich ist die obige Programm ist nur ein Proof of Concept / Testprogramm: wir daran interessiert, bestimmte Frequenzen aber Unterschiede in Frequenzen / Zeiten sind es nicht. Sie müssen für Ihren Boden zu bestimmen, was das richtige Timing / Frequenz ist für sie Wasser brauchen oder nicht und übernehmen, dass in Ihrem Programm auf die gleiche Weise wie zuvor würden Sie so fr den Spannungsteiler-Sonde auf einer anolog Port getan. Es ist immer noch möglich, das Potentiometer auf A1 verwenden, um eine Ebene, zB durch Zuordnung zu Ihrem Frequenzbereich, oder mit ein paar Falls oder Case-Anweisungen gesetzt.
Um einen Eindruck zu geben, wenn ich es getestet in meinem System (Sonden mit etwa 6 cm Abstand, in so genannten "Mels Mix ') eine etwas feucht Lesung war 3 kHz, während ein nasser Boden gab 10kHz
Schritt 7: Arduino für Gewächshaus, Garten oder Growbox: der Pegel / Niveauschalter
-
Ich habe einen Niveauschalter zu überprüfen, ob der Wasserbehälter ist immer noch voll aufgenommen. Dies ist nicht nur für das Wohlbefinden der Pflanzen, sondern auch für das Wohl der Pumpe als Tauchwasserpumpen sollten nicht verlassen trocken laufen notwendig.
Es gibt viele Möglichkeiten, in denen man einen Niveauschalter bauen: ein Magnet auf einem Schwimmer, der einen Reed-Schalter, eine tlt Schalter mit einem Hebel, der nach oben und unten mit dem Wasserstand, "Fühler" im Wasser usw. geht angebracht aktiviert
Ich habe einen sehr einfachen Ansatz gewählt. Ich habe eine Gummi-Ente auf dem Wasser schwimmen. Das Enten hat eine Schnur befestigt, die einen Mikroschalter, der über die Oberseite des Behälters hängt arbeitet. Wenn das Wasser nach unten geht, so geht die ducky intil zieht es den Schalter. Daß der Schalter durch den Arduino die dann schaltet die Pumpe ab und sendet ein Signal an den Summer zu lesen.
Der Schalter ist mit einem gewöhnlichen digitalen I / O-Pin verbunden. vielleicht wäre es eleganter, um es zu einem Interrupt-Pin zu befestigen, aber wie der Arduino ist nicht wirklich bis in alle Arten von Routinen statt, das Lesen eines normalen I / O-Pin sollte nicht viel verzögert werden.
Anstelle einer Gummi-Ente kann man auch ein Stück Holz nehmen. Alles, was schwimmt, ist aber schwer genug, um den Schalter zu betätigen. Nach der Zeichenfolge Ich rate Nylonfischerei String
Schritt 8: Arduino für Gewächshaus, Garten oder Growbox: eine Alternative Niveauschalter
-
Wenn Sie nicht wie einen mechanischen Schalter, um das Wasser-Reservoir Signal voll zu sein, ist dir eine einfache elektronische Lösung:
Hängen Sie zwei Elektroden auf der Ebene des Wassers, die Sie bei signalisieren soll. Sie können kommen, höher, aber nicht geringer. Anstelle von zwei losen Elektroden könnte man auch ein Stück PCB Verwendung mit zwei Spuren darauf geätzt.
Ernähren diese beiden Elektroden an der Schaltung, wie hier dargestellt.
Solange das Wasser in Kontakt mit den Elektroden, wird der Transistor einen Basisstrom zu empfangen und zu erschließen. Der Kollektor wird nach unten gezogen werden, und die Arduino Pin kann, dass zu erkennen.
Wenn der Wasserstand unter den Elektroden fällt, wird der Transistor einen Basisstrom nicht mehr empfangen und zu schließen. Der Kollektor wird daher hoch sein.
Wohlgemerkt die Atmega 328 I / O-Pins haben einen internen Pull-up-Widerstand und damit eine Pull-up-Transistor ist in dieser Schaltung nicht erforderlich. Um sicher zu sein, obwohl ein 15k oder 22k Pull-up-Widerstand zwischen dem Kollektor und dem +5 Volt Leitung hinzugefügt werden.
Wenn Sie kurz auf I / O-Pins sind Sie einen Stift mit Hilfe T1 nicht nur auf einen niedrigen Pegel zu dem Prozessor zu signalisieren retten könnte, aber auch, um den Summer direkt steuern oder sogar einen Relay betreiben, um die Pumpe auszuschalten, spart ein weiteres I / O-Pin. Aber dann wieder, die meisten Funktionen könnten wahrscheinlich sein mit diskreten Komponenten und der Atmega 328 bauen genügend I / Opins für dieses Projekt
Schritt 9: Der Wasserbehälter
-
Ich verwende eine 86-Liter-Eimer Zement als Wasserbehälter.
Ich habe das in den Boden gegraben, um sicherzustellen, dass sie niedriger als die plantbed ist. Wenn sie höher als die plantbed ist, gibt es achance die yr Pumpe, nachdem er ausgeschaltet wurde, startet Absaugen, das Leeren des gesamten Eimer in Ihrem plantbed.
Wenn aus irgendeinem Grund Ihre Wasserbehälter muss höher als Ihre plantbed zu können, benötigen Sie, um ein Vakuum Release installieren.
Schritt 10: Arduino für Gewächshaus, Garten oder Growbox: eine Alternative Schwimmerschalter
-
Bestimmen, ob der Tank leer ist, auch mit einem Reedschalter als Figur möglich zeigt: Wenn der Pegel sinkt auf einen bestimmten Betrag, wird der Magnet auf den Kolben den Schalter zu schließen, und das wird sein Signalisierung des Arduino, dass die Pumpe nicht betrieben werden nicht mehr.
Der Nachteil dieser Schaltung ist, dass irgendwann der Reed-Schalter wird zu magnetisieren und gehen Sie zu einer permanenten geschlossenen position.Replacing die relativ billig Reed-Schalter wird natürlich zu beheben, dass.
Schritt 11: Arduino für Garten, Gewächshaus oder Growbox: Summer
-
Ich habe einen Summer für Meldefunktionen (vor allem, um zu signalisieren, dass der Wasserbehälter leer wäre). Ich habe die CMB-06 Summer aus Star eingesetzt. Meine wichtigste Kriterium war, dass ich, dass Summer herum schon seit Jahren. Es ist ein sehr handliches Summer obwohl, weil es auslösbar ist. Der Vorteil davon ist, dass ich nicht brauchen ein Arduino Pin, den gesamten Strom für das Audiosignal benötigt wird, nur einige aktuelle für den Auslöser zu liefern. Deshalb habe ich nicht, um einen Transistor, um den Summer zu fahren hinzuzufügen.
Die + und - sind bequem mit dem Netzteil und dem 'C' (= Kontrolle) Stift wird über eine 1k Widerstand zu einem Arduino Pin angeschlossen (in der Tat Pin 9, die PWM hat) verbunden
Der Höchstbetrag des durchschnittlichen (!) Strom durch den Summer als 23 mA, der von einem Arduino Pin zugestellt werden konnte festgestellt, aber die Datenblatt benötigt eine Stromquelle von etwa 70 mA für Spitzen. Das ist über das, was ein Arduino sicher liefern kann. Direkt Einspeisung von der Netzleitung und der Auslösestrom nur aus einem Arduino Pin geliefert löst dieses Problem.
Schritt 12: Arduino für Gewächshaus, Garten oder Growbox: Solid State Relais
-
Die 4-Kanal-Halbleiterrelais wird verwendet, um Dinge wie wachsen Lichter, einer Wasserpumpe über einen Ventilator und eine Heizung bei Bedarf zu wechseln. Es ist fast ein eigenes Projekt (wenn auch einfachen).
Die Schaltung muss 4 mal zu bauen, und ich habe ein Print-Design zur Verfügung.
Die Schaltung verwendet einen 39MF22 Halbleiterrelais, die einfach braucht ein Vorwiderstand zur Strombegrenzung. Eine LED zeigt an, ob das Relais aktiv ist.
Weil es auf 220 Volt angeschlossen ist, habe ich es auf einer separaten Leiterplatte aufgebaut und es in einem anderen Fall.
Die 4 Kanäle von digitalen Pins 5,6,7 und 8 (Das sind physicals Stifte 11-14 auf der Atmega 328) gesteuert
Induktive Lasten wie die Lüfter und die Pumpe, benötigen Sie einen Überspannungsschutznetzwerk (100 Ohm Widerstand und 100 nF Kondensator in Reihe über die Verbindung). Da diese induktiven Lasten sind nur geringer Strom ich sie ausgelassen und habe keine Probleme erlebt.
Dieser Teil ist vollständig in einem anderen instructable beschrieben.
.
Warnung
Dieses Gerät eine Verbindung zu einem Netzspannung. Das kann dich töten. Wenn Sie nicht mit der Arbeit mit Hochspannungsschaltkreisen kennen dann nicht bauen diese
Schritt 13: Arduino für Gewächshaus, Garten oder Growbox: Der LCD-
-
In Anbetracht es gibt nur so viel I / O-Pins auf der Atmega 328, beschloss ich, einen LCD-über einen I2C-Schnittstelle hinzufügen
Die Bibliothek, um den Einsatz der neuen LCD-Bibliothek aus Malpertida
Die Pin-Out der I2C-Schnittstelle ist so, dass es gut passen die meisten LCDs.
Es ist möglich, eigene I2C-Schnittstelle zu bauen, aber ich würde davon abraten. Die einzeln Dealextreme ist so billig, dass der Aufbau selbst teurer wäre. Nur der Chip allein würde wahrscheinlich schon mehr als die ca. sein 1,80 Euro, der gesamte fertig gebaut Teilkosten bei Dealextreme.
Ich hatte als Nokia 5110 Display benutzen, aber dass einige 4 oder 5 Daten-Pins benötigt. Sicherlich könnte ich I2C entweder für die Anzeige oder für die Ein- und Ausgänge, aber da war ich schon zu weit voraus, alles für I2C für Ausgänge und mit I2C für das Nokia LCD neu verkabeln zu verwenden ist etwas, was ich noch nicht herausgefunden, aber es ist möglich. Die zur Verfügung stehende Bibliothek verwendet SPI -Welche der schnellste Modus von Kommunikations- ist aber, wie es hart codiert ist, müssten Sie einige Umschreiben zu tun. Deshalb entschied ich mich für den regulären LCD.
Unter Verwendung eines 5110-Display über I2C ernsthaft verlangsamen den Bildschirm aufzubauen, um vielleicht eine Sekunde. Sie werden einige erste Lesung finden Sie hier
Schritt 14: Arduino für Gewächshaus, Garten oder Growbox: Construction
-
Es ist schwer, eine Beschreibung der Konstruktion als Give 'das ist, wie Sie es tun ", wie die Art, wie ich sie gebaut auf dem Material, das ich auf der Hand hatte hing: eine leicht opake Kunststoff-Box als Behälter und ein Stück Archer, dass PCB nach der Verlegung schon seit 10 Jahren habe ich schließlich wollte bis zu einem gewissen guten Zweck.
Deshalb kann ich nur einige allgemeine Hinweise zu geben.
Ich begann mit dem Aufbau der Stromversorgung, gefolgt von der Atmel-Prozessor 328. Letztere etwas in der Mitte des PCB so noch Platz auf beiden Seiten für verschiedene Komponenten sein.
Es ist eine gute Idee, die Funktionsweise jedes Teils überprüfen, nachdem Sie es zu beenden, diese Weise können Sie vermeiden, den Aufbau der gesamten Schaltung und habe keine Ahnung, warum es nicht funktioniert (wenn alle Stricke zum schlechtesten). So, nachdem ich war mit der Stromversorgung durchgeführt, überprüfte ich es für 5 Volt. Dann, nachdem ich baute den Prozessor eingeführt ich eine 328-Chip, die ich mit einem Testprogramm vorprogrammiert war, hinzugefügt die Schnittstelle für das Relais / SSR und das funktionierte. Verdrahtet das FTDI getestet usw.
In der Zwischenzeit hatte ich die die LCD durch Löten des I2C Huckepack, um es hergestellt und getestet, dass auf einem Arduino UNO so wusste ich, dass es funktionierte. Dann legte ich sie in der Box als auch.
Anfangs hatte ich gedacht, um die Verbindung zu dem SSRI / Relais, indem Sie ein Kabel durch die Box zu machen, aber ich beschlossen, ich wollte einen Anschluss. Da diese benötigt, um einen 5-Stecker Stift, und ich hatte bereits einen weiblichen sil-Anschluss an der Relais gemacht, ich habe gerade für die Herstellung einer männlichen sil-Anschluss an der Box, mit viel Heißkleber entschieden.
Den Fehler, den ich durch die Montage des Sensors auf DHT11 Oberseite des Gehäuses gemacht nicht machen .... vor allem, wenn die LCD-Hintergrundbeleuchtung eingeschaltet ist, wird die Temperatur in und um das Gehäuse kann steigen, leicht zu einem 2-5 Grad Unterschied führenden
Schritt 15: Arduino für Gewächshaus, Garten oder Growbox: Die Software
Die Software ist das, was meine Situation zugeschnitten und Sie können auch entscheiden, Sie brauchen, um Änderungen vorzunehmen. Ich habe versucht, zu kommentieren, so viel wie möglich. Ich bin sicher, dass der Code vereinfacht werden könnte, aber das funktionierte für mich.
Die wichtigsten Elemente sind die folgenden:
BibliothekenAdafruit DHT Bibliothek
Malpertida neuen LCD-Bibliothek
RTC-Bibliothek (optional, für das Hinzufügen eines DS1307 RTC)
ErklärungenDas übliche: Stifte, Konstanten, Variablen etc
Definition der Zeichen für den LCD
EinrichtenEinrichten der PinModes und deren Status
Einrichten des LCD, laden Sie die benutzerdefinierte Zeichen
Drucken Sie eine Begrüßungstext
Blinken die LCD zweimal
Geben einen schnellen buzz
stellen Sie die RTC (optional)
SchleifePrüfen Sie zunächst, ob der Wasserbehälter leer ist oder nicht. Damit soll verhindert werden, dass die Pumpe trocken läuft
Wenn es leer ist, geben Sie ein Summen
Dann lesen Sie den Pegel für trockene vs nass wie durch den variablen Widerstand eingestellt
Setzen Sie dann eine Spannung an der Bodenfeuchtesensor
und las er Bodenfeuchte
// // --------------------------
Lesen Sie den Sensor DHT11
Lesen Sie den LDR// // ------------------------
Anzeigedaten in Abhängigkeit von dem Zustand des Drucktasten
// ------------ AKTIONEN ----------- //
wenn die Temperatur unter 20 Grad schalten Sie Heizung
Wenn die Luftfeuchtigkeit über 60% wiederum am Ventilator
Wenn unter dem Niveau der variablen Widerstands- gesetzt> starten Sie die Pumpe
Man kann den Code ändern, um nur bewässern, wenn es hell ist
FunktionenProbe
Wird ein Sensor 5 mal gelesen und Karte die durchschnittliche auf ein 8-Bit-Wert
Blitz
kann der LCD-Beleuchtung blinkt einige Male. kann als Alarmfunktion verwendet werden
Summen
kann der Summer für eine Reihe von Zeiten klingen
Schritt 16: Arduino für Gewächshaus, Garten oder Growbox: Die Software: Code
/ * Messen Bodenfeuchte, wenn weniger als der Sollwert-Schalter Pumpe messen Temperatur, wenn weniger als Sollwert, schalten Sie Heizung Maßnahme Feuchte, wenn höher als Sollwert, schaltet Lüfter <a href="http://www.quickgrow.com/gardening_articles/fans_air_movement.html"> <a rel="nofollow"> <a href = "http://www.quickgrow.com/gardening_articles/fans_ .. .</a"> http://www.quickgrow.com/gardening_articles/fans_...</a>>> LCD commands: lcd.setBacklight(LED_OFF); lcd.noBacklight(); lcd.clear(); lcd.home(); * / /*-----( Import needed libraries )-----*/ #include <Wire.h> #include <LiquidCrystal_I2C.h> //F. Malpertida #include "RTClib.h" //Adafruit #include <dht.h> // Rob Tillaart <a href="http://arduino.cc/playground/Main/DHTLib"> http://www.quickgrow.com/gardening_articles/fans_...</a> /*-----( Declare objects )-----*/ dht DHT; // set the LCD address to 0x27 for a 20 chars 4 line display // Set the pins on the I2C chip used for LCD connections: // addr, en,rw,rs,d4,d5,d6,d7,bl,blpol LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE); // Set the LCD I2C address /*-----(Declare RTC object )------*/ RTC_DS1307 RTC; //declare onject /*-----( Declare pins )------*/ byte moisturePin=0; //read soil mositure byte levelPin= 1; //analogue Pin1 set level for irrigation byte humidPin=2; //Physical pin4 Humidity sensor byte lightPin=5; //Switches on light byte fanPin=6; //Switches fan byte pumpPin =7; //Switches pump byte hotPin= 8; // Switches heater byte buzPin=9; // Switches buzzer byte emptyPin=10; //digital Pin10 guards waterlevel byte spikePin=12; //Digital Pin12 Extra for intermittent switching of spike byte LDRPin=3;// analog pin for LDR byte PushButton=4; // PushButton byte SwitchButton=3;// throw Switch byte push=0; byte sButton=0; #define DHT11_PIN humidPin /* Variable setting */ unsigned int moist=0; //will contain the soil moisture level unsigned int irrigate=0; //sets level for irrigation in case no potmeter byte level=0; int c;// contains the temperature reading // these constants won't change: const int sensorMin = 40; // LDR minimum, discovered through experiment const int sensorMax = 1012; // LDR maximum, discovered through experiment byte light; // value for LDR reading // Create a set of new characters const uint8_t charBitmap[][8] = { { 0xc, 0x12, 0x12, 0xc, 0, 0, 0, 0 } . { 0x6, 0x9, 0x9, 0x6, 0, 0, 0, 0 } . { 0x0, 0x6, 0x9, 0x9, 0x6, 0, 0, 0x0 } . { 0x0, 0xc, 0x12, 0x12, 0xc, 0, 0, 0x0 } . { 0x0, 0x0, 0xc, 0x12, 0x12, 0xc, 0, 0x0 } . { 0x0, 0x0, 0x6, 0x9, 0x9, 0x6, 0, 0x0 } . { 0x0, 0x0, 0x0, 0x6, 0x9, 0x9, 0x6, 0x0 } . { 0x4,0x4,0x4, 0x4, 0x15, 0xE,0x4,0x0 } }; /// -------- end creation-------------- //The following function, "setup", must always be present Leere setup () { Serial.begin(115200); //upload defined characters to LCD //---------------end upload---------------- pinMode(levelPin,INPUT); // set level pinMode(humidPin,INPUT); // measures humidity pinMode(emptyPin,INPUT); // measures reservoir pinMode(SwitchButton, INPUT); // make Switch pinMode(PushButton, INPUT); // PushButton pinMode(spikePin,OUTPUT); // for alternative supply to spikes pinMode(pumpPin,OUTPUT); // Output for Relay pinMode(fanPin, OUTPUT); // Output for fan pinMode(hotPin, OUTPUT); // Output for heater pinMode(lightPin, OUTPUT);// Output for light pinMode(buzPin, OUTPUT); // Output for buzzer digitalWrite(pumpPin, LOW);// Pump off digitalWrite(spikePin, LOW);// moisture sensor off digitalWrite(fanPin,LOW); // fan Off digitalWrite(hotPin,LOW); // heater off digitalWrite(lightPin, LOW); // light Off digitalWrite(buzPin, LOW); // buzzer off /* Now LCD */ lcd.begin(16,2); // initialize the lcd for 20 chars 4 lines, turn on backlight int charBitmapSize = (sizeof(charBitmap ) / sizeof (charBitmap[0])); for ( int i = 0; i < charBitmapSize; i++ ) { lcd.createChar ( i, (uint8_t *)charBitmap[i] ); } lcd.backlight(); // Print a message to the LCD. lcd.setCursor(0, 0); lcd.print("Greenhouse"); // ------- Quick 2 blinks of backlight ------------- flash(2); // ------- Quick buzz-------------------------------- buzz(1); Wire.begin(); //needed for RTC, not for LCD RTC.begin(); /* Set the date / time to the time this program was compiled. Comment this OUT, AND upload, to let the clock just run. * / // RTC.adjust(DateTime(__DATE__, __TIME__)); } /*----------------------------(end setup )---------------------*/ Leere Schleife () { DateTime now = RTC.now(); //Get the current data // Serial.print("The year is "); // Serial.print(now.year(), DEC); // Serial.print(" Month = "); // Serial.print(now.month(), DEC); // Serial.print(" Day = "); // Serial.print(now.day(), DEC); // Serial.print(" Time = "); // Serial.print(now.hour(), DEC); // Serial.print(':'); // Serial.print(now.minute(), DEC); // Serial.print(':'); // Serial.print(now.second(), DEC); // Serial.println(); //------------end of RTC // ---------- 1. Check if there is enough water ------------- // check if there is water level= digitalRead(emptyPin); if (level==0) { buzz(3); delay(500); } //------------2. Read the soil moisture content/switch pump---------------- /* First read the level set with P1 on the levelPin and store that in 'irrigate' * / irrigate=sample(levelPin); //average of 5 readings /* Then we read the soil humidity sensor. We'll first have to set the spikePin to HIGH, in case that is used to feed the sensor. After the reading we set it back) If the value read ('moist') is smaller (high resistance) than what is considered dry <br> (='irrigate') then the pump should be switched on for a specific time. Flutter is prevented by indicating a slightly higher treshhold for switching the pump off If however the waterreservoir is empty ('level == LOW'), the pump should not be on.<br> To avoid a nested if loop, we write the value of 'level' to the pump. If the soil is dry, but the waterreservoir empty, the pump will remain Off ->dead plants but pump still alive * / digitalWrite(spikePin, HIGH);// put voltage on the humidity sensor delay(100); //wait a short while moist=sample(moisturePin); //read soil humiditySensor, average of 5 readings digitalWrite(spikePin, LOW); if (moist <= irrigate) digitalWrite(pumpPin, level);// if empty a 'LOW' is written if (moist >= irrigate+5) digitalWrite(pumpPin, LOW); // prevents Jitter //-------------3. Read the DHT11 humidity/temp sensor----------------- // now we measure temperature and air humidity // READ DATA // Serial.print("DHT11, \t"); int chk = DHT.read11(DHT11_PIN); switch (chk) { case DHTLIB_OK: // Serial.print("OK,\t"); Unterbrechung; case DHTLIB_ERROR_CHECKSUM: Serial.print("Checksum error,\t"); Unterbrechung; case DHTLIB_ERROR_TIMEOUT: Serial.print("Time out error,\t"); Unterbrechung; default: Serial.print("Unknown error,\t"); Unterbrechung; } //-------------4. Read LDR ---------------------------------------- light=Map(LDRPin); /* ------------------Actions -------------------*/ //-------------5. DISPLAY DATA ------------------------------------ /* Display data on LCD */ push=digitalRead(PushButton); if (push==1) // pushbutton not pressed { lcd.clear(); lcd.setCursor(0, 0); //set cursor on first line (line 0) lcd.print("Temp. : "); lcd.print((float)DHT.temperature, 0); lcd.print (char(1)); // prints degree sign lcd.print("C"); lcd.print(" "); lcd.print (char(7)); lcd.setCursor(0,1); //set cursor on 2nd line lcd.print("Humidity: "); lcd.print((float)DHT.humidity, 0); lcd.print("%"); lcd.print(" "); Verzögerung (1000); // wait for one second and then print the soilmoisture lcd.setCursor(0,1); lcd.print ("Irr. Level: "); lcd.print(irrigate); lcd.setCursor(0,0); lcd.print("Moisture: "); lcd.print(moist); lcd.print(" "); } if (push==0) // pushbutton pressed { lcd.clear(); lcd.setCursor(0,0); lcd.print("licht: "); lcd.print(light); lcd.print(" "); lcd.setCursor(0,1); lcd.print("licht niv.: "); lcd.print(analogRead(LDRPin)); //buzz(1); } // ---------------5. Action on temperature ------ //if ((DHT.temperature,0) =<20) c=(DHT.temperature); if (c<=20) //Serial.println(c); {// switch on heating digitalWrite(hotPin,HIGH); } else { digitalWrite(hotPin,LOW); } //--------------6. Action on Humidity ----------- if (DHT.humidity >=50) { // zet ventilator aan digitalWrite(fanPin, HIGH); } else { digitalWrite(fanPin,LOW); } Verzögerung (1000); //end dht //end loop } //------- End of Main program----------- // //-------- Start of functions------------ int sample(int z) /* This function will read the Pin 'z' 5 times and take an average. Afterwards it will be mapped to 8 bits by dividing by 4 Could ofcourse immediately divided by 20 but this way it is easier to follow the program * / { byte i; int sval = 0; for (i = 0; i < 5; i++){ sval = sval + analogRead(z);// sensor on analog pin 'z' } //sval = sval / 5; // average //sval = sval / 4; // scale to 8 bits (0 - 255) sval=sval / 20; return sval; } //------------- Flash the backlight a number of times-------- void flash(byte y) { byte j; for (j=0; j<y;j++) { lcd.backlight(); delay(250); lcd.noBacklight(); delay(250); } lcd.backlight(); // finish with backlight on return; } // This function will sound the buzzer "u" times void buzz(byte u) { byte k; for (k=0; k<u;k++) { digitalWrite(buzPin, HIGH); delay(250); digitalWrite(buzPin, LOW); delay(250); } return; } // This function will blink an LED a number of times for a specific duration void ledblink(int times, int lengthms, int pinnum){ for (int x=0; x<times;x++){ digitalWrite(pinnum, HIGH); delay (lengthms); digitalWrite(pinnum, LOW); delay(lengthms); } } // This function maps the LDR reading into nrs 0-3 int Map(byte sens) { // read the sensor: int sensorReading = analogRead(sens); // map the sensor range to a range of four options: int range = map(sensorReading, sensorMin, sensorMax, 0, 3); // do something different depending on the // range value: switch (range) { case 0: // // Serial.println("dark"); lcd.backlight(); Unterbrechung; case 1: // // Serial.println("dim"); lcd.backlight(); Unterbrechung; case 2: // // Serial.println("medium"); lcd.noBacklight(); Unterbrechung; case 3: // // Serial.println("bright"); lcd.noBacklight(); Unterbrechung; } return range; }
You will find a slightly updated version of the sketch here
Step 17: Arduino for Greenhouse, Garden or Growbox: The Software: special characters
-
As I wanted a proper 'degree' character to use for Celsius (check yr LCD for character 123, perhaps that is suitable for you), I was in luck as the LCD allows for definition of 8 user characters. Decided to make an arrow as well as visual indication of an empty tank. With regard to the definition of characters for the LCD, that is simple to do with Malpartida's library On page http://custom-character.appspot.com/ you will find a 5x8 template that you can use to design your own characters. For the Arrow I designed, the pattern as follows (white segment is '0', black segment is '1'). With the help of a binary - hex converter, one can then find the hex equivalent of the binary number, but one can also directly send the binary number.
00100 -> 4
00100 -> 4
00100 -> 4
00100 -> 4
10101 -> 15
01110 -> E
00100 -> 4
00000 -> 0
Those binary numbers then can be send to the LCD with the help of the lcd.createChar function of the library. Of course one can also directly send the binary numbers
Step 18: Arduino for Greenhouse, Garden or Growbox: possible expansions
-
-Adding an RTC (DS1307) module will make the circuit more flexible and will simplify the software for eg switching on a lamp for a specified time as times can be set and determined much easier. The circuit shows an addition for an RTC and includes a led that can be set to flash every second. ofcourse that is only optional. Though it is quite simple to put together an RTC, I would advise against it as ready made RTC modules are very very cheap and look neat. probably cheaper than self built. (currently 2.83 USD/2.10 euro. the cost of the DS1307 is alread 2.95 euro, a crystal is 0.70 ct, a battery 50 cts, a battery holder 60cts, while the RTC I linked to also contains a 24C32 EEPROM that offers 32kbit=4kByte of space)
an even cheaper RTC module (€ 1.99) you find here . but even High precision DS3231 RTC boards are available at very low price ( currently Euro 1.94 )
Should you still want to build the RTC yourself, I enclosed a circuit, a picture and a stripboard layout. You don't need the EEPROM, just leave it out (and the 6 wire bridges connecting it)
In order to set the LED attached to the SQW to 1Hz, use the code below. the DS1307_ADDRESS=0x68 (usually)void sqw1() // set to 1Hz { Wire.beginTransmission(DS1307_ADDRESS); Wire.write(0x07); // move pointer to SQW address Wire.write(0x10); // sends 0x10 (hex) 00010000 (binary) Wire.endTransmission(); }
-Setting the threshold level for irrigation in the software with a button rather than with a variable resistor
-Adding various automated growth cycles to the program to chose from. Possibly stored in the EEPROM that comes with an RTC module).
-There is still an analogue port available. One could add an ntc to measure soil temperature, or a rain detector.
-Consider replacing the 4 solidstate relays by a ClickOn-ClickOff system that usually works on 433MHz, by adding a 433 MHz transmitter and sending the right codes. The 433 MHz transmitter only needs 1 pin, freeing up 3. Ofcourse this is only useful if you feed the heater, fan, pump, lights with 110 or 220 Volt
After building this, i decided that having the LCD on, even if only at low light levels, wasnt the right choice, so i added a switch to just switch it on and off. The I2C module i used for the LCD has a jumper to disconnect the backlight. A 2 pin female header attached to a switch will do that.
A better idea perhaps would be to add a proximity detector that switches on the LCD whenever someone comes close
Step 19: Updated software
I have updated the software slightly. It now uses symbols for temperature, humidity and pump use.
I have left the original software in place
NOTE: publishing a program somehow always leads to strange effects on this site and substantial manual editing was necessary. It is possible that that resulted in a mistake and he code wont run. If so, drop me a line and i will send the code/* ======================================================= Measures soil moisture. If less than a set value it switches the pump measures temperature. If less than a specific value (20 degrees) switch heating measures humidity. if above a certain humidity switch fan measure light... at yr disposal <a href="http://www.quickgrow.com/gardening_articles/fans_air_movement.html" rel="nofollow"> http://www.quickgrow.com/gardening_articles/fans_...</a> LCD commands: lcd.setBacklight(LED_OFF); lcd.noBacklight(); lcd.clear(); lcd.home(); ========================================================= */ //--------------------------------------- /*-----( Import needed libraries )-----*/ //--------------------------------------- #include <wire.h> #include <liquidcrystal_i2c.h> //Malpertida #include "RTClib.h" //Adafruit RTC_DS1307 rtc; #include <dht.h> //------------------------------- /*-----( Declare objects )-----*/ //------------------------------- // first the humidity sensor dht DHT; // ------ ( declare LCD data)------------------------- // set the LCD address to 0x27 for a 20 chars 4 line display // Set the pins on the I2C chip used for LCD connections: // addr, en,rw,rs,d4,d5,d6,d7,bl,blpol LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE); // Set the LCD I2C address // /*-----(Declare RTC objects )------*/ RTC_DS1307 RTC; //declare object // ------------------------- // >> pin definitions // ------------------------- // this is where you define what pins you'll be using</p><p>/*-----( Declare pins )------*/ //analogue pins byte moisturePin=0; //read soil mositure byte LDRPin=3;// analog pin for LDR</p><p>//digital pins byte levelPin= 1; //set level for irrigation byte humidPin=2; //Humidity sensor byte lightPin=5; //Switches on light byte fanPin=6; //Switches fan byte pumpPin =7; //Switches pump byte hotPin= 8; //Switches heater byte buzPin=9; //Switches buzzer byte emptyPin=10; //digital Pin10 guards waterlevel byte spikePin=12; //Digital Pin12 ->for intermittent switching of spike byte PushButton=4; // PushButton byte SwitchButton=3;// Make Switch #define DHT11_PIN humidPin</p><p>/* Variable setting */ // variables -placeholders for various readings byte push=0; // contains the state of the pushbutton byte sButton=0; // contains the state of the throw switch byte light; // contains the value for LDR reading byte pump=0; // contains the pump state unsigned int moist=0; // contains the soil moisture level unsigned int irrigate=0; // contains the set level for irrigation in case no potmeter byte level=0; // contains level of the waterlevel (HIGH or LOW) int c; // contains the temperature reading // Constants // these constants won't change: const int sensorMin = 40; // LDR minimum, discovered through experiment const int sensorMax = 1012; // LDR maximum, discovered through experiment</p><p>//---------------- Define Special Characters----------------- // Create a set of new characters // 0= // 1=degree sign // 2=termometer // 3=waterdrupp // 4=spikes // 5=pump // 6=up arrow // 7=down arrow const uint8_t charBitmap[][8] = { { 0xc, 0x12, 0x12, 0xc, 0, 0, 0, 0 } . { 0x6, 0x9, 0x9, 0x6, 0, 0, 0, 0 } . { B00100, B01010, B01010, B01110, B01110, B11111, B11111, B01110 } . { B00100, B00100, B01010, B01010, B10001, B10001, B10001, B01110 } . { B10001, B10001, B11111, B10001, B10001, B10001, B10001, B10001 } . { B01010, B00100, B00100, B00100, B11111, B11111, B11111 } . { 0x0, 0x4, 0xE, 0x15, 0x4, 0x4, 0x4, 0x0 } . { 0x4,0x4,0x4, 0x4, 0x15, 0xE,0x4,0x0 } }; /// -------- end creation-------------- //The following function, "setup", must always be present Leere setup () { Serial.begin(115200); //----RTC----- #ifdef AVR Wire.begin(); #else Wire1.begin(); // Shield I2C pins connect to alt I2C bus on Arduino Due #endif rtc.begin(); if (! rtc.isrunning()) { Serial.println("RTC is NOT running!"); // following line sets the RTC to the date & time this sketch was compiled rtc.adjust(DateTime(F(__DATE__), F(__TIME__))); // This line sets the RTC with an explicit date & time, for example to set // January 21, 2014 at 3am you would call: // rtc.adjust(DateTime(2014, 1, 21, 3, 0, 0)); } //----end rtc------- //----Set sqw to 1 Hz--- Wire.beginTransmission(0x68); Wire.write(0x07); //move pointer to SQW address Wire.write(0x10); // sends 0×10 (hex) 00010000 (binary) Wire.endTransmission(); //---end sqw----- pinMode(levelPin,INPUT); // set level pinMode(humidPin,INPUT); // measures humidity pinMode(emptyPin,INPUT); // measures reservoir //digitalWrite(emptyPin, HIGH); // turn on pullup resistors pinMode(SwitchButton, INPUT); // make Switch pinMode(PushButton, INPUT); // PushButton pinMode(spikePin,OUTPUT); // for alternative supply to spikes pinMode(pumpPin,OUTPUT); // Output for Relay pinMode(fanPin, OUTPUT); // Output for fan pinMode(hotPin, OUTPUT); // Output for heater pinMode(lightPin, OUTPUT);// Output for light pinMode(buzPin, OUTPUT); // Output for buzzer digitalWrite(pumpPin, LOW);// Pump off digitalWrite(spikePin, LOW);// moisture sensor off digitalWrite(fanPin,LOW); // fan Off digitalWrite(hotPin,LOW); // heater off digitalWrite(lightPin, LOW); // light Off digitalWrite(buzPin, LOW); // buzzer off /* Now LCD */ //---------------Set up LCD------------------ lcd.begin(16,2); // initialize the lcd for 20 chars 4 lines, turn on backlight //upload defined characters to LCD int charBitmapSize = (sizeof(charBitmap ) / sizeof (charBitmap[0])); for ( int i = 0; i < charBitmapSize; i++ ) { lcd.createChar ( i, (uint8_t *)charBitmap[i] ); } //---------------end upload---------------- lcd.backlight(); // Print a message to the LCD. lcd.setCursor(0, 0); lcd.print("Greenhouse"); // ------- Quick 2 blinks of backlight ------------- flash(2); // ------- Quick buzz-------------------------------- buzz(1); Wire.begin(); //needed for RTC, not for LCD RTC.begin(); /* Set the date / time to the time this program was compiled. Comment this OUT, AND upload, to let the clock just run. * / // RTC.adjust(DateTime(__DATE__, __TIME__)); } /*----------------------------(end setup )---------------------*/ Leere Schleife () { DateTime now = rtc.now(); //Get the current data Serial.print("Het jaar is "); Serial.print(now.year(), DEC); Serial.print(" Maand = "); Serial.print(now.month(), DEC); Serial.print(" Dag = "); Serial.print(now.day(), DEC); Serial.print(" Tijd = "); Serial.print(now.hour(), DEC); Serial.print(':'); Serial.print(now.minute(), DEC); Serial.print(':'); Serial.print(now.second(), DEC); Serial.println(); //------------end of RTC // ---------- 1. Check if there is enough water ------------- // check if there is water // if not sound the buzzer // later in the program the pump will be disabled level= digitalRead(emptyPin);//Switch closed = empty if (level==0) { digitalWrite(buzPin, HIGH); delay (50); digitalWrite(buzPin, LOW); delay(500); } //------------2. Read the soil moisture content/switch pump---------------- /* First read the level set with P1 on the levelPin and store that in 'irrigate' * / irrigate=sample(levelPin); /* Then we read the soil humidity sensor. We'll first have to set the spikePin to HIGH, in case that is used to feed the sensor. After the reading we set it back) If the value read ('moist') is smaller than what is considered dry ('irrigate') then the pump should be switched on for a specific time. This is done by indicating a higher treshhold for switching the pump off * / digitalWrite(spikePin, HIGH);// put voltage on the humidity sensor delay(100); //wait a short while moist=sample(moisturePin); //read soil humiditySensor // digitalWrite(spikePin, LOW); if (moist <= irrigate){ pump=1; digitalWrite(pumpPin, level); // if the reservoir is empty a 0 will be written } if (moist >= irrigate+5) { pump=0; digitalWrite(pumpPin, LOW); // prevents Jitter } //-------------3. Read the DHT11 humidity/temp sensor----------------- // now we measure temperature and air humidity // READ DATA // Serial.print("DHT11, \t"); int chk = DHT.read11(DHT11_PIN); switch (chk) { case DHTLIB_OK: // Serial.print("OK,\t"); Unterbrechung; case DHTLIB_ERROR_CHECKSUM: Serial.print("Checksum error,\t"); Unterbrechung; case DHTLIB_ERROR_TIMEOUT: Serial.print("Time out error,\t"); Unterbrechung; default: Serial.print("Unknown error,\t"); Unterbrechung; } //-------------4. Read LDR ---------------------------------------- light=Map(LDRPin); /* ------------------Actions -------------------*/ //-------------5. DISPLAY DATA ------------------------------------ /* Display data on LCD */ push=digitalRead(PushButton); if (push==1) // pushbutton not pressed { lcd.clear(); lcd.setCursor(0, 0); //set cursor on first line (line 0) lcd.print(char(2)); //prints thermometer lcd.print(" "); lcd.print((float)DHT.temperature, 0); lcd.print (char(1)); // prints degree sign lcd.print("C"); lcd.print(" "); lcd.print(char(3));// droplet lcd.print(" "); lcd.print((float)DHT.humidity, 0); lcd.print("%"); lcd.print(" "); lcd.print (char(7-level));//prints up or down arrow (char 7 or 6) if(level+pump==2){ lcd.print(" "); lcd.print(char(5)); } else { lcd.print(" ");} lcd.setCursor(0,1); lcd.print(char(4)); // spikes lcd.print(" "); lcd.print(moist); lcd.print("/"); lcd.print(irrigate); } if (push==0) // pushbutton pressed { lcd.clear(); lcd.setCursor(0,0); //lcd.print("licht: "); //lcd.print(light); //-------------- DateTime now = rtc.now(); lcd.print(now.year(), DEC); lcd.print('/'); lcd.print(now.month(), DEC); lcd.print('/'); lcd.print(now.day(), DEC); //----------- lcd.print(" "); lcd.setCursor(0,1); lcd.print("licht niv.: "); lcd.print(analogRead(LDRPin)); //buzz(1); } // ---------------5. Action on temperature ------ c=(DHT.temperature); if (c<=19) { // switch on heating digitalWrite(hotPin,HIGH); } else { digitalWrite(hotPin,LOW); } //--------------6. Action on Humidity ----------- if (DHT.humidity >=50) { // zet ventilator aan digitalWrite(fanPin, HIGH); } else { digitalWrite(fanPin,LOW); } delay(1000); //end dht //end loop } //------- End of Main program----------- // //-------- Start of functions------------ int sample(int z) /* This function will read the Pin 'z' 5 times and take an average. Afterwards it will be mapped to 8 bits by dividing by 4 Could ofcourse immediately divided by 20 but this way it is easier to follow the program * / { byte i; int sval = 0; for (i = 0; i < 5; i++){ sval = sval + analogRead(z);// sensor on analog pin 'z' } //sval = sval / 5; // average //sval = sval / 4; // scale to 8 bits (0 - 255) sval=sval / 20; return sval; } //------------- Flash the backlight a number of times-------- void flash(byte y) { byte j; for (j=0; j<y;j++) { lcd.backlight(); delay(250); lcd.nobacklight(); } //finish with backlight on= return; //this function will sound the buzzer "u" times void buzz(byte u) byte k; for=(k=0; k<u;k++) digitalwrite(buzpin, high); delay(200); digitalWrite(buzPin, LOW); delay(200); } return; } // This function will blink an LED a number of times for a specific duration void ledblink(int times, int lengthms, int pinnum){ for (int x=0; x<times;x++){ digitalWrite(pinnum, HIGH); delay (lengthms); digitalWrite(pinnum, LOW); delay(lengthms); } } // This function maps the LDR reading into nrs 0-3 int Map(byte sens) { // read the sensor: int sensorReading = analogRead(sens); // map the sensor range to a range of four options: int range = map(sensorReading, sensorMin, sensorMax, 0, 3); // do something different depending on the // range value: switch (range) { case 0: // // Serial.println("dark"); // lcd.backlight(); Unterbrechung; case 1: // // Serial.println("dim"); // lcd.backlight(); Unterbrechung; case 2: // // Serial.println("medium"); // lcd.noBacklight(); Unterbrechung; case 3: // // Serial.println("bright"); // lcd.noBacklight(); Unterbrechung; } return range; } void printDigits(int digits) { //this adds a 0 before single digit numbers //if (digits >= 0 && digits < 10) { if (digits <10) { lcd.write('0'); } lcd.print(digits); }float tempConvert(float celsius) { float fahrenheit = 0; fahrenheit = (1.8 * celsius) + 32; return fahrenheit; }
Step 20: Using timers to read sensors
It is not necessary to continuously read the sensor(s). Especially if it is the soil humidity sensor, it is a good idea to only read that one at intervals, because that will limit the amount of DC flowing through the pins and thus slow down corrosion.
Rather than using delays, it is possible to use a timer interrupt.
In the example below the prescaler for timer 1 is set to overflow every second. The timer compare interrupt will count the seconds till 10 and then read the sensor. Read up on use of timers here .// avr-libc library includes #include <avr/io.h> #include <avr/interrupt.h> int seconds=0; Leere setup () { pinMode(LEDPIN, OUTPUT); // initialize Timer1 cli(); // disable global interrupts TCCR1A = 0; // set entire TCCR1A register to 0 TCCR1B = 0; // same for TCCR1B // set compare match register to desired timer count: OCR1A = 15624; // turn on CTC mode: TCCR1B |= (1 << WGM12); // Set CS10 and CS12 bits for 1024 prescaler: TCCR1B |= (1 << CS10); TCCR1B |= (1 << CS12); // enable timer compare interrupt: TIMSK1 |= (1 << OCIE1A); sei(); // enable global interrupts } ISR(TIMER1_COMPA_vect) { seconds++; if(seconds == 10) { seconds = 0; readSensor; } } Leere Schleife () { //other stuff }
Keep in mind though that if you would set a timer such that your soilhumidity would be read every 10 minutes, that if there is need to switch the pump on, you need to read the soil humidity constantly, otherwise your pump will flow for at least 10 minutes, before another reading is taken. That may be too much water.