-1

I'm new to python and coding generally, so I'm a bit stuck on something where I need some guidance.

I'm currently working on a project from school, where I'm building a rc car with raspberry pi 3. Im currently working on a UI for the car in Tkinter. The code is below, what I am asking for is how I can make the car go forward, backward, left and right with clicking on the buttons from the GUI, and how to add push and release function on it.

As you can see I run it through remote GPIO (Gpiozero). Also, I'm just adding the left button here to have as an example of the rest of the code.

I have a photo image on the button, but if you want to run the code, just # it, and put in text instead inside tk.button

    import tkinter as tk
    import sys
    from PIL import Image, ImageTk
    import time
    from gpiozero import motor
    from gpiozero.pins.pigpio import PiGPIOFactory

    #remote_factory = PiGPIOFactory(host=)
    turn_speed = 0.5
    drive_speed = 0.15
    #remote_factory = PiGPIOFactory(host=)
    # 19 = FORWARD, 13 = BACKWARD
    motor_1 = Motor(forward=19, backward=13)
    # 6 = LEFT, 5 = RIGHT
    motor_2 = Motor(forward=6, backward=5)

    drive_forward = motor_1.forward
    drive_backward = motor_1.backward
    turn_left = motor_2.forward
    turn_right = motor_2.backward

    #motor_forward = Motor(forward=19)
    #motor_reverse = Motor(backward=13)
    #motor_left = Motor(forward=6)
    #motor_right = Motor(backward=5)





    def main():
        vindu=tk.Tk()
        vindu.title("PiDrv")
        vindu.geometry("300x300")
       #vindu.configure


        #Turn left
        def left_arrow():

            print("Left")
            #turn_left

        def stop():
            print("Stop")

        def left_button():
            b = tk.Button(vindu, command=left_arrow )
            b.grid(row=1, column=1, padx=0, pady=150) 
            image=ImageTk.PhotoImage(file="Arrow_left2.jpg")
            b.config(image=image)
            b.image = image
            b.config(height=70, width=70)
            #b.bind("<Button-1>", left_arrow)
            #b.bind("<ButtonRelease-1>",stop)
            b.grid()
        left_button()

    main()

Thanks in advance :)

Bryan Oakley
  • 370,779
  • 53
  • 539
  • 685
jodlar
  • 11
  • 1

1 Answers1

0

Decent question imho, it brings up an important concern; how to loop stuff outside tkinter's mainloop. The answer is to use Tk's after(delay, callback), see the example I drafted, feel free to run it;

from tkinter import *
import sys
from PIL import Image, ImageTk
import time
from gpiozero import motor
from gpiozero.pins.pigpio import PiGPIOFactory

#remote_factory = PiGPIOFactory(host=)
turn_speed = 0.5
drive_speed = 0.15
#remote_factory = PiGPIOFactory(host=)
# 19 = FORWARD, 13 = BACKWARD
motor_1 = Motor(forward=19, backward=13)
# 6 = LEFT, 5 = RIGHT
motor_2 = Motor(forward=6, backward=5)

drive_forward = motor_1.forward
drive_backward = motor_1.backward
turn_left = motor_2.forward
turn_right = motor_2.backward

#motor_forward = Motor(forward=19)
#motor_reverse = Motor(backward=13)
#motor_left = Motor(forward=6)
#motor_right = Motor(backward=5)

class RcApp(Tk):

    def __init__(self):
        Tk.__init__(self)

        self.left = Button(self, text='go left!')
        self.right = Button(self, text='go right!')
        self.forward = Button(self, text='go forward!')
        self.reverse = Button(self, text='reverse!')

        self.bind('<ButtonPress>', self.callback)
        self.bind('<ButtonRelease>', self.callback)

        self.left.grid(column=0,row=1)
        self.right.grid(column=2,row=1)
        self.forward.grid(column=1,row=0)
        self.reverse.grid(column=1,row=2)

        self.type = None

    def callback(self, event):
        print(event.type)
        self.type = event.type
        if self.type == '4':
            if event.widget == self.left:
                self.after(200, self.move_left)
            if event.widget == self.right:
                self.after(200, self.move_right)
            if event.widget == self.forward:
                self.after(200, self.move_forward)
            if event.widget == self.reverse:
                self.after(200, self.move_reverse)

    def move_left(self):
        if self.type == '4':
            print('moving left!')
            turn_left()
            self.after(200, self.move_left)

    def move_right(self):
        if self.type == '4':
            print('moving right!')
            turn_right()
            self.after(200, self.move_right)

    def move_forward(self):
        if self.type == '4':
            print('moving forward!')
            drive_forward()
            self.after(200, self.move_forward)

    def move_reverse(self):
        if self.type == '4':
            print('moving reverse!')
            drive_backward()
            self.after(200, self.move_reverse)

root = RcApp()
root.mainloop()

More info about after you can find at this other question

Good luck!

Pax Vobiscum
  • 2,551
  • 2
  • 21
  • 32
  • Thank you, Rloqvist. Do you know how I can activate the output pins from the motor inside this code when triggering the buttons? – jodlar Nov 03 '17 at 18:46
  • Great, thank you very much! Appreciate you taking your time to help a newbie out :) It ran great now, only one thing left, and that is when I push one of the buttons, the car goes in a loop, and won't stop until I push another button. Any suggestions? – jodlar Nov 04 '17 at 13:27