English is not my first language, so expect some grammar mistakes.
Hi, I'm new to programming, haven't really touched python at all, I usually write JavaScript and PowerShell scripts, python syntax just breaks my mind. This question has been asked several times, but the answers provided were too convoluted and involved some specifics to the question asked that I just got lost in it.
What I'm trying to do is a simple door sensor, I have a Raspberry Pi that can read the state of a GPIO pin, when that pin is pulled to ground (state 0) the sensor is engaged and the door is closed, but when its state is 1, the sensor is not engaged, thus the door must be open. I got my code to detect that and print out "door open" or "door closed" to the terminal over and over until I stop it, I set up a telegram bot and got it to talk to my code, now when the door is open the bot send the same message until I stop the code.
This is what I got so far
import RPi.GPIO as GPIO
from time import sleep
import telegram_send
GPIO.setmode(GPIO.BCM)
#sensor is connected to pin 21
sensor=21
#pull the sensor to 3.3v when not engaged
GPIO.setup(sensor,GPIO.IN,pull_up_down=GPIO.PUD_UP)
#send the message
while(1):
if GPIO.input(sensor)==1:
print("The door is open")
telegram_send.send(messages=["The door is open!"])
sleep(1)
elif GPIO.input(sensor)==0:
print("The door is closed")
telegram_send.send(messages=["The door is closed!"])
sleep(1)
What It thought of doing is storing the state of the sensor to a variable every second and then checking the state of that variable. Then telling the bot to send me a message only when the variable changes, so I need two loops, one for updating the variable and one for checking it and when a condition is met, sending the message only once, what I have no idea how to do, is comparing the current state of the variable to the state of that variable 1 second ago.
I got this far and kinda gave up, searched around here for a bit, the few answers I found got me even more confused, I looked up a tutorial on YouTube, but everyone just says "and then I wrote some code to go with it" so no luck there.
import RPi.GPIO as GPIO
from time import sleep
import telegram_send
GPIO.setmode(GPIO.BCM)
#sensor is connected to pin 21
sensor=21
#pull the sensor to 3.3v when not engaged
GPIO.setup(sensor,GPIO.IN,pull_up_down=GPIO.PUD_UP)
#store the status of the GPIO pin
while True:
status=GPIO.input(sensor)
#check the status of the pin
if status==0:
print("Door is closed!")
elif status==1:
print("Door is open!")
I hope someone wants to help me out :D I'm really interested in this and want to learn how to do these kinds of home automation projects since I see a lot of people talking about it.
SOLUTION
#Import necesary libraries
from time import sleep
import RPi.GPIO as GPIO
import telegram_send
sensor = 21 # The sensor is on GPIO pin 21
OPEN_DOOR = 1 # The state of the sensor is 1 when the door is open
CLOSED_DOOR = 0 # The state of the sensor is 0 when the door is closed
DOOR_LAST_STATE = -1
# Send the message
if __name__ == '__main__':
# Sets the GPIO pinout to BCM
GPIO.setmode(GPIO.BCM)
# Pull the sensor to 3.3v when not engaged, It will be pulled to ground when engaged
GPIO.setup(sensor,GPIO.IN,pull_up_down=GPIO.PUD_UP)
# Recovering current state of the door
DOOR_LAST_STATE = GPIO.input(sensor)
# Main Event Loop
# ------------------------------------------------------------------------
print("Program started!")
while True:
curr_state = GPIO.input(sensor)
if curr_state == OPEN_DOOR: # If the door is open
if DOOR_LAST_STATE == CLOSED_DOOR: # And the las known state is "closed"
print("The door is open") # Send the message
telegram_send.send(messages=["The door is open!"])
DOOR_LAST_STATE = OPEN_DOOR # And upate the last known state to "open"
elif DOOR_LAST_STATE == OPEN_DOOR: # But if the last known state is the same as the current
print("The door is still open")
# Do Nothing
else:
print("The door is at unknow state")
elif curr_state == CLOSED_DOOR: # If the door is closed
if DOOR_LAST_STATE == OPEN_DOOR: # And the last know state is open
print("The door is closed") # Send the message
telegram_send.send(messages=["The door is closed!"])
DOOR_LAST_STATE = CLOSED_DOOR # And update the last known state to "closed"
elif DOOR_LAST_STATE == CLOSED_DOOR: # If the last known state is te same as the current
print("The door is still closed")
# Do Nothing
else:
print("The door is at unknow state")
else:
print("The door is at unknow state")
sleep(1) # What we do we will always sleep at the end
# ------------------------------------------------------------------------
# End of loop
--------
CodePudding user response:
Here is the correct answer:
#Import necessary libraries
from time import sleep
import RPi.GPIO as GPIO
import telegram_send
sensor = 21 # The sensor is on GPIO pin 21
OPEN_DOOR = 1 # The state of the sensor is 1 when the door is open
CLOSED_DOOR = 0 # The state of the sensor is 0 when the door is closed
DOOR_LAST_STATE = -1
# Send the message
if __name__ == '__main__':
# Sets the GPIO pinout to BCM
GPIO.setmode(GPIO.BCM)
# Pull the sensor to 3.3v when not engaged, It will be pulled to ground when engaged
GPIO.setup(sensor,GPIO.IN,pull_up_down=GPIO.PUD_UP)
# Recovering current state of the door
DOOR_LAST_STATE = GPIO.input(sensor)
# Main Event Loop
# ------------------------------------------------------------------------
print("Program started!")
while True:
curr_state = GPIO.input(sensor)
if curr_state == OPEN_DOOR: # If the door is open
if DOOR_LAST_STATE == CLOSED_DOOR: # And the las known state is "closed"
print("The door is open") # Send the message
telegram_send.send(messages=["The door is open!"])
DOOR_LAST_STATE = OPEN_DOOR # And upate the last known state to "open"
elif DOOR_LAST_STATE == OPEN_DOOR: # But if the last known state is the same as the current
print("The door is still open")
# Do Nothing
else:
print("The door is at unknow state")
elif curr_state == CLOSED_DOOR: # If the door is closed
if DOOR_LAST_STATE == OPEN_DOOR: # And the last know state is open
print("The door is closed") # Send the message
telegram_send.send(messages=["The door is closed!"])
DOOR_LAST_STATE = CLOSED_DOOR # And update the last known state to "closed"
elif DOOR_LAST_STATE == CLOSED_DOOR: # If the last known state is te same as the current
print("The door is still closed")
# Do Nothing
else:
print("The door is at unknow state")
else:
print("The door is at unknow state")
sleep(1) # What we do we will always sleep at the end
# ------------------------------------------------------------------------
# End of loop
CodePudding user response:
from time import sleep
import RPi.GPIO as GPIO
import telegram_send
OPEN_DOOR = 1
CLOSED_DOOR = 0
DOOR_LAST_STATE = -1
#send the message
if __name__ == '__main__':
# Initializing Connections
# ------------------------------------------------------------------------
GPIO.setmode(GPIO.BCM)
#pull the sensor to 3.3v when not engaged
GPIO.setup(sensor,GPIO.IN,pull_up_down=GPIO.PUD_UP)
# Recovering current state of the door
# ------------------------------------------------------------------------
DOOR_LAST_STATE = GPIO.input(sensor)
# Main Event Loop
# ------------------------------------------------------------------------
while True:
curr_state = GPIO.input(sensor)
if curr_state == OPEN_DOOR:
if DOOR_LAST_STATE == CLOSED_DOOR:
print("The door is openning")
telegram_send.send(messages=["The door is open!"])
DOOR_LAST_STATE = CLOSED_DOOR
elif DOOR_LAST_STATE == OPEN_DOOR:
print("The door is still openned")
# Do Nothing
else:
print("The door is at unknow state")
# Do Something... maybe raise an Exception?
elif curr_state == CLOSED_DOOR:
if DOOR_LAST_STATE == OPEN_DOOR:
print("The door is closing")
telegram_send.send(messages=["The door is closed!"])
DOOR_LAST_STATE = CLOSED_DOOR
elif DOOR_LAST_STATE == CLOSED_DOOR:
print("The door is still closed")
# Do Nothing
else:
print("The door is at unknow state")
# Do Something... maybe raise an Exception?
else:
print("The door is at unknow state")
# Do Something... maybe raise an Exception?
sleep(1) # Whatever we do we will always sleep at the end
The "missing" trick here is that you were not using a variable to track the last state of the door.