Python Forum
Picture changing triggered by GPIO
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Picture changing triggered by GPIO
#1
Hello,
I'm just started learning Python. Program will work under RPi.
General functionality is: when gpio input is grounded picture red picture should me displayed, when input is on open circuit to ground white picture should be displayed.

from Tkinter import *
from PIL import Image
from PIL import ImageTk
import os
import sys
import RPi.GPIO as GPIO


root = Tk()

#root.geometry("800x600")
#root.attributes('-type', 'dock')
#root.focus_force()

GPIO.setmode(GPIO.BCM)
GPIO.setwarnings(False)
IP = 21
GPIO.setup(IP, GPIO.IN, pull_up_down=GPIO.PUD_UP)

root.geometry("800x600")
#root.attributes('-type', 'dock')
root.focus_force()

if os.environ.get('DISPLAY','') == '':
    print('no display found. Using :0.0')
    os.environ.__setitem__('DISPLAY', ':0.0')
GPIO.setmode(GPIO.BCM)

global p1_rd
global p1_wh

p1_rd = ImageTk.PhotoImage(Image.open("1_rd.png"))
p1_wh = ImageTk.PhotoImage(Image.open("1_wh.png"))


im_1 = Label(image= p1_wh, borderwidth=0)
im_1.grid(row=0, column=0)

global trig1

trig1 = 1

def ChangeImage1(self):
    global trig1
    if GPIO.input(21) == 0:
        if GPIO.input(21) != trig1:
            im_1 = Label(image= p1_rd, borderwidth=0)
            im_1.grid(row=0, column=0)
            trig1 = 0
    else:
        if trig1 != 1:
            im_1 = Label(image= p1_wh, borderwidth=0)
            im_1.grid(row=0, column=0)
            trig1 = 1


ChangeImage1(None)
#root = Tkinter.Tk()
#state_det1(None)
root.mainloop()
GPIO.cleanup()
Program gives expected result only if gpio is triggered when program is starting up (once)
I tried to use while loop with extra function def. - only my program stuck.
I'm not sure that way with Tkinker is good one.

Can you help me with any direction when I should go?
Reply
#2
The program always gives the expected result. It displays the state of the input when the ChangeImage() function is called. The problem is that your program only calls the ChangeImage() function once, when it starts.

To see changes on input 21 you need to keep looking over and over. I suggest you do a few of the many Raspberry Pi Python tutorials to learn about how to write programs that monitor and control hardware.

To see some results right now try this:
def ChangeImage1(self):
    global trig1
    if GPIO.input(21) == 0:
        if GPIO.input(21) != trig1:
            im_1 = Label(image= p1_rd, borderwidth=0)
            im_1.grid(row=0, column=0)
            trig1 = 0
    else:
        if trig1 != 1:
            im_1 = Label(image= p1_wh, borderwidth=0)
            im_1.grid(row=0, column=0)
            trig1 = 1
    root.after(100, self.ChangeImage1)
This will call ChangeImage1() 10 times a second.
Reply
#3
You should use gpiozero, which has already event driven callbacks and it's own background thread.

Example-Code:
import os
from tkinter import Button, Label, Tk

from gpiozero import Button as GPIO_Button
from gpiozero.pins.mock import MockFactory
from PIL import Image
from PIL.ImageTk import PhotoImage

# There is Button from tkinter already imported
# renaming Button to GPIO_Button
# MockFactory is to test without GPIO (real Hardware)


if not os.environ.get("DISPLAY", ""):
    print("no display found. Using :0.0")
    os.environ["DISPLAY"] = ":0.0"


def set_red_image():
    """
    Callback function for gpio Button
    """
    label["image"] = red_img


def set_white_image():
    """
    Callback function for gpio Button
    """
    label["image"] = white_img


def drive_low():
    """
    This function is for testing without GPIO.
    """
    print("Setting GPIO to low state")
    gpio_pin = mock_factory.pins[pin]
    gpio_pin.drive_low()
    # call drive high after 2 seconds
    root.after(2000, drive_high)


def drive_high():
    """
    This function is for testing without GPIO.
    """
    print("Setting GPIO to high state")
    gpio_pin = mock_factory.pins[pin]
    gpio_pin.drive_high()
    # call drive_low after one second
    root.after(1000, drive_low)


if __name__ == "__main__":
    pin = 21

    # for testing without gpio
    mock_factory = MockFactory()
    # end

    button = GPIO_Button(pin, pin_factory=mock_factory)
    # button = GPIO_Button(pin) # <- with real gpio

    # the library has an own background thread,
    # which handles incomming events like positive edge or negative edge
    # https://gpiozero.readthedocs.io/en/stable/recipes.html#button
    button.when_pressed = set_red_image
    button.when_released = set_white_image
    # when_pressed calls set_red_image
    # when_released calls set_white_image

    root = Tk()
    root.geometry("800x600")

    # placeholder images
    # Hint: PhotoImage requires the master (root).
    #       Don't create instances of PhotoImage
    #       before root was created
    white_img = PhotoImage(
        Image.new(mode="RGB", size=(200, 200), color=(255, 255, 255))
    )
    red_img = PhotoImage(Image.new(mode="RGB", size=(200, 200), color=(255, 0, 0)))

    # creating the label once is enough
    # you can change the label afterwards it was created
    label = Label(root, image=white_img, borderwidth=0)
    label.grid(row=0, column=0)

    # button to close the app
    Button(root, text="Close", command=root.destroy).grid(row=1, column=0)

    root.focus_force()

    # this calls the test function to test without gpio
    # you don't need it with gpio
    # and you can remove drive_high and drive_low
    root.after(1000, drive_low)
    root.mainloop()
My code examples are always for Python >=3.6.0
Almost dead, but too lazy to die: https://sourceserver.info
All humans together. We don't need politicians!
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  Seemingly unstable GPIO output while executing from RetroPie LouF 6 291 Feb-19-2021, 06:29 AM
Last Post: LouF
  GPIO high if network IP has good ping duckredbeard 3 313 Oct-12-2020, 10:41 PM
Last Post: bowlofred
  How to scrolling Picture in x axis kalihotname 1 446 Jun-16-2020, 12:18 PM
Last Post: DeaD_EyE
  raspberry pi tank gpio help jatgm1 1 487 May-06-2020, 09:00 PM
Last Post: Larz60+
  Where should I place GPIO.cleanup() shallanq 2 550 Apr-11-2020, 05:02 AM
Last Post: shallanq
  Orange PI Win steering LEDs connect to GPIO djmcg 0 415 Dec-27-2019, 08:26 AM
Last Post: djmcg
  GPIO time in HIGH LOW boris_za 1 569 Dec-07-2019, 01:48 PM
Last Post: Larz60+
  RPi GPIO Flashing LED nickayres 1 956 Jun-07-2019, 01:32 PM
Last Post: gontajones
  How to get the picture from gender dataset vokoyo 1 745 May-03-2019, 12:20 AM
Last Post: micseydel
  cropping a picture (always square) Leon 1 844 Aug-13-2018, 10:04 AM
Last Post: Leon

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020