Python ability to manage 2 or more physical buttons - python-3.x

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")

Related

Rotary encoder value looking sticky after using tkinter function " root.after"

I am quite new to python and tkinter ,I am working on a project where i give demand to slave device through rotary encoder value and reading feedback value from slave devices through communication.
I face issue when i use root.after () function .
Any suggestion regarding proper use of root.after () function so that my interrupt routine not affected welcome heartly.
Thank you.
Here is my code.
import pigpio
import tkinter as tk
from PIL import ImageTk,Image
import time
from RPi import GPIO
import serial
i="*00T%"
j="*01T%"
s=serial.Serial(port='/dev/ttyS0',
baudrate=9600,
parity=serial.PARITY_NONE,
stopbits=serial.STOPBITS_ONE,
bytesize=serial.EIGHTBITS,
timeout=1)
class decoder: # class for decoding rotary encoder
def __init__(self, pi, gpioA, gpioB, callback):
----------
---------------
----------------
if __name__ == "__main__":
import RPi.GPIO as GPIO
import time
import pigpio
import tkinter as tk
import board
import busio
rpm=0
tor=0
pow=0
pi = pigpio.pi()
st=1
pos=0
def callback(way): # interrupt event sense on pin no 17,18
global pos
global st
if st ==1:
pos += way
if pos >= 9999:
pos=9999
if pos <= 0:
pos=0
var.set(pos)
print("pos={}".format(pos))
def rpm_update():
global rpm
s.write(str.encode(i))
print(i)
time.sleep(0.2)
if s.inWaiting():
rpm=s.readline(s.inWaiting())
rpm=rpm.decode('utf-8',errors='ignore')
rpm=rpm[5:-1]
print(rpm)
var2.set(rpm)
def tor_update():
global tor
s.write(str.encode(j))
print(j)
time.sleep(0.2)
if s.inWaiting():
tor=s.readline(s.inWaiting())
tor=tor.decode('utf-8',errors='ignore')
tor=tor[4:-1]
print(tor)
var3.set(tor)
def pow_update():
global rpm,tor,pow
try:
rpm=float(rpm)
tor=float(tor)
except ValueError:
pass
pow=int(rpm*tor/5252)
var4.set(pow)
def update():
rpm_update()
time.sleep(0.5)
tor_update()
time.sleep(0.5)
pow_update()
root.after(1000,update)
path="/home/pi/logo.png"
root=tk.Tk()
img=ImageTk.PhotoImage(Image.open(path))
panel=tk.Label(root,image=img)
panel.pack()
panel.place(x=195,y=10,height=50,width=80)
root.title("Dynalec")
root.geometry("500x600")
{
body of tkinter screen
}
decoder=decoder(pi, 17, 18, callback)
root.after(1000,update)
root.mainloop()
everything is working fine before root.after() function " root.after(1000,update)
but i need it because i have to read slave values in every sec and update in gui screen.
Adding as a answer because long for comments, will remove soon.
Try this out:
def update():
root.after(500,rpm_update)
root.after(500,tor_update)
root.after(500,pow_update)
root.after(1000,update)
Do let me know.

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?

button.when_pressed is activated before actually pressing the button

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

why a thread does not end

I'm trying to make an app to interact with an usb rfid reader on a Raspberry pi.
it looks like the solution is using the trheading module (otherwise the data entry leads to a disfunction)
After some essays I made an app that works... the first time. After that, a message error says "threads can only be started once"... so the interpretation is that the thread does not end naturally...why??
import time
import sys
import os
from tkinter import *
from tkinter.ttk import *
import threading
def activa_fil(self):
print ('activant fil')
fil.start()
def prova2():
print('hola')
print(Control.get())
print(NumCorr.get())
print(time.strftime("%H:%M:%S"))
DisplayCorr.config(text=NumCorr.get())
Llistacorr.insert(0, (Control.get(),NumCorr.get(), time.strftime("%H:%M:%S")))
marc.contador +=1
Contador.config (text=marc.contador)
print(marc.contador)
file = open("prova.txt", "a")
file.write(Control.get())
file.write(NumCorr.get())
file.write (time.strftime("%H:%M:%S"))
file.write('\n')
file.close()
NumCorr.after(500, NumCorr.delete(0,END))
def tick():
time_string = time.strftime("%H:%M:%S")
Hora.config(text=time_string)
Hora.after(200, tick)
def canvia_focus(self):
NumCorr.focus()
fil=threading.Timer(0.5, prova2)
marc = Tk()
marc.geometry('480x320')
marc.bind_all(''<'Key-Return'>'', activa_fil)
marc.contador =0
Control = Combobox(marc)
Control['values']=('sortida','can cuias','can campanya','papiol','sortida papiol', 'can olivero', 'ullastrell', 'coll olesa','pla fideuer','aeri', 'arribada')
Control.config(font="helvetica 30", )
Control.grid(column='0', row='0', columnspan='2')
Llistacorr = Listbox(marc)
Llistacorr.config(font='arial')
Llistacorr.grid_propagate(0)
Llistacorr.grid(column='0', row='1', rowspan='3')
DisplayCorr=Label(marc, font='Arial 10')
DisplayCorr.grid(column='1', row='1')
NumCorr = Entry(marc)
NumCorr.config(font='helvetica 6')
Control.bind('<<ComboboxSelected>>', canvia_focus)
NumCorr.grid(column='0', row='4', columnspan='2')
Contador=Label(marc, font='arial 30')
Contador.grid(column='1', row='2')
Hora=Label(marc, font='arial 30')
Hora.grid(column='1', row='3')
tick()
marc.mainloop()

How would I constantly update a variable within a script/program?

I am attempting to make a thermostat of sorts. To do this, I am using a Pi3 with a DHT22 Temperature sensor, and Python3.
What I need is for the temperature to be polled and the corresponding variable to update on its own.
Attempting to do so with any sort of While True: statements results in the gui I'm testing with, not opening.
I'm lost (And yes, this code is hacked together from others. LOL)
#! python3
import time
import RPi.GPIO as GPIO
import string
import tkinter
import tkinter.ttk
import Adafruit_DHT
from tkinter import messagebox
from tkinter import *
root = Tk()
root.title('PiTEST')
root.configure(background='black')
GPIO.setmode(GPIO.BCM)
GPIO.setwarnings(False)
sensor = Adafruit_DHT.DHT22
pin = 4
def PRINTTEST():
print(temperature, humidity)
TESTTEXT = Label(root,text="TESTING",fg="white",bg="black",font='Consolas 20 bold')
TESTTEXT.grid(row=1,column=1,sticky="W,S,E")
B1 = tkinter.Button(root,bd=5,text="TEST",bg="gray",fg="white",command=PRINTTEST,height=4,width=20)
B1.grid(row=2,column=1,sticky="N,S,E,W",padx=8,pady=8)
while True:
humidity, temperature = Adafruit_DHT.read_retry(sensor, pin)
temperature = temperature * 9/5.0 + 32
root.mainloop()
GPIO.cleanup()
Here is a code example without your GPIO things:
#! python3
import time
import string
import tkinter
import random
from tkinter import messagebox
from tkinter import *
root = Tk()
root.title('PiTEST')
root.configure(background='black')
def PRINTTEST():
temperature = random.randint(0,100)
humidity = random.randint(0,100)
print(temperature, humidity)
root.after(1000, PRINTTEST)
TESTTEXT = Label(root,text="TESTING",fg="white",bg="black",font='Consolas 20 bold')
TESTTEXT.grid(row=1,column=1,sticky="W,S,E")
B1 = tkinter.Button(root,bd=5,text="TEST",bg="gray",fg="white",command=PRINTTEST,height=4,width=20)
B1.grid(row=2,column=1,sticky="N,S,E,W",padx=8,pady=8)
root.mainloop()
This will print 2 random integers every second in your terminal.

Resources