#Developed by JJ Slabbert for the PiSiphon Rain Gauge, Part of the raspberry pi open weather station.
#Python 2.7 used for testing.
#This application is used to check if the probes pick up rain and if the siphoning action works after the measuring cylinder is full.

#Probe Pairs:
#Probe Pair 1 (lowest water level), Pin 26 and 20)
#Probe Pair 2, Pin 19 and 16
#Probe Pair 3, Pin 6 and 12
#Probe Pair 4, Pin 0 and 1
#Probe Pair 5, Pin 11 and 8

#Althought gpiozero is very usefull, the number of times that a pin can be re-used (switch between input and output, using the close() function), is limited.
#It seems like a new thread is generated by gpiozeroo, each time the the pins are switch between input/output.
#To prevent the above proble, the RPi.GPIO module will be used instead of gpiozero.

#WARNING: Electricity is dangerous. Water and high voltage/current should always be avoided. The rasperri pi use low voltage and current, making this project save.

import time
import RPi.GPIO as GPIO


print("Probe and Siphoning testing algorithm for PiSiphon Rain Gauge.")
print("Add artificial rain to see if probes are detecting rain.")
print("00000 means no probes detects rain.")
print("00001 means the lowest Probe (p1) detects rain, ......11111 means all probes (p1-p5) detects rain.")
print("Also test if the siphon action works when the measuring cylinder is full. After siphoning, the probe status should return to 00000.")
n=0.0 #Loop counter to determine even and odd alterations of the loop
while True:
    GPIO.setmode(GPIO.BCM)
    n=n+1
    if n/2==int(n/2): #Case for even n. The direction of current is changed on each alteration of the loop to reduce electrolysis        
        GPIO.setup(26,GPIO.OUT)
        GPIO.output(26, GPIO.HIGH)
        GPIO.setup(19,GPIO.OUT)
        GPIO.output(19, GPIO.HIGH)
        GPIO.setup(6,GPIO.OUT)
        GPIO.output(6, GPIO.HIGH)
        GPIO.setup(0,GPIO.OUT)
        GPIO.output(0, GPIO.HIGH)
        GPIO.setup(11,GPIO.OUT)
        GPIO.output(11, GPIO.HIGH)

        GPIO.setup(20,GPIO.IN,GPIO.PUD_DOWN)
        GPIO.setup(16,GPIO.IN,GPIO.PUD_DOWN)
        GPIO.setup(12,GPIO.IN,GPIO.PUD_DOWN)
        GPIO.setup(1,GPIO.IN,GPIO.PUD_DOWN)
        GPIO.setup(8,GPIO.IN,GPIO.PUD_DOWN)
        
        p1=GPIO.input(20)
        p2=GPIO.input(16)
        p3=GPIO.input(12)
        p4=GPIO.input(1)
        p5=GPIO.input(8)        
    else: #Case for odd n. The direction of current is changed on each alteration of the loop to reduce electrolysis        
        GPIO.setup(20,GPIO.OUT)
        GPIO.output(20, GPIO.HIGH)
        GPIO.setup(16,GPIO.OUT)
        GPIO.output(16, GPIO.HIGH)
        GPIO.setup(12,GPIO.OUT)
        GPIO.output(12, GPIO.HIGH)
        GPIO.setup(1,GPIO.OUT)
        GPIO.output(1, GPIO.HIGH)
        GPIO.setup(8,GPIO.OUT)
        GPIO.output(8, GPIO.HIGH)

        GPIO.setup(26,GPIO.IN,GPIO.PUD_DOWN)
        GPIO.setup(19,GPIO.IN,GPIO.PUD_DOWN)
        GPIO.setup(6,GPIO.IN,GPIO.PUD_DOWN)
        GPIO.setup(0,GPIO.IN,GPIO.PUD_DOWN)
        GPIO.setup(11,GPIO.IN,GPIO.PUD_DOWN)
        
        p1=GPIO.input(26)
        p2=GPIO.input(19)
        p3=GPIO.input(6)
        p4=GPIO.input(0)
        p5=GPIO.input(11)

    GPIO.cleanup() #Cleanup is needed to switch input/output (direction of current) pins
    status_bin=str(p5)+str(p4)+str(p3)+str(p2)+str(p1)
    print(status_bin)
    if n==10000: # prevent n from taking up to much memory. My experience: "python can create memory leaks"
        n=0
    time.sleep(5)
