clissolo
Posts: 2
Joined: Wed Jan 15, 2020 6:33 pm

Automated Can Crusher

Wed Jan 15, 2020 6:50 pm

been working on it for a couple days, building an automated pop can smasher...so.... the solenoid(using a relay just for simplicity), kicks on when started, stays on, but i can use my "stop" button to stop it, and my "start" button to start it again. i cant figure out how to include my "if" statement and "range(2) string to work with my "start" button.
Say i run it 100 times(in my range) and want to "stop" it at any given time.....
Next, when i exit my window(widget) my "IF" statement executes the rest of the sequence, can't figure out where to put my root.mainloop*()
My code is correct without any errors, just positioning problems ..maybe...thanks for all the help and info, it is greatly appreciated!

Code: Select all

import RPi.GPIO as GPIO
import time
from tkinter import *
import tkinter.font as font

root = Tk()
root.geometry('500x500')      #size of window

class CanSmasher:
    def __init__(self, master):
        frame = Frame(master)
        frame.pack()

        myFont = font.Font(size=20)     #define Font

        self.printButton = Button(frame, text="Start", bg="green", fg="black", command = lambda: solenoid_off(21),width=20, height=5)
        self.printButton['font'] = myFont
        self.printButton.pack()

        self.quitButton = Button(frame, text ="Stop", bg="red", fg="black", command = lambda: solenoid_on(21), width=20, height=5)
        self.quitButton['font'] = myFont
        self.quitButton.pack()

channel = 21

# GPIO setup
GPIO.setmode(GPIO.BCM)
GPIO.setup(channel, GPIO.OUT)

def solenoid_on(pin):
    GPIO.output(pin, GPIO.HIGH)   # Turn solenoid on
def solenoid_off(pin):
    GPIO.output(pin, GPIO.LOW)    # Turn solenoid off

c=CanSmasher(root)
root.mainloop()  

if __name__ == '__main__':
    try:
        for i in range(2):        # Number of times ran is writen in ==> [range(put run times here)]
            
            solenoid_on(channel)
            time.sleep(1)         # Sets lag time

            solenoid_off(channel)
            time.sleep(1)         # Sets run time
        print("Cans Crushed", i+1)

        GPIO.cleanup()

    except KeyboardInterrupt:
        GPIO.cleanup()
        

scotty101
Posts: 3774
Joined: Fri Jun 08, 2012 6:03 pm

Re: Automated Can Crusher

Thu Jan 16, 2020 1:20 pm

Loops, time.sleep and Tkinter don't play well together.

As you've discovered, your mainloop will keep running until the window is closed which is when any code after the mainloop can execute.
Anytime you use time.sleep in a (single threaded) tkinter program, you are preventing the GUI from updating and responding to events.
You have two options.
  • Use the tkinter .after method to schedule a task which will change the state of the soleniod and then schedule itself to run after after a period of time.
  • Use threading. Your mainloop starts a seperate code thread which handles the soleniod. This can have a loop inside it.
Not sure what you are looking for your program to do so can't give any specific examples.
Electronic and Computer Engineer
Pi Interests: Home Automation, IOT, Python and Tkinter

clissolo
Posts: 2
Joined: Wed Jan 15, 2020 6:33 pm

Re: Automated Can Crusher

Thu Jan 16, 2020 9:52 pm

Yeah you ain't lying when it comes down to loops and sleep thanks for the input, I'll have to dig into your suggestions, I am fairly new to python in general .....this is actually one of my first "builds" ever .....figured it was an easy concept, granted it only took 4 days and a total of 36 hours lol thanks again

Return to “Troubleshooting”