Moisture detection not resetting - python

I have a friend setting up an irrigation system at his house. He is telling me it won't detect moisture after the first run-through, regardless of whether there is moisture or not. In his own words:
"I’m trying to figure out how to make my program restarts the detection process. Like say my sensor is in soil and it detects water then after a certain period I need it to run again. My problems is that when I run it again and it’s sitting in a cup of water, it’s doesn’t detect the water. I read something about maybe checking the state of the sensor but I couldn’t get anywhere.
Also would I would the delay function to continuously run it in intervals."
He sent me his code today, and I would like to help him, although I am new to Python. Here is the code.
#!/usr/bin/python
import RPi.GPIO as GPIO
import time
#GPIO SETUP
channel = 20
GPIO.setmode(GPIO.BCM)
GPIO.setup(channel, GPIO.IN)
def callback(channel):
if GPIO.input(channel)==0:
print (" Water Detected!")
else:
print ( 'NO Water Detected!')
GPIO.add_event_detect(channel, GPIO.FALLING, bouncetime=300) # let us know when the pin goes HIGH or LOW
GPIO.add_event_callback(channel, callback) # assign function to GPIO PIN, Run function on change
# infinite loop
while True:
time.sleep(1)
import RPi.GPIO as GPIO # Import Raspberry Pi GPIO library
from time import sleep # Import the sleep function from the time module
GPIO.setwarnings(False) # Ignore warning for now
GPIO.setmode(GPIO.BOARD) # Use physical pin numbering
GPIO.setup(3, GPIO.OUT, initial=GPIO.LOW) # Set pin 8 to be an outputpin and set initial value to low (off)
while True: # Run forever
GPIO.output(3, GPIO.HIGH) # Turn on
sleep(1) # Sleep for 1 second
GPIO.output(3, GPIO.LOW) # Turn off
sleep(1) # Sleep for 1 second

Related

rotary encoder script for raspberry pi using python

I have a setup in which I have a motor turning a 5cm diameter shaft at about 1 revolution a second. I need to stop the motor after a predetermined number of revolutions - lets say 10 for now.
The sensor mechanism I am using is simply a magnet and reed switch. The following script works well to record each time the switch is triggered.
import RPi.GPIO as GPIO
GPIO.setmode(GPIO.BOARD)
button1=22
GPIO.setup(button1,GPIO.IN,pull_up_down=GPIO.PUD_UP)
while(1):
if GPIO.input(button1)==0:
print "Button 1 Pressed"
sleep(0.5)
Whilst this script runs the motor -
import RPi.GPIO as GPIO
from time import sleep
GPIO.setmode(GPIO.BOARD)
Motor1A = 19
Motor1B = 21
Motor1E = 23
GPIO.setup(Motor1A,GPIO.OUT)
GPIO.setup(Motor1B,GPIO.OUT)
GPIO.setup(Motor1E,GPIO.OUT)
print "Going forwards"
GPIO.output(Motor1A,GPIO.LOW)
GPIO.output(Motor1B,GPIO.HIGH)
GPIO.output(Motor1E,GPIO.HIGH)
GPIO.cleanup()
In a nutshell then what I am seeking is a combined script which counts the number of event inputs on pin 22 and then turns pin 23 (the motor enable pin) to LOW on the count of 10.
Many thanks
Nick

Raspberry Pi Interrupts Python (GPIO Library)

I have a little problem with my little raspberry project, I have hooked up an LCD screen and a bunch of buttons to it, from my university course about micro-controllers I've learned that interrupts always trigger, no matter where the code is (but it was an actual microprocessor written in C). I found an "equivalent" in python, GPIO library. Normally a program is in a infinite loop waiting for an interrupt.
GPIO.add_event_detect(4, GPIO.RISING, callback=interrupt, bouncetime=200)
I set them up this way, they all go to the same method and check which button was pressed and run another method that I want (e.g one is for displaying time, another for IP address etc). A thing is, one of those methods I've done is in an infinite loop that another button press should break, but from this point a method
while not GPIO.event_detected(4):
doesn't work (calling this method in any other doesn't either if its in this loop, and all other button that I have set up will not react at all too), if it was my default while loop it does tho. I don't have much experience in either micro-controllers and python, its just hobby thing at the moment. If needed I'll share my entire code but I think its quite tangled.
Ok I am providing a simplified example, same same thing happens as in my original code. After an interrupt happens, buttons will not react, doesn't matter if I use while not GPIO.event_detected(19) or GPIO.add_event_callback(26, callback=second_interrupt).
import RPi.GPIO as GPIO
import time
GPIO.setmode(GPIO.BCM)
GPIO.setup(26, GPIO.IN, pull_up_down=GPIO.PUD_UP) # Button 1
GPIO.setup(19, GPIO.IN, pull_up_down=GPIO.PUD_UP) # Button 2
def interrupt(channel):
print "interrupt"
if channel == 26:
print "in loop"
GPIO.add_event_callback(26, callback=second_interrupt) #Trying to use this won't trigger second interrupt
while not GPIO.event_detected(19): #and this wont ever trigger
time.sleep(1)
print "inside loop"
def second_interrupt():
print "second interrupt"
GPIO.add_event_detect(26, GPIO.RISING, callback=interrupt, bouncetime=200) # add rising edge detection on a channel
GPIO.add_event_detect(19, GPIO.RISING, callback=interrupt, bouncetime=200) # add rising edge detection on a channel
while (True):
time.sleep(1)
if GPIO.event_detected(19): #this version works if I wont enter an interrupt first
second_interrupt()
There are several things going on in your code. I suspect that what's really causing the problem is that you need to exit the interrupt handler before another interrupt callback can be triggered...but there is also a confusing mix of callback-based handlers and the GPIO.event_detected method.
I think you can simplify things by performing less manipulation of your interrupt configuration. Just have a state variable that starts at 0, increment it to 1 on the first interrupt, so the next time the interrupt method is called you know it's the second interrupt. No need to try setting multiple handlers like that.
Keeping in mind that I don't actually know what you're trying to do...I imagine something like this:
import RPi.GPIO as GPIO
import time
state = 0
GPIO.setmode(GPIO.BCM)
GPIO.setup(26, GPIO.IN, pull_up_down=GPIO.PUD_UP)
GPIO.setup(19, GPIO.IN, pull_up_down=GPIO.PUD_UP)
def interrupt_handler(channel):
global state
print("interrupt handler")
if channel == 19:
if state == 1:
state = 0
print("state reset by event on pin 19")
elif channel == 26:
if state == 0:
state = 1
print("state set by event on pin 26")
GPIO.add_event_detect(26, GPIO.RISING,
callback=interrupt_handler,
bouncetime=200)
GPIO.add_event_detect(19, GPIO.RISING,
callback=interrupt_handler,
bouncetime=200)
while (True):
time.sleep(0)

How can keep a timed count of user input (from a button)?

I'm using a Raspberry Pi 2 and a breadboard to make a morse code interpreter. The circuit is a simple button that lights up an LED when pressed. How could I use functions to count how long the button is held down?
You haven't given sufficient details of your circuit to pin this down to your particular use case, so I'll suggest the following (on which I'll base my code):
Connect the LED (with series resistor) to GPIO 12
Connect a 10k resistor between GPIO 11 and the 3.3V rail (acts as a pull-up)
Connect the push-button between GPIO 11 and Ground (0V).
I'd then write the code to monitor the pin and log the time for each press into a list. You can read out the values in the same order which allows you to process the times and interpret the code from them.
import RPi.GPIO as GPIO
import time
# set up an empty list for the key presses
presses = []
# set up the GPIO pins to register the presses and control the LED
GPIO.setmode(GPIO.BOARD)
GPIO.setup(12, GPIO.OUT)
GPIO.setup(11, GPIO.IN)
# turn LED off initially
GPIO.output(12, False)
while True:
# wait for input to go 'low'
input_value = GPIO.input(11)
if not input_value:
# log start time and light the LED
start_time = time.time()
GPIO.output(12, True)
# wait for input to go high again
while not input_value:
input_value = GPIO.input(11)
else:
# log the time the button is un-pressed, and extinguish LED
end_time = time.time()
GPIO.output(12, False)
# store the press times in the list, as a dictionary object
presses.append({'start':start_time, 'end':end_time})
You'll finish up with a list that looks something like this:
[{start:123234234.34534, end:123234240.23482}, {start:123234289.96841, end:123234333.12345}]
The numbers you see here are in units of seconds (this is your system time, which is measured in seconds since the epoch).
You can then use a for loop to run through each item in the list, subtract each end time from the start time, and of course subtract the start of the next press from the end of the previous one, so that you can assemble characters and words based on the gaps between presses. Have fun :-)

Lighting program - GPIO on/off on raspberry pi runtimewarning

Hello i have been trying to work this one out by myself for over a week now but i think its time to ask the question.
This is my first program with python and i intend to control my aquarium with various functions.
The first function i am programming is a lighting schedule (shortened the code a bit for this post)
The code executes okay but the GPIO pin 2 isnt turning on and off properly. and im also getting a "runtimewarning this channel is already in use"
Can i please have a bit of guidance, im sure its something simple and noob :)
here is my code
#Lighting Program
import RPi.GPIO as GPIO
import datetime
GPIO.setmode(GPIO.BCM)
GPIO.setwarnings(False)
#Declare Lighting On/Off Times
on_time_Monday = 600
off_time_Monday = 2330
rest of the days here
#Find out what day of the week it is
day = datetime.datetime.now()
day_of_week = day.isoweekday()
#find out what time it is
Current_time = datetime.datetime.strftime(datetime.datetime.now(),'%H%M')
#convert the time to an int so it can be compared
Current_time_INT = int(Current_time)
#Schedule on / off
if (day_of_week == 1) and (Current_time_INT > on_time_Monday and Current_time_INT < off_time_Monday) :
Light_on_off = 'on'
Using 'elif' for tues wed etc etc
else :
Light_on_off = 'off'
Now enable the outputs
#CALL OUTPUTS ON / OFF
GPIO.setup(2, GPIO.OUT)
if Light_on_off == 'on':
GPIO.output(2, GPIO.HIGH)
else:
GPIO.output(2, GPIO.LOW)
GPIO.cleanup()
In my experience "runtimewarning this channel is already in use" comes up when you have previously setup the GPIO pin, but haven't called
GPIO.cleanup().
I see that in your code, but I would suspect that for some reason it is not actually running.
Sometimes it is helpful to test out a GPIO pin in the terminal by running the python interpreter. It is especially useful to test if you have wired your circuit correctly.
>>>import RPi.GPIO as GPIO
>>>GPIO.setmode(GPIO.BCM)
>>>GPIO.setwarnings(False)
>>>GPIO.setup(2, GPIO.OUT)
>>>GPIO.output(2, GPIO.HIGH)
>>>GPIO.input(2)
True
>>>GPIO.output(2, GPIO.LOW)
>>>GPIO.input(2)
False
>>>GPIO.cleanup()
If your circuit is wired correctly you should be able to turn your light on and off this way. When you call GPIO.input(2) the interpreter responds with the current state of the pin. This enables you to make sure the pin is working even without a working external circuit. Once you know that it is working you can move on from there.
One simple way to flip a light switch on and off would be to use cron jobs. I have used this method successfully in the past.
You can write two short scripts, one that turns the light on, and one that turns it off.
Example: lightOn.py (replace 'HIGH' with 'LOW' for lightOff.py)
#!/usr/bin/env python
import RPi.GPIO as GPIO
GPIO.setmode(GPIO.BCM)
GPIO.setwarnings(False)
GPIO.setup(2, GPIO.OUT)
GPIO.output(2, GPIO.HIGH)
GPIO.cleanup()
Now you can create a crontab to automatically run the script at the times you want.
For example:
0 6 * * * /home/pi/lightOn.py
0 18 * * * /home/pi/lightOff.py
Would turn the light on everyday at 6AM and off at 6PM

Python Script - Nesting an if / else under an if inside a while True: on - Raspberry Pi

Python is my first interaction with a programming language, I started learning yesterday.
I'm trying to control LEDs from physical momentary switches through a Raspberry Pi and it's GPIO pins.
I have wired the switches and have a piece of code that turns each of 4 LEDs on or off.
I have a 5th switch to turn on or off all 4 LEDs at once depending on the state of an unwired pin.
The code for each LED looks like this:
import RPi.GPIO as GPIO
import time
GPIO.setwarnings(False)
GPIO.setmode(GPIO.BCM)
GPIO.setup(10, GPIO.IN, pull_up_down=GPIO.PUD_UP)
GPIO.setup(4,GPIO.OUT)
GPIO.output(4,0)
GPIO.setup(18,GPIO.OUT)
GPIO.output(18,0)
while True:
input_state = GPIO.input(10)
if input_state == False:
GPIO.output(4, not GPIO.input(4))
time.sleep(0.1)
GPIO.output(18, GPIO.input(4))
time.sleep(0.4)
Where pin 10 is an input wired to my switch, 4 is the pin that gets turned on and powers the LED and pin 18 is a pin I use to turn on/off all LEDs at the same time with another switch. I have 4 versions of this script, 1 for each LED and just the pins used are changed.
The code to turn on/off all pins at the same time looks like this:
import RPi.GPIO as GPIO
import time
GPIO.setwarnings(False)
GPIO.setmode(GPIO.BCM)
GPIO.setup(26, GPIO.IN, pull_up_down=GPIO.PUD_UP)
chan_list = (4,17,22,27)
GPIO.setup(chan_list,GPIO.OUT)
GPIO.output(chan_list,0)
GPIO.setup(18,GPIO.OUT)
GPIO.output(18,0)
while True:
input_state = GPIO.input(26)
if input_state == False:
chan_list = (4,17,22,27)
GPIO.output(18, not GPIO.input(18))
time.sleep(0.1)
GPIO.output(chan_list, GPIO.input(18))
time.sleep(0.4)
These codes work really well. I have them all setup to launch on startup as background processes.
I want to use pin 18 to turn on an indicator LED that turns on if any of the four LEDs are turned on and that stays on if any LEDs are turned off unless all 4 of the LEDs are turned off. This works fine using the all on/off button. The problem comes up when I use the individual LED buttons to turn off individual LEDs. In the current setup as soon as I turn off any individual LED pin 18 is turned off.
I'm trying to find a code solution to get around this issue so that pin 18 (the indicator LED) is on when any of the 4 LEDs are on and is only off if all 4 LEDs are off.
I was thinking some kind of nested series of if / else: conditions but my limited knowledge is stopping my success.
An example piece of code that I have tried is this:
import RPi.GPIO as GPIO
import time
GPIO.setwarnings(False)
GPIO.setmode(GPIO.BCM)
GPIO.setup(10, GPIO.IN, pull_up_down=GPIO.PUD_UP)
GPIO.setup(4,GPIO.OUT)
GPIO.output(4,0)
GPIO.setup(18,GPIO.OUT)
GPIO.output(18,0)
while True:
input_state = GPIO.input(10)
if input_state == False:
if GPIO.output(17) == True:
GPIO.output(4, not GPIO.input(4))
else:
if GPIO.output(22) == True:
GPIO.output(4, not GPIO.input(4))
else:
if GPIO.output(27) == True:
GPIO.output(4, not GPIO.input(4))
else:
GPIO.output(4, not GPIO.input(4))
time.sleep(0.1)
GPIO.output(18, GPIO.input(4))
time.sleep(0.4)
This gives an error:
Traceback (most recent call last):
File "pin10test.py", line 20, in <module>
if GPIO.output(17) == True:
TypeError: function takes exactly 2 arguments (1 given)
My intention is that when a button press is detected the it will go:
If pin 17 is on, toggle pin 4. If not go to next check.
If pin 22 is on, toggle pin 4. If not go to next check.
If pin 27 is on, toggle pin 4. If not go to final else:
toggle pin 4, sleep 0.1, set pin 18 to whatever pin 4 was just set to, sleep 0.4.
Then I'd adjust this piece of script into the script for each button.
This way pin 18 only changes state to off if all pins are off.
Any help in getting this script right is appreciated.
Any ideas or tips on how to improve this is also appreciated.
input_state = GPIO.input(10)
and
if input_state == False:
should be at the same level of indentation, which is exactly what the error message is saying. There is no reason to indent the second line (since the previous one doesn't open a new block, so indenting it is an error).

Categories

Resources