Sanchobob
Posts: 9
Joined: Fri Jul 21, 2017 7:30 am

Help with Python code interupts

Fri Jul 21, 2017 11:56 am

Hi
Working on a robot project but thought as it is with the code this would be the better place to post.

I am a noob when it comes to Python and the code I have written is a bit of a mash up of what I have found on the internet.

This a 2 part question :

1)
The main code works I can get the motors turning and in the right directions, the issue I have is I have added a few switches and cant get it to work how i want.

The standard head movement switch seems to work, when triggered it moves in the desired direction and stops when it hits the home switch.

problem I have is the main limit switch, I wanted it to move left till left switch activated, then right till right switch activated then stops at home but it just moves left and right and not stopping at home

I am using Global variables from what I have read is BAD but seeing as this is only a short simple code thought it would work fine :?: :?: :?:


2)
I am controlling the gpio pins on the pi with keyboard using tkinter, I would like to in the end control the robot from a tablet so not sure how easy it would be for tkinter to interface with a mobile app, and if there is an easier/better solution for this ?

Hope someone could give advice or assistance

Thanks

I hope i have done the code tag right

Code: Select all

import RPi.GPIO as gpio
import sys
import time
import Tkinter as tk

def init():
    gpio.setmode(gpio.BOARD)
    gpio.setwarnings(False)
    gpio.setup(40, gpio.OUT) #Wheel motor
    gpio.setup(38, gpio.OUT) #Wheel motor
    gpio.setup(36, gpio.OUT) #wheel motor
    gpio.setup(32, gpio.OUT) #wheel motor
    gpio.setup(37, gpio.OUT) # LED
    gpio.setup(18, gpio.OUT) #head motor
    gpio.setup(16, gpio.OUT) #Head motor
    gpio.setup(35, gpio.IN, pull_up_down=gpio.PUD_UP) # Front Limit
    gpio.setup(33, gpio.IN, pull_up_down=gpio.PUD_UP) # Head Limit Left
    gpio.setup(31, gpio.IN, pull_up_down=gpio.PUD_UP) # Head Home switch
    gpio.setup(29, gpio.IN, pull_up_down=gpio.PUD_UP) # Head limit right
    

def led():
    gpio.output(37, gpio.HIGH)
    time.sleep(1)
    gpio.output(37, gpio.LOW)

#Define Body movement

def forward():
    gpio.output(40, True)
    gpio.output(38, False)
    gpio.output(36,True)
    gpio.output(32,False)
   

def reverse():
    gpio.output(40, False)
    gpio.output(38, True)
    gpio.output(36,False)
    gpio.output(32,True)

def turn_left():
    gpio.output(40, True)
    gpio.output(38, True)
    gpio.output(36, True)
    gpio.output(32, False)
    
    
def turn_right():
    gpio.output(40, True)
    gpio.output(38, False)
    gpio.output(36, False)
    gpio.output(32, False)

def pivot_left():
    gpio.output(40, False)
    gpio.output(38, True)
    gpio.output(36, True)
    gpio.output(32, False)
    

def pivot_right():
    gpio.output(40, True)
    gpio.output(38, False)
    gpio.output(36, False)
    gpio.output(32, True)

# Define head movement    

def head_right():
    gpio.output(18, True)
    gpio.output(16, False)
    
def head_left():
    gpio.output(18, False)
    gpio.output(16, True)
    

# All motors stop

def stop():
    gpio.output(40, False)
    gpio.output(38, False)
    gpio.output(36, False)
    gpio.output(32, False)
    gpio.output(18, False)
    gpio.output(16, False)

# Keyboard input

def key_input(event):
    init()
    if ord(event.char) == 27:
        gpio.cleanup()
        quit()
    key_press = event.char.lower()

    if key_press == 'w':
        forward()
    elif key_press == 's':
        reverse()
    elif key_press == 'a':
        turn_left()
    elif key_press == 'd':
        turn_right()
    elif key_press == 'q':
        pivot_left()
    elif key_press == 'e':
        pivot_right()
    elif key_press == 'n':
        head_left()
    elif key_press == 'm':
        head_right()    
    elif key_press == 'l':
        led()
    

def key_release(event):
    stop()

 # Set variables

x=1

 # Define Head limits


def stop_head():
    gpio.output(18, False)
    gpio.output(16, False)

    
def rotate_left(channel):
    global x
    x= (x+1)
    stop_head()	
    gpio.output(18, False)
    gpio.output(16, True)
    led()
   

def rotate_right(channel):
    global x
    x= (x+1)
    stop_head()
    gpio.output(18, True)
    gpio.output(16, False)
    led()



 # Define Main Limit

def flashing():
  count = 0
  while (count < 3):
    gpio.output(37, gpio.HIGH)
    time.sleep(1)
    gpio.output(37, gpio.LOW)
    count = count + 1

def limit(channel):
    global x
    x = 0
    stop_head()
    flashing()
    rotate_left(channel)
    
    
def home(channel):
    global x
    if x <= 1:
     pass
    if x == 2:
     stop_head()
     x = 1
    
    
init()    
gpio.add_event_detect(33, gpio.FALLING, callback=rotate_right, bouncetime=500)
gpio.add_event_detect(29, gpio.FALLING, callback=rotate_left, bouncetime=500)
gpio.add_event_detect(31, gpio.FALLING, callback=home, bouncetime=500)
gpio.add_event_detect(35, gpio.FALLING, callback=limit, bouncetime=500)


command = tk.Tk()
command.bind('<KeyPress>', key_input)
command.bind('<KeyRelease>', key_release)
command.mainloop()






User avatar
MrYsLab
Posts: 40
Joined: Mon Dec 15, 2014 7:14 pm
Location: Noo Joysey, USA

Re: Help with Python code interupts

Fri Jul 21, 2017 2:36 pm

For question 1:
I might be missing the obvious, but I just tried your code in simulation mode (removed all the GPIO stuff and replaced with prints) and never see the home function called. How and when is that called?

For question 2:
If you want to run on a tablet, will you be using WiFi or are you planning some other scheme?
In either case, there are at least 2 challenges to conquer for this:
A. Getting a GUI on the tablet.
B. Getting the GUI to communicate with the Pi.

I solved both of these issues in my robot project razmq https://github.com/MrYsLab/razmq

The project supplies 2 GUIs. One built with kivy (which is the prettier of the two, but I could not get the GUI to work on a tablet) and the other was built with remi https://github.com/dddomodossola/remi

The remi library allows you to build Web pages written totally in Python - no javascript, no css, no html. It really is quite magical.

You can bring up the remi GUI on a tablet by just entering the URL in the tablet's web browser (remi has its own web server that would be running on the Pi).

That solves the first problem, no on to the solution for the second. The razmq project is an earlier version of the Python Banyan Framework https://github.com/MrYsLab/python_banyan. It provides the network connectivity simply and easily. The remi GUI provided with the razmq project has all the communication stuff integrated with the GUI. Again, remi is a pleasure to use.

Take a look and if any of this is interesting, feel free to ask any questions you might have.

Sanchobob
Posts: 9
Joined: Fri Jul 21, 2017 7:30 am

Re: Help with Python code interupts

Fri Jul 21, 2017 4:12 pm

Hi MrYsLab

Thanks for the reply.

The Home function is called from

Code: Select all

gpio.add_event_detect(31, gpio.FALLING, callback=home, bouncetime=500)

which should call this function

Code: Select all

def home(channel):
    global x
    if x <= 1:
     pass
    if x == 2:
     stop_head()
     x = 1
Or am I looking at this wrong ?

With regards to the 2nd part I was thinking wifi- but I will take a look at the links you have posted before I make any decisions.

Thanks again

Sanchobob
Posts: 9
Joined: Fri Jul 21, 2017 7:30 am

Re: Help with Python code interupts

Fri Jul 21, 2017 4:41 pm

Forgot to ask when you say in simulation mode, i was using the blog with code but didnt like the gpio detect falling stuff

what is it you use to simulate ??

User avatar
MrYsLab
Posts: 40
Joined: Mon Dec 15, 2014 7:14 pm
Location: Noo Joysey, USA

Re: Help with Python code interupts

Fri Jul 21, 2017 5:11 pm

Sorry, I missed seeing that code. Not being familiar with your hardware design, are you sure that the home switch is being activated when operating the robot? What mechanically trigger it?

The "simulation" was just removing all the gpio code and replacing it with a print statement in each function. Not fancy, but allowed me to try the code out.

Again, if I can be of help, just ask.

Sanchobob
Posts: 9
Joined: Fri Jul 21, 2017 7:30 am

Re: Help with Python code interupts

Sun Jul 23, 2017 6:39 pm

Figured out what the issue is (removed all motors and sensors , used leds, manual switches and print)
and it is the Global variables

when the Limit switch is triggered I set x = 0

Code: Select all

def limit(channel):
    global x
    x = 0
    print x
    stop_head()
    flashing()
    rotate_left(channel)
But this is overwritten when function finishes and set to 1

Code: Select all

 # set variables

global x
x = 1
Which basically means the head only moves left then to home instead of left then right (going past home) then left stopping at home.



So back to the drawing board (google)

this is my main test code now until I get it right

Code: Select all

import RPi.GPIO as gpio
import time
import Tkinter as tk

def init():
    gpio.setmode(gpio.BOARD)
    gpio.setwarnings(False)
    gpio.setup(37, gpio.OUT) # Flashing LED
    gpio.setup(40, gpio.OUT) # LED Home switch
    gpio.setup(18, gpio.OUT) # LED Head right
    gpio.setup(16, gpio.OUT) # LED head left
    gpio.setup(35, gpio.IN, pull_up_down=gpio.PUD_UP) # Front Limit
    gpio.setup(33, gpio.IN, pull_up_down=gpio.PUD_UP) # Head Limit Left
    gpio.setup(31, gpio.IN, pull_up_down=gpio.PUD_UP) # Head Home switch
    gpio.setup(29, gpio.IN, pull_up_down=gpio.PUD_UP) # Head limit right
    

# Define head movement    

def head_right():
    gpio.output(16, gpio.LOW)
    gpio.output(18, gpio.HIGH)
    
    
def head_left():
    gpio.output(18, gpio.LOW)
    gpio.output(16, gpio.HIGH)
    
def stop_head():
    gpio.output(18, gpio.LOW)
    gpio.output(16, gpio.LOW)


 # set variables

global x
x = 1

 # Define Head limits

def rotate_left(channel):
    global x
    print x
    x= (x+1)
    stop_head()
    head_left()
   

def rotate_right(channel):
    global x
    print x
    x= (x+1)
    stop_head()
    head_right()
    



 # Define Main Limit

def flashing():
  count = 0
  while (count < 3):
    gpio.output(37, gpio.HIGH)
    time.sleep(1)
    gpio.output(37, gpio.LOW)
    count = count + 1

def limit(channel):
    global x
    x = 0
    print x
    stop_head()
    flashing()
    rotate_left(channel)
    
    
def home(channel):
    global x
    print x
    if x <= 1:
     pass
    if x == 2:
     stop_head()
     gpio.output(40, gpio.HIGH)
     time.sleep(1)
     gpio.output(40, gpio.LOW)
     x = 1
     print  x

def key_input(event):
    init()
    if ord(event.char) == 27:
        gpio.cleanup()
        quit()
    key_press = event.char.lower()

    if key_press == 'w':
        forward()
    elif key_press == 's':
        reverse()
    elif key_press == 'a':
        turn_left()
    elif key_press == 'd':
        turn_right()
    elif key_press == 'q':
        pivot_left()
    elif key_press == 'e':
        pivot_right()
    elif key_press == 'n':
        head_left()
    elif key_press == 'm':
        head_right()    
    elif key_press == 'l':
        led()
    

def key_release(event):
    stop()
init()
gpio.add_event_detect(33, gpio.FALLING, callback=rotate_right, bouncetime=500)
gpio.add_event_detect(29, gpio.FALLING, callback=rotate_left, bouncetime=500)
gpio.add_event_detect(31, gpio.FALLING, callback=home, bouncetime=500)
gpio.add_event_detect(35, gpio.FALLING, callback=limit, bouncetime=500)

command = tk.Tk()
command.bind('<KeyPress>', key_input)
command.bind('<KeyRelease>', key_release)
command.mainloop()
   






User avatar
MrYsLab
Posts: 40
Joined: Mon Dec 15, 2014 7:14 pm
Location: Noo Joysey, USA

Re: Help with Python code interupts

Sun Jul 23, 2017 8:43 pm

I don't know if this will make things more difficult for you or not, but I converted your original program to a python class.
If you are able to fix your problem and understand the fix, and find classes too confusing, please ignore this code.

Classes help get rid of global (truly evil things :D ). Your x variable is defined in the __init__ method and is common to all of the methods in the class.

For your flashing method, I am not sure, but I think during the flashing period, you may not have access to the keyboard. I don't know if that sleep will conflict with the tkinter mainloop or not.

Here is the code. If you have any questions please ask:

Code: Select all

import time

import RPi.GPIO as gpio
import Tkinter as tk


class Robot:
    def __init__(self):
        gpio.setmode(gpio.BOARD)
        gpio.setwarnings(False)
        gpio.setup(40, gpio.OUT)  # Wheel motor
        gpio.setup(38, gpio.OUT)  # Wheel motor
        gpio.setup(36, gpio.OUT)  # wheel motor
        gpio.setup(32, gpio.OUT)  # wheel motor
        gpio.setup(37, gpio.OUT)  # LED
        gpio.setup(18, gpio.OUT)  # head motor
        gpio.setup(16, gpio.OUT)  # Head motor
        gpio.setup(35, gpio.IN, pull_up_down=gpio.PUD_UP)  # Front Limit
        gpio.setup(33, gpio.IN, pull_up_down=gpio.PUD_UP)  # Head Limit Left
        gpio.setup(31, gpio.IN, pull_up_down=gpio.PUD_UP)  # Head Home switch
        gpio.setup(29, gpio.IN, pull_up_down=gpio.PUD_UP)  # Head limit right

        gpio.add_event_detect(33, gpio.FALLING, callback=self.rotate_right, bouncetime=500)
        gpio.add_event_detect(29, gpio.FALLING, callback=self.rotate_left, bouncetime=500)
        gpio.add_event_detect(31, gpio.FALLING, callback=self.home, bouncetime=500)
        gpio.add_event_detect(35, gpio.FALLING, callback=self.limit, bouncetime=500)

        self.x = 1

        self.command = tk.Tk()
        self.command.bind('<KeyPress>', self.key_input)
        self.command.bind('<KeyRelease>', self.key_release)
        self.command.mainloop()

    def key_input(self, event):
        if ord(event.char) == 27:
            gpio.cleanup()
            quit()
        key_press = event.char.lower()

        if key_press == 'w':
            self.forward()
        elif key_press == 's':
            self.reverse()
        elif key_press == 'a':
            self.turn_left()
        elif key_press == 'd':
            self.turn_right()
        elif key_press == 'q':
            self.pivot_left()
        elif key_press == 'e':
            self.pivot_right()
        elif key_press == 'n':
            self.head_left()
        elif key_press == 'm':
            self.head_right()
        elif key_press == 'l':
            self.led()

    def key_release(self, event):
        self.stop()

    def led(self):
        print('LED High')
        gpio.output(37, gpio.HIGH)
        time.sleep(1)
        gpio.output(37, gpio.LOW)
        print('LED High')

    # Define Body movement

    def forward(self):
        print('forward')
        gpio.output(40, True)
        gpio.output(38, False)
        gpio.output(36, True)
        gpio.output(32, False)

    def reverse(self):
        print('reverse')
        gpio.output(40, False)
        gpio.output(38, True)
        gpio.output(36, False)
        gpio.output(32, True)

    def turn_left(self):
        print('turn_left')
        gpio.output(40, True)
        gpio.output(38, True)
        gpio.output(36, True)
        gpio.output(32, False)

    def turn_right(self):
        print('turn right')
        gpio.output(40, True)
        gpio.output(38, False)
        gpio.output(36, False)
        gpio.output(32, False)

    def pivot_left(self):
        print('pivot_left')
        gpio.output(40, False)
        gpio.output(38, True)
        gpio.output(36, True)
        gpio.output(32, False)

    def pivot_right(self):
        gpio.output(40, True)
        gpio.output(38, False)
        gpio.output(36, False)
        gpio.output(32, True)

    # Define head movement

    def head_right(self):
        gpio.output(18, True)
        gpio.output(16, False)

    def head_left(self):
        gpio.output(18, False)
        gpio.output(16, True)

    # All motors stop

    def stop(self):
        gpio.output(40, False)
        gpio.output(38, False)
        gpio.output(36, False)
        gpio.output(32, False)
        gpio.output(18, False)
        gpio.output(16, False)

    def stop_head(self):
        gpio.output(18, False)
        gpio.output(16, False)

    def rotate_left(self, channel):
        self.x += 1
        self.stop_head()
        gpio.output(18, False)
        gpio.output(16, True)
        self.led()

    def rotate_right(self, channel):
        self.x += 1
        self.stop_head()
        gpio.output(18, True)
        gpio.output(16, False)
        self.led()

        # Define Main Limit

    def flashing(self):
        count = 0
        while count < 3:
            gpio.output(37, gpio.HIGH)
            time.sleep(1)
            gpio.output(37, gpio.LOW)
            count = count + 1

    def limit(self, channel):
        self.x = 0
        self.stop_head()
        self.flashing()
        self.rotate_left(channel)

    def home(self, channel):
        if self.x <= 1:
            pass
        if self.x == 2:
            self.stop_head()
            self.x = 1

# instantiate a Robot object to start the program
my_robot = Robot()


Sanchobob
Posts: 9
Joined: Fri Jul 21, 2017 7:30 am

Re: Help with Python code interupts

Mon Jul 24, 2017 8:18 am

Hi MrYsLab

I have figured out where my mistake is set x = 0 is in the wrong place as when the rotate_left function is called it performs x+1
so have set x=0 after this function and now works,
just need to test it with motor and then finally all together

Thanks for the class code, theres no harm in having 2 options

User avatar
MrYsLab
Posts: 40
Joined: Mon Dec 15, 2014 7:14 pm
Location: Noo Joysey, USA

Re: Help with Python code interupts

Mon Jul 24, 2017 1:25 pm

Glad you figured it out. BTW, the class I provided is unlikely to work since it contains the same logic as your original file. Once you get your code working, if you wish apply the same changes to the class and it too should work.

Sanchobob
Posts: 9
Joined: Fri Jul 21, 2017 7:30 am

Re: Help with Python code interupts

Thu Jul 27, 2017 2:26 pm

Yes they both worked but will need to have a look into Classes to get my head round it.
But now I have found another issue, the limit interupts can be stopped with a keyboard entry

Code: Select all

def key_input(event):
if .....

def key_release(event):
    stop()
So now to figure out how to stop keyboard inputs when the limit switch triggers until the home switch is activated and then start it again.

Thinking about nesting the key_input IF loop inside a WHILE loop or maybe THREADING ?????

If you could point me in the right direction .

Thanks

User avatar
MrYsLab
Posts: 40
Joined: Mon Dec 15, 2014 7:14 pm
Location: Noo Joysey, USA

Re: Help with Python code interupts

Thu Jul 27, 2017 3:39 pm

Don't worry about using classes, since they are just another way of organizing things. They have other uses as well, such as inheritance, but since you don't need that here, just keep things within your understanding.

I am not sure I am totally understanding the challenge you are facing. Are you losing limit notifications because you are blocked by keyboard input or getting the notifications but just don't get around to processing until after keyboard processing is complete?

If it is the former, threading is one solution to the problem.

If it is the latter, you can break into the tkinter event loop by using the "after" method of tkinter. To see a usage example, please look at https://github.com/MrYsLab/xibot/blob/m ... tk/xitk.py.
Don't get bogged down in the code - the important parts are:
Line 192. This call tells the mainloop to wait 5 ms and then the mainloop calls a method provided by the user.

Line 540. This is my user method. It rearms the "after" method to fire again in 1 ms.

If I totally missed your question or if you have any other questions, please let me know.

Sanchobob
Posts: 9
Joined: Fri Jul 21, 2017 7:30 am

Re: Help with Python code interupts

Sat Jul 29, 2017 7:08 am

The issue was when the limit is activated the motor turns but the keyboard inputs are still active and can stop the limit function before it has completed.

i have managed to solve this with setting another variable y when the limits triggered

Code: Select all

def key_input(self, event):
        if ord(event.char) == 27:
            gpio.cleanup()
            quit()
        key_press = event.char.lower()

        if self.y == 0:
            if key_press == 'n':
             self.head_left()
            elif key_press == 'm':
             self.head_right()
            elif key_press == 'l':
             self.panic()
        else:
           pass

    def key_release(self, event):
        if self.y == 0:
             self.stop_head()
        else:
            pass
This didnt seem to work with the global variables, no matter what line i put global y in this part of the code it still errors already set.( maybe why global variables is not recommended)

So your Class code has come in handy

Thanks again.

I have decided to add some audio so now off to figure this out
Little project is now getting bigger :o :o :o

Sanchobob
Posts: 9
Joined: Fri Jul 21, 2017 7:30 am

Re: Help with Python code interupts

Mon Jul 31, 2017 2:34 pm

Hi

I split code into 2 scripts to save trying to figure out how to have the body keyboard inputs active without stopping the head limit function

the issue that this created is that it opens 2 tk windows and will take input from the window that is active.

i have done a bit of looking and can have 2 scripts running in 1 window which i think is correct

No sure about if things are called correctly,

If you could take a look at my code and advise
Even if i have to post it in a different section
Thanks


This is the main/primary script

Code: Select all

import time
import RPi.GPIO as gpio
import Tkinter as tk
import os
import random 
from Tkinter import*
from headclass import Right

class Left(Frame):
	def _init_(self, parent):
		Frame._init_(self, parent, width=100, height=100)
		self.config(bg='white')
        
class Body:
        def __init__(self):
        gpio.setmode(gpio.BOARD)
        gpio.setwarnings(False)
        gpio.setup(40, gpio.OUT) #Wheel motor
        gpio.setup(38, gpio.OUT) #Wheel motor
        gpio.setup(36, gpio.OUT) #wheel motor
        gpio.setup(32, gpio.OUT) #wheel motor
        gpio.setup(37, gpio.IN, pull_up_down=gpio.PUD_UP) # MAIN limit

        gpio.add_event_detect(37, gpio.FALLING, callback=self.trigger, bouncetime=1500)

        self.y = 0

        self.command = tk.Tk()
        self.command.bind('<KeyPress>', self.key_input)
        self.command.bind('<KeyRelease>', self.key_release)
        self.command.mainloop()

# Define keyboard inputs   

    def key_input(self, event):
        if ord(event.char) == 27:
            gpio.cleanup()
            quit()
        key_press = event.char.lower()

        if self.y == 0:
            if key_press == 'w':
              self.forward()
            elif key_press == 's':
              self.reverse()
            elif key_press == 'a':
              self.turn_left()
	        elif key_press == 'd':
              self.turn_right()
            elif key_press == 'q':
              self.pivot_left()
	        elif key_press == 'e':
              self.pivot_right()
            elif key_press == '1':
              self.rndmp3()
            elif key_press == '2':
              self.daddy()
	        elif key_press == '3':
              self.leader()
            elif key_press == '4':
              self.dark()
	        elif key_press == '5':
              self.junk()
            
        else:
           pass

    def key_release(self, event):
        if self.y == 0:
             self.stop_body()
        else:
            pass

# Define Audio

    def rndmp3(self):
	    randomfile = random.choice(os.listdir("/home/pi/R2D2/Working//Random/"))
	    file = '/home/pi/R2D2/Working/Random/' + randomfile
	    os.system ('omxplayer -o local ' + file)

    def dark(self):
	     os.system('omxplayer -o local Dark.mp3 &')

    def junk(self):
	     os.system('omxplayer -o local Junk.mp3 &')

    def daddy(self):
	    os.system('omxplayer -o local daddy.MP3 &')

    def leader(self):
	    os.system('omxplayer -o local leader.MP3 &')

    def scream(self):
        os.system('omxplayer -o local Scream.mp3 &')
    
 # Define body movement

    def forward(self):
    	gpio.output(40, True)
    	gpio.output(38, False)
   	    gpio.output(36,True)
    	gpio.output(32,False)
   

    def reverse(self):
    	gpio.output(40, False)
    	gpio.output(38, True)
    	gpio.output(36,False)
    	gpio.output(32,True)

    def turn_left(self):
    	gpio.output(40, True)
   	    gpio.output(38, True)
   	    gpio.output(36, True)
    	gpio.output(32, False)
    
    
    def turn_right(self):
    	gpio.output(40, True)
    	gpio.output(38, False)
    	gpio.output(36, False)
    	gpio.output(32, False)

    def pivot_left(self):
    	gpio.output(40, False)
    	gpio.output(38, True)
    	gpio.output(36, True)
    	gpio.output(32, False)
    

    def pivot_right(self):
    	gpio.output(40, True)
    	gpio.output(38, False)
    	gpio.output(36, False)
    	gpio.output(32, True)

    def stop_body(self):
	    gpio.output(40, False)
        gpio.output(38, False)
        gpio.output(36, False)
        gpio.output(32, False)

  # Define Main Limit

    def trip(self):
        self.stop_body()
        self.scream()
	    self.reverse()
	    time.sleep(3)
	    self.stop_body()
    

    def trigger(self, channel):
        self.y = 1
        self.trip()
        self.y = 0

    

# instantiate a Robot object to start the program
my_robot = Body()


if _name_ == "_main_":
	root = Tk()
	Left(root).pack(side=LEFT)
	Right(root).pack(side=RIGHT)
	root.mainloop()
and this is the secondary script

Code: Select all

import time
import RPi.GPIO as gpio
import Tkinter as tk
import os
from Tkinter import *

class Right(Frame):
  def_init_(self, parent):
    Frame._init_(self, parent, width=100, height=100)
    self.config(bg='black')
    
    
class Head:
    def __init__(self):
        gpio.setmode(gpio.BOARD)
        gpio.setwarnings(False)
        gpio.setup(11, gpio.OUT) # Flashing LED
        gpio.setup(13, gpio.OUT) # LED Home switch
        gpio.setup(16, gpio.OUT) #Head Motor
        gpio.setup(18, gpio.OUT) #Head Motor
        gpio.setup(31, gpio.IN, pull_up_down=gpio.PUD_UP) #Right Head limit
        gpio.setup(33, gpio.IN, pull_up_down=gpio.PUD_UP) #Head Home limit
        gpio.setup(35, gpio.IN, pull_up_down=gpio.PUD_UP) #Left Head limit
        gpio.setup(37, gpio.IN, pull_up_down=gpio.PUD_UP) # MAIN limit

        gpio.add_event_detect(31, gpio.FALLING, callback=self.rotate_left, bouncetime=1500)
        gpio.add_event_detect(33, gpio.FALLING, callback=self.home, bouncetime=1500)
        gpio.add_event_detect(35, gpio.FALLING, callback=self.rotate_right, bouncetime=1500)
        gpio.add_event_detect(37, gpio.FALLING, callback=self.limit, bouncetime=1500)

        self.x = 1
        self.y = 0

        self.command = tk.Tk()
        self.command.bind('<KeyPress>', self.key_input)
        self.command.bind('<KeyRelease>', self.key_release)
        self.command.mainloop()

# DEFINE KEY INPUT    

    def key_input(self, event):
        if ord(event.char) == 27:
            gpio.cleanup()
            quit()
        key_press = event.char.lower()

        if self.y == 0:
            if key_press == 'n':
             self.head_left()
            elif key_press == 'm':
             self.head_right()
            elif key_press == 'l':
             self.panic()
        else:
           pass

    def key_release(self, event):
        if self.y == 0:
             self.stop_head()
        else:
            pass
# Define audio 

    def beep(self):
	os.system('omxplayer -o local Surprised.mp3 &')

    def beepstop(self):
	os.system('omxplayer -o local beepstop.mp3 &')

#define LEDS

    def led(self):
        gpio.output(11, gpio.HIGH)
        time.sleep(1)
        gpio.output(11, gpio.LOW)

    def home_led(self):
        gpio.output(13, gpio.HIGH)
        time.sleep(1)
        gpio.output(13, gpio.LOW)

    def panic(self):
        count = 0
        while (count < 4):
            gpio.output(11, gpio.HIGH)
            time.sleep(0.5)
            gpio.output(11, gpio.LOW)
            gpio.output(13, gpio.HIGH)
            time.sleep(0.5)
            gpio.output(13, gpio.LOW)
            count = count + 1

 # Define head movement

    def head_right(self):
        gpio.output(18, True)
        gpio.output(16, False)

    def head_left(self):
        gpio.output(18, False)
        gpio.output(16, True)


    def stop_head(self):
        gpio.output(18, False)
        gpio.output(16, False)

#Define Head limits

    def rotate_left(self, channel):
        self.x += 1
        self.y = 1
        self.stop_head()
	    self.beep()
        self.head_left()
        self.led()

    def rotate_right(self, channel):
        self.x += 1
        self.y = 1
        self.stop_head()
	    self.beep()
        self.head_right()
        self.led()

 # Define Main Limit

    def flashing(self):
        count = 0
        while count < 3:
            gpio.output(13, gpio.HIGH)
            time.sleep(1)
            gpio.output(13, gpio.LOW)
            count = count + 1

    def limit(self, channel):
        self.y = 1
        self.stop_head()
        self.rotate_left(channel)
        self.flashing()
        self.x = 0

    def home(self, channel):
        if self.x <= 1:
            pass
        if self.x == 2:
            self.stop_head()
            self.home_led()
	        self.beepstop()
            self.x = 1
            self.y = 0

# instantiate a Robot object to start the program
my_robot = Head()

User avatar
MrYsLab
Posts: 40
Joined: Mon Dec 15, 2014 7:14 pm
Location: Noo Joysey, USA

Re: Help with Python code interupts

Mon Jul 31, 2017 3:42 pm

I am not sure if I understand your 2 frame approach. Let me restate what I think your problem is:

When interacting with the keyboard, you want to make sure that you don't miss a limit switch event.
If that is not correct, please explain again, but if it is, please continue on.

What I have done in the code below is create a very simple program that will create a tk window with a single button that is used to kill the program.
This program adds a keyboard listener and simply prints out the "value" of the key that was pressed. In addition, I wired up a switch to BCM pin 11 of my RPi to simulate your limit switch. I am using pigpio and its digital input callback feature. You should be able to convert this to RPi.GPIO calls. If you want to run the code without changes, you will need to first start the pigpio daemon using the following command:

Code: Select all

sudo pigpiod
And now on to my code. I tested by holding a key down and seeing that its value was continuously printed to the console. I then, at random times, closed the switch attached to BCM 11 and when I did, I a message on the console showing me that the switch was closed.

Let me know if this solves your problem or not.

Code: Select all

from Tkinter import Tk, Button
import pigpio
import sys


class TkPlay:
    def __init__(self):

        self.button_pin = 11  # assign a switch to a gpio pin

        self.pi = pigpio.pi()

        # set the glitch filter to debounce the switch
        self.pi.set_glitch_filter(self.button_pin, 20000)

        # set the pin mode as input and react to both ed
        self.pi.set_mode(self.button_pin, pigpio.INPUT)
        self.pi.callback(self.button_pin, pigpio.RISING_EDGE, self.button_callback)

        self.root = Tk()
        self.root.title("A simple GUI")

        self.close_button = Button(self.root, text="Close", command=self.quit)
        self.close_button.pack()

        self.root.bind('<KeyPress>', self.key_input)
        self.root.mainloop()

    def quit(self):
        self.root.quit()
        sys.exit(0)

    def key_input(self, event):
        key_press = event.char.lower()
        print(key_press)

    def button_callback(self, pin, level, tick):
        print('pressed')


TkPlay()


Sanchobob
Posts: 9
Joined: Fri Jul 21, 2017 7:30 am

Re: Help with Python code interupts

Wed Aug 09, 2017 7:51 pm

Managed to get it sorted :D added another variable, had to add a little bit to the code and is about 99 % what i want it to do but seeing as its a simple robot project I can live with it

Now to put it all back together

Thanks for your input

you will probably hear from me again when I start looking at this remi GUI

User avatar
MrYsLab
Posts: 40
Joined: Mon Dec 15, 2014 7:14 pm
Location: Noo Joysey, USA

Re: Help with Python code interupts

Thu Aug 10, 2017 3:30 pm

That's great. I find the fastest way to deal with Remi is to use the editor they supply since it will generate 95% of the code. I have not developed with it directly on the Rpi, but I have worked on my PC and then just moved the files. It should be fine, but might be a little slow.

Alan

Return to “Python”

Who is online

Users browsing this forum: No registered users and 13 guests