Hallo Liebe Raspi's,
ich bin ein kompletter Neuling bezüglich Raspi und Python, mit Programmierung hatte ich bisher nichts am Hut (ausser mal einen Batch-File für Windoof)
Ich habe folgendes Problem für meine Gartenbewässerung (zu diesem Thema hab ich schon einiges gelesen, aber nichts hat mir so richtig weitergeholfen):
An/von einem 8 Kanal Relaisboard (die GPIO's schalten schon) sollen Bewässerungsventile Zeitgesteuert ein- und ausgeschaltet werden. (GPIO_an_Relais.py)
#!/usr/bi/python
# -*- coding: utf-8 -*-
# Name: GPIO_an_Relais.py
# Zweck: Die 8 Relais über GPIO's ansteuern.
#gelb = GPIO 12 = Relays 01
#braun = GPIO 13 = Relays 02
#weiß = GPIO 19 = Relais 03
#blau = GPIO 21 = Relays 04
#lila = GPIO 22 = Relays 05
#grau= GPIO 23 = Relays 06
#grün = GPIO 26 = Relays 07
#orange = GPIO 27 = Relays 08
import RPi.GPIO as GPIO
import time
GPIO.setmode(GPIO.BCM)
GPIO.setwarnings(False)
#GPIO.setup(12, GPIO.OUT)
#GPIO.setup(13, GPIO.OUT)
#GPIO.setup(19, GPIO.OUT)
#GPIO.setup(21, GPIO.OUT)
#GPIO.setup(22, GPIO.OUT)
#GPIO.setup(23, GPIO.OUT)
#GPIO.setup(26, GPIO.OUT)
#GPIO.setup(27, GPIO.OUT)
#GPIO.output(12, GPIO.LOW)
#GPIO.output(13, GPIO.LOW)
#GPIO.output(19, GPIO.LOW)
#GPIO.output(21, GPIO.LOW)
#GPIO.output(22, GPIO.LOW)
#GPIO.output(23, GPIO.LOW)
#GPIO.output(26, GPIO.LOW)
#GPIO.output(27, GPIO.LOW)
#GPIO.output(12, GPIO.HIGH)
#GPIO.output(13, GPIO.HIGH)
#GPIO.output(19, GPIO.HIGH)
#GPIO.output(21, GPIO.HIGH)
#GPIO.output(22, GPIO.HIGH)
#GPIO.output(23, GPIO.HIGH)
#GPIO.output(26, GPIO.HIGH)
#GPIO.output(27, GPIO.HIGH)
# Relais 1
GPIO.setup(12, GPIO.OUT)
GPIO.output(12, GPIO.HIGH)
GPIO.output(12, GPIO.LOW)
time.sleep(15)
GPIO.output(12, GPIO.HIGH)
time.sleep(15)
GPIO.cleanup(12)
# Relais 2
GPIO.setup(13, GPIO.OUT)
GPIO.output(13, GPIO.HIGH)
GPIO.output(13, GPIO.LOW)
time.sleep(15)
GPIO.output(13, GPIO.HIGH)
time.sleep(15)
GPIO.cleanup(13)
# Relais 3
GPIO.setup(19, GPIO.OUT)
GPIO.output(19, GPIO.HIGH)
GPIO.output(19, GPIO.LOW)
time.sleep(15)
GPIO.output(19, GPIO.HIGH)
time.sleep(15)
GPIO.cleanup(19)
# Relais 4
GPIO.setup(21, GPIO.OUT)
GPIO.output(21, GPIO.HIGH)
GPIO.output(21, GPIO.LOW)
time.sleep(15)
GPIO.output(21, GPIO.HIGH)
time.sleep(15)
GPIO.cleanup(21)
# Relais 5
GPIO.setup(22, GPIO.OUT)
GPIO.output(22, GPIO.HIGH)
GPIO.output(22, GPIO.LOW)
time.sleep(15)
GPIO.output(22, GPIO.HIGH)
time.sleep(15)
GPIO.cleanup(22)
# Relais 6
GPIO.setup(23, GPIO.OUT)
GPIO.output(23, GPIO.HIGH)
GPIO.output(23, GPIO.LOW)
time.sleep(15)
GPIO.output(23, GPIO.HIGH)
time.sleep(15)
GPIO.cleanup(23)
# Relais 7
GPIO.setup(26, GPIO.OUT)
GPIO.output(26, GPIO.HIGH)
GPIO.output(26, GPIO.LOW)
time.sleep(15)
GPIO.output(26, GPIO.HIGH)
time.sleep(15)
GPIO.cleanup(26)
# Relais 8
GPIO.setup(27, GPIO.OUT)
GPIO.output(27, GPIO.HIGH)
GPIO.output(27, GPIO.LOW)
time.sleep(15)
GPIO.output(27, GPIO.HIGH)
time.sleep(15)
GPIO.cleanup(27)
GPIO.cleanup()
print("Abbruch")
#gelb = GPIO 12 = Relays 01
#braun = GPIO 13 = Relays 02
#weiß = GPIO 19 = Relais 03
#blau = GPIO 21 = Relays 04
#lila = GPIO 22 = Relays 05
#grau= GPIO 23 = Relays 06
#grün = GPIO 26 = Relays 07
#orange = GPIO 27 = Relays 08
Display More
Zudem soll die Bodenfeuchte kapazitiv gemessen werden - auch der Sensor liefert schon Werte (get_hum.py)
# Simple demo of continuous ADC conversion mode for channel 0 of the ADS1x15 ADC
# with the comparator enabled.
# Script um ADS11x5 zu installieren:
#sudo apt-get update
#sudo apt-get install build-essential python-dev python-smbus git
#cd ~
#git clone https://github.com/adafruit/Adafruit_Python_ADS1x15.git
#cd Adafruit_Python_ADS1x15
#sudo python setup.py install
import time
# Import the ADS1x15 module.
import Adafruit_ADS1x15
# Create an ADS1115 ADC (16-bit) instance.
adc = Adafruit_ADS1x15.ADS1115()
# Or create an ADS1015 ADC (12-bit) instance.
#adc = Adafruit_ADS1x15.ADS1015()
# Note you can change the I2C address from its default (0x48), and/or the I2C
# bus by passing in these optional parameters:
#adc = Adafruit_ADS1x15.ADS1015(address=0x49, busnum=1)
# Choose a gain of 1 for reading voltages from 0 to 4.09V.
# Or pick a different gain to change the range of voltages that are read:
# - 2/3 = +/-6.144V
# - 1 = +/-4.096V
# - 2 = +/-2.048V
# - 4 = +/-1.024V
# - 8 = +/-0.512V
# - 16 = +/-0.256V
# See table 3 in the ADS1015/ADS1115 datasheet for more info on gain.
GAIN = 1
# Start continuous ADC conversions on channel 0 using the previously set gain
# value, and with the comparator enabled. See the comparator section of the
# datasheet for information on what the comparator does, but at a high level
# the comparator can trigger the ALERT pin when an ADC value falls within
# (or outside) a provided threshold range. The comparator can be configured with
# these parameters:
# - active_low: Boolean that indicates if ALERT is pulled low or high
# when active/triggered. Default is true, active low.
# - traditional: Boolean that indicates if the comparator is in traditional
# mode where it fires when the value is within the threshold,
# or in window mode where it fires when the value is _outside_
# the threshold range. Default is true, traditional mode.
# - latching: Boolean that indicates if the alert should be held until
# get_last_result() is called to read the value and clear
# the alert. Default is false, non-latching.
# - num_readings: The number of readings that match the comparator before
# triggering the alert. Can be 1, 2, or 4. Default is 1.
# The call below will enable the comparator with its defaults and a threshold
# range of 5000-20000. This means if the ADC value falls within 5000-20000 the
# ALERT pin will briefly be pulled low.
# Note you can also pass an optional data_rate parameter, see the simpletest.py
# example and read_adc function for more infromation.
adc.start_adc_comparator(0, # Channel number
20000, 5000, # High threshold value, low threshold value
active_low=True, traditional=True, latching=False,
num_readings=1, gain=GAIN)
# Once continuous ADC conversions are started you can call get_last_result() to
# retrieve the latest result, or stop_adc() to stop conversions.
# Note you can also call start_adc_difference_comparator() to take continuous
# differential readings with comparator enabled. See the read_adc_difference()
# function in differential.py for more information and parameter description.
# Read channel 0 with comparator for 5 seconds and print out its values.
print('Reading ADS1x15 channel 0 for 60 seconds with comparator...')
start = time.time()
while (time.time() - start) <= 60.0:
# Read the last ADC conversion value and print it out.
value = adc.get_last_result()
# WARNING! If you try to read any other ADC channel during this continuous
# conversion (like by calling read_adc again) it will disable the
# continuous conversion!
print('Channel 0: {0}'.format(value))
# Sleep for half a second.
time.sleep(2.0)
# Stop continuous conversion. After this point you can't get data from get_last_result!
#adc.stop_adc()
Display More
Dann noch die Temperatur - auch die funktioniert schon (get_temp.py
import time
from read_temp import DS18B20
degree_sign = u'\xb0' # degree sign
devices = DS18B20()
count = devices.device_count()
names = devices.device_names()
print('[press ctrl+c to end the script]')
try: # Main program loop
while True:
i = 0
print('\nReading temperature, number of sensors: {}'
.format(count))
while i < count:
container = devices.tempC(i)
print('{}. Temp: {:.3f}{}C, {:.3f}{}F of the device {}'
.format(i+1, container, degree_sign,
container * 9.0 / 5.0 + 32.0, degree_sign,
names[i]))
i = i + 1
time.sleep(1)
# Scavenging work after the end of the program
except KeyboardInterrupt:
print('Script end!')
Display More
und read_temp.py)
import os
import glob
import time
class DS18B20:
def __init__(self):
os.system('modprobe w1-gpio')
os.system('modprobe w1-therm')
base_dir = '/sys/bus/w1/devices/'
device_folder = glob.glob(base_dir + '28*')
self._count_devices = len(device_folder)
self._devices = list()
i = 0
while i < self._count_devices:
self._devices.append(device_folder[i] + '/w1_slave')
i += 1
def device_names(self):
names = list()
for i in range(self._count_devices):
names.append(self._devices[i])
temp = names[i][20:35]
names[i] = temp
return names
# (one tab)
def _read_temp(self, index):
f = open(self._devices[index], 'r')
lines = f.readlines()
f.close()
return lines
def tempC(self, index = 0):
lines = self._read_temp(index)
retries = 5
while (lines[0].strip()[-3:] != 'YES') and (retries > 0):
time.sleep(0.1)
lines = self._read_temp(index)
retries -= 1
if retries == 0:
return 998
equals_pos = lines[1].find('t=')
if equals_pos != -1:
temp = lines[1][equals_pos + 2:]
return float(temp) / 1000
else:
return 999 # error
def device_count(self):
return self._count_devices
Display More
Bisher hab ich für die Relaissteuerung ein*.py geschrieben (bzw. Kopiert), ebenso für Bodenfeuchte und Temperatur (siehe Dateianhänge)
Ich dachte mir, so ist es für den Anfang mal einfacher, um zu sehen, ob die Scripte auch laufen, bzw. den Fehler besser eingrenzen zu können).
Später will ich sie dann zusammenkopieren, bzw. - wenn das geht im Hauptscript sozusagen zu "verlinken", da ich ja jeweils nur den aktuellen Messwert (Temperatur, bzw. Bodenfeuchte) brauche (müsste ja mit "import" gehen ...?)
Jetzt gehts aber um die Abhängigkeiten, zum einen sollen 4 Ventile jeweils zu einer bestimmten Zeit ein, bzw. ausgeschaltet werden:
Ventil 1 An 3:00 Uhr, Aus 3:20 Uhr,
Ventil 2 An 3:40 Uhr, Aus 4:00 Uhr,
Ventil 3 An 4:20 Uhr, Aus 4:40 Uhr,
Ventil 4 An 8:00 Uhr, Aus 8:20 Uhr,
Ventil 1 An 5:00 Uhr, Aus 5:20 Uhr,
Ventil 2 An 5:40 Uhr, Aus 6:00, Uhr,
Ventil 3 An 6:20 Uhr, Aus 6:40 Uhr,
Ventil 4 An 12:00 Uhr, Aus 12:20 Uhr,
Ventil 4 An 17:00 Uhr, Aus 17:20 Uhr.
(Die 20 min Pause dienen nur zu Regeneration meines Gartenbrunnens - bin nicht tief genug mit dem Bohren gekommen und hab nur 1,5 m Wasserüberstand über der Pumpe, aber das reicht für 20 min Bewässerung)
Das wäre mal Punkt 1, ich bekomme es einfach nicht hin, Python davon zu überzeugen, dass die Ventile/Relais/GPIO's jeden Tag zu gegebenen Uhrzeiten öffnen bzw. schließen.
... das ist aber bei weitem noch nicht alles:
Logischerweise sollen die Ventile 1 -3 nur dann ihre Arbeit tun, wenn es nicht regnet, bzw. der Rasen nicht feucht genug ist, deshalb der Bodenfeuchtemesser (das geht ja irgendwie mit if/else ...?)
... ja und dann ist da ja noch der Winter:
Hier soll sich das ganze System Automatisch in den Winterschlaf begeben, d.h. sinkt die gemessene Außentemperatur unter 0 Grad, sollen sich Ventile 5 und 6 öffnen um die Wasserleitung zu entleeren (Ventil 5 ist am tiefsten Punkt des Wasserkreislaufs, Ventil 6 an höchsten Punkt) zusätzlich sollen dann auch die Ventile 1 - 4 auch für 10 min öffnen, um auch hier die Leitungen zumindest Drucklos zu machen.
Auch die Pumpe sollte dann elektrisch "AUS" sein, da sie über einen Druckschalter angesteuert wird, gibt es da einen Schalter, den ich über ein Relais ansteuern kann?
Und weils noch nicht genug ist, habe ich mir jetzt auch noch einen Durchflussmesser gekauft (AS010 – Vortex-Durchflusssensor G1 ¼ - 9…150 l/min – analog 4…20 mA) den ich evtl. auch noch - rein zu Messzwecken - damit ich sehe, wieviel Wasser ich verballere - anbinden.
Müsste ja wie beim Bodenfeuchtesensor über einen AD Wandler (ich hab einen ADS1150 von QRobot) funktionieren?
Kann mir da jemand einfache Tipps geben, wie ich das hinbekomme?
... und wie schon geschrieben, ich habs mir wirklich nicht einfach gemacht und Tante Google lange genervt, um zu meinem Problem ein Lösung im Internet zu finden.
Ich würde mich wirklich über konstruktive Antworten freuen.
Ach ja, die Hardware ist schon komplett installiert, falls jemand interesse hat, ich hab sie gut "Bebildert"
LG
Andreas