button.when_pressed is activated before actually pressing the button - python-3.x

from twython import Twython
from time import sleep
from gpiozero import LED, Buzzer, InputDevice, Button
import RPi.GPIO as GPIO
import sys
import Adafruit_DHT
from signal import pause
import mysql.connector
GPIO.setwarnings(False)
GPIO.setmode(GPIO.BCM)
GPIO.setup(13,GPIO.OUT)
no_rain = InputDevice(18)
bz = Buzzer(19)
n = True
led = LED(23)
button = Button(13, pull_up=False)
def printstate():
print("pressed")
n = True
if no_rain.is_active:
bz.off()
while n == True:
if no_rain.is_active:
print("It's raining, get your clothes out.")
#bz.off
ledON()
humidity, temperature = Adafruit_DHT.read_retry(11, 17)
print('Temp: {:.1f} C'.format(temperature))
print('Humidity: {:.1f}'.format(humidity))
n = False
button.when_pressed = printstate()
pause()
button.when_pressed is registered as pressed even though i didn't actually press the button on my GPIO raspberry pi.
Tried both released and pressed, Is there anyway for me use to button to stop the buzzer from buzzing?
The buzzer is buzzing even though the program ended.

button.when_pressed expects a function, but you assign it the function response. I.e. the function is called when you assign it, instead of when the button is pressed.
If you change the function to return something other than None you will probably get an exception when pressing the button also. Making the mistake a bit more noticable.
Change it to:
button.when_pressed = printstate # without the parentheses

Related

Stopping a while loop from a break command in a callback (different thread) HOW?

The following code is meant to model a stepper motor motor running (as a result of the reset() method of the Dolly class (details not shown)) moving the Dolly until it cuts the beam of an optical switch. This is to calibrate the dolly position.
My code gets the motor going (1 step per while loop) but the optical switch event that should fork to the callback never seems to get triggered, even though I've set up a breakpoint in VScod but the print statement in the callback executes, so something's going on.
The while loop should step the motor each time and when triggered, the optical switch should invoke a break command in the callback to jump out of the while loop. This doesn't happen, so the motor just keeps going
I think one complication is that because the callback event trigger is in a different thread, the scope of break has no effect on the while loop == True logic. If I invoke a break command, it isn't in the context of the while loop and so has no effect. Can I qualify the break command with some reference to the loop I want to stop or is there a better way to do this?
Code below:
#!/usr/bin/python3
import RPi.GPIO as GPIO
import time
#import threading
import math
from adafruit_motorkit import MotorKit
from adafruit_motor import stepper
GPIO.setmode(GPIO.BCM)
track_end_detector = 23 #BCM number
kit1 = MotorKit(address=0x62)
GPIO.setup(track_end_detector, GPIO.IN, pull_up_down=GPIO.PUD_UP)
def my_callback(channel):
loop = False
kit1.stepper1.release()
print('Edge detected on channel %s'%channel)
break #This has no knowledge of the loop I want to stop (the While loop, near the end
GPIO.add_event_detect(track_end_detector, GPIO.RISING, callback=my_callback) # add rising edge detection on a channel
#Classes
class Movie:
snip
class Track:
snip
class Target:
snip
class PnT:
snip
class Camera:
snip
class Dolly:
snip
#Main
Jaws = Movie(10, 990, 60, 25, 600)
Route66 = Track()
Thing = Target()
RocknRoll = PnT(pos=500)
loop = True
while loop == True:
#!/usr/bin/python3
import RPi.GPIO as GPIO
import time
import threading
import math
from adafruit_motorkit import MotorKit
from adafruit_motor import stepper
GPIO.setmode(GPIO.BCM)
track_end_detector = 23 #BCM number
kit1 = MotorKit(address=0x62)
GPIO.setup(track_end_detector, GPIO.IN, pull_up_down=GPIO.PUD_UP)
def my_callback(channel): #Jump out of loop if endpoint detected
#What IS the channel parameter here - can't find any decent documentation
for i in range(500):
kit1.stepper1.onestep(direction=stepper.FORWARD, style=stepper.DOUBLE)
loop = False
kit1.stepper1.release()
GPIO.add_event_detect(track_end_detector, GPIO.RISING, callback=my_callback) # add rising edge detection on a channel
#Classes
class Movie:
snip
class Track:
snip
class Target:
snip
class PnT:
snip
class Camera:
snip
class Dolly:
snip
#Main
Jaws = Movie(10, 990, 60, 25, 600)
Route66 = Track()
Thing = Target()
RocknRoll = PnT(pos=500)
loop = True
while loop == True:
kit1.stepper1.onestep(direction=stepper.FORWARD, style=stepper.DOUBLE)
time.sleep(0.05)

Python Auto Click bot not working and I cant figure out why

I made a python 'aimbot' type program that looks for targets in the aim trainer and clicks on them. The problem is it clicks but not on the target and I'm pretty sure I did everything right. Here's the program:
from pyautogui import *
import pyautogui
import time
import keyboard
import random
import win32api, win32con
time.sleep(2)
def click(x,y):
win32api.SetCursorPos((x,y))
win32api.mouse_event(win32con.MOUSEEVENTF_LEFTDOWN,0,0)
win32api.mouse_event(win32con.MOUSEEVENTF_LEFTUP,0,0)
while keyboard.is_pressed('q')== False:
pic = pyautogui.screenshot(region=(0,0,1080,1920))
width, height = pic.size
for x in range(0,width,5):
for y in range(0,height,5):
r,g,b = pic.getpixel((x,y))
if g == 154:
click(x,y)
time.sleep(1)
break

Python 3 Subprocess does not terminate with signal.SIGINT

I've read many of the questions here on SO, but none of the solutions seem to solve my problem. I have a file called "light_led.py" which looks like this
import RPi.GPIO as gpio
import time
# Set the mode for the GPIO numbering
gpio.setmode(gpio.BCM)
pin = 23
# Set the GPIO as output
gpio.setup(pin, gpio.OUT, initial=gpio.LOW)
try:
while True: # Run forever
gpio.output(pin, gpio.HIGH) # Turn on
time.sleep(1) # Sleep for 1 second
gpio.output(pin, gpio.LOW) # Turn off
time.sleep(1) # Sleep for 1 second
except KeyboardInterrupt:
# cleanup all GPIO
gpio.cleanup()
print('Cleaned up')
It simply toggles an LED on and off. This file is called in the following script
import RPi.GPIO as gpio
import time
import subprocess
import signal
# Set the mode for the GPIO numbering
gpio.setmode(gpio.BCM)
pin = 24
# Set the GPIO as input w/ pull up
gpio.setup(pin, gpio.IN, pull_up_down = gpio.PUD_UP)
# Initialize
pin_prev = gpio.input(pin)
while True:
pin = gpio.input(pin)
if (pin == 0) and (pin_prev == 1):
process = subprocess.Popen('python <PATH-TO-FILE>/light_led.py', shell=True)
print('Should be blinking')
if (pin == 1) and (pin_prev == 0):
process.send_signal(signal.SIGINT)
print('Should be off')
# Update previous state
pin_prev = pin
# Slight pause to debounce
time.sleep(0.05)
The files run fine and do what they're suppose to. The only problem I'm having is that I can't stop the blinking light by "flipping the switch". In other words, I'm having trouble with this process.send_signal(signal.SIGINT). There are not errors, so I don't have much to report.
I've tried process.terminate() and os.kill(process.pid, signal.SIGINT), both with no luck. I just want to stop the subprocess from running and continue with the main toggle script. From what I read, "signal.SIGINT" should invoke the "KeyboardInterrupt" in the subprocess...but maybe not?

Python import pygame does not play an audio

the code just print the name of the song and dont stop after he finish
my code:
import glob
import os
os.environ['PYGAME_HIDE_SUPPORT_PROMPT'] = "hide"
import pygame
songs = glob.glob("C:\\Users\zivsi\Music\\*.mp3")
import random
song = random.choice(songs)
song_name = song.replace("C:\\Users\zivsi\Music\\", "").replace(".mp3", "")
print("song: ", song_name)
pygame.init()
pygame.mixer.music.load(song)
pygame.mixer.music.play()
while pygame.mixer.music.get_busy():
pygame.time.Clock().tick(10)
I did not use from pygame import *
because it cannot be done in def
Use pygame.mixer.music.stop() when you want to stop the music. The pygame.time.Clock().tick(10) computes the time since it was last called and stalls the program until 1/framerate (in your case framerate=10) seconds have passed. Therefore, your code will run until the song is done playing. If instead you want to pause the program for a set amount of time and stop the music from playing, use time.sleep(), which takes seconds as an argument. Possible example:
import glob
import os
import time
os.environ['PYGAME_HIDE_SUPPORT_PROMPT'] = "hide"
import pygame
songs = glob.glob("C:\\Users\zivsi\Music\\*.mp3")
import random
song = random.choice(songs)
song_name = song.replace("C:\\Users\zivsi\Music\\", "").replace(".mp3", "")
print("song: ", song_name)
pygame.init()
pygame.mixer.music.load(song)
pygame.mixer.music.play()
time.sleep(10) #sleep for 10 seconds before moving on
pygame.mixer.music.stop()
thank you. i understand now. my mistake was:
pygame.init() -
i need
pygame.mixer.init()

Python ability to manage 2 or more physical buttons

I am making a camera. I am using a RPi 3 and python. I am using 2 GPIO attached to momentary switches. With the first button I want to be able to take pictures. The second one runs a script to shutdown the system, but IT IS NOT WORKING. This is the code. Please help.
import RPi.GPIO as GPIO
from gpiozero import Button
import time
import os
from time import sleep
from picamera import PiCamera
GPIO.setmode(GPIO.BCM)
GPIO.setup(17, GPIO.IN, pull_up_down = GPIO.PUD_DOWN)
GPIO.setup(18, GPIO.IN, pull_up_down = GPIO.PUD_DOWN)
button1 = Button(17)
button2 = Button(18)
camera = PiCamera()
channel = 1
if GPIO.input(18):
button2.wait_for_press()
print("Here I will run the shutdown code")
if GPIO.input(17):
frame = 1
while True:
try:
button1.wait_for_press()
camera.capture('/home/pi/Vinpics/frame%03d.jpg' % frame)
frame += 1
except KeyboardInterrupt:
print("Just a place holder")

Resources