Wednesday, 15 June 2016

RaspberryPi GPIO Pulse Generator - Windows Based

Background

In one of my previous posts - RaspberryPi Pulse Generator Console Based, I put together a simple Python3 script to take user input supplied parameters to have the RaspberryPi generate pulses from a GPIO port.

Whilst this was adequate for simple applications it had the drawback of having to supply the parameters via keyboard every time. This method of use was also prone to errors due to the entry of incorrect port numbers.

I decided to experiment with the idea of creating a Windows interface to capture user supplied input with the use of a mouse click to start the pulse generator.

I re-used some of the Pulse Generator code and Windows code from the GPIO Ports Set & Toggle application. Some new code was required in order to allow the capture of user input into entry boxes.

Some screen shots are provided below that illustrate the 4 user input areas:
1. GPIO port number
2. Pulse length (the 'on' or 'high' time)
3. Pulse inter-space length (the 'off' or 'low' time)
4. Number of pulses

A button to 'Generate' the pulse(s) and a Quit button to exit the application.

The advantage of providing the 'Generate' button is the ability to create the pulse stream by one click of the mouse. Once the pulse stream has been completed, the generate button can be used again. If the pulse parameters need modifying it is a simple case of changing the value in the relevant input box.

One additional piece of code I included was to check the port number supplied was valid to be used as an output port.


Start-up Window


Parameters entered - pulses generated - and previous values shown



Incorrect Port number with error message when 'Generate' selected

It is possible to run more than one instance of this application using the format:

python3 <filename.py> &

This allows multiple GPIO ports to be used to generate separate pulse streams.

It is important when connecting GPIO ports to external circuits that appropriate interfacing is provided. In the case of connecting +3.3v RaspberryPi GPIO ports to external +5v TTL or CMOS components I prefer to use the CMOS 4050 Hex buffer as detailed in my other blog posts (see the GPIO Set & Toggle example).


Python3 code:

Here is the Python3 code listing for this application. The file can be downloaded from here.

# Python3 script to run on RaspberryPi B to enter pulse parameters within a Window
# Apply the parameters to a RaspberryPi B GPIO port in order to generate a pulse stream
# Port numbers are validated as those available to use as outputs:
# numbers 0,1,4,7,8,9,10,11,14,15,17,18,21,22,23,24,25
# Entered parameters are displayed next to the input areas
# Error message provided if invalid port number entered

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

GPIO.setwarnings(False)
GPIO.cleanup()
GPIO.setmode(GPIO.BCM)

def pulse_gen():
    portlist = ['0','1','4','7','8','9','10','11','14','15','17','18','21','22','23','24','25'] # string list of valid ports available
    ps=(portstr.get()) # get the entered value as a string
    if ps not in portlist: # check if entered value not in list              
        label6=Label(myGUI, text='Invalid port', fg='red').grid(row=1,column=2)
        return # if invalid do not proceed    
    port=int(portstr.get())
    label10=Label(myGUI, text="                  ").grid(row=1,column=2)
    label6=Label(myGUI, text=ps, fg='red').grid(row=1,column=2)
    length=float(lengthstr.get()) # get pulse duration
    label7a=Label(myGUI, text="                  ").grid(row=2,column=2)
    label7=Label(myGUI, text=length, fg='red').grid(row=2,column=2)
    space=float(spacestr.get()) # get intra pulse duration
    label8a=Label(myGUI, text="                  ").grid(row=3,column=2)
    label8=Label(myGUI, text=space, fg='red').grid(row=3,column=2)
    number=int(numberstr.get()) # get number of pulses
    label9a=Label(myGUI, text="                  ").grid(row=4,column=2)
    label9=Label(myGUI, text=number, fg='red').grid(row=4,column=2)

    GPIO.setup(port,GPIO.OUT)
    GPIO.output(port,GPIO.LOW)
    loop = 0
    while loop < number:
        GPIO.output(port,GPIO.HIGH)
        time.sleep(length)
        GPIO.output(port,GPIO.LOW)
        time.sleep(space)
        loop += 1
    return

def finish():
    myGUI.destroy()
    GPIO.cleanup()

myGUI = Tk()
myGUI.geometry('500x170')
myGUI.title('RPi B GPIO Pulse Generator')
myGUI.resizable(0,0)

portstr=StringVar()
lengthstr=StringVar()
spacestr=StringVar()
numberstr=StringVar()

label1=Label(myGUI, text='RaspberryPi Pulse Generator', fg='black').grid(row=0,column=0)
label1a=Label(myGUI, text='Enter values', fg='black').grid(row=0,column=1)
label1b=Label(myGUI, text='Last values', fg='black').grid(row=0,column=2)
label2=Label(myGUI, text='Enter valid GPIO port number').grid(row=1,column=0)
label3=Label(myGUI, text='Enter pulse length (secs)').grid(row=2,column=0)
label4=Label(myGUI, text='Enter pulse inter-space (secs)').grid(row=3,column=0)
label5=Label(myGUI, text='Enter number of pulses').grid(row=4,column=0)

portgpio=Entry(myGUI, textvariable=portstr).grid(row=1,column=1)
lengthgpio=Entry(myGUI, textvariable=lengthstr).grid(row=2,column=1)
spacegpio=Entry(myGUI, textvariable=spacestr).grid(row=3,column=1)
numbergpio=Entry(myGUI, textvariable=numberstr).grid(row=4,column=1)

button1=Button(myGUI,text='Generate', fg='blue', command=pulse_gen).grid(row=5,column=0)
button2=Button(myGUI,text='Quit', fg='red', command=finish).grid(row=6,column=0)

myGUI.mainloop()

No comments:

Post a Comment