Raspberry Pi fan, Chuck Elliot, has been kind enough to send me a little GUI simulation for use with the Lessons.
This is an excellent idea and should allow everyone to have a go even if they don’t have the hardware. It also underlines some of the concepts mentioned in Lesson 1 about being able to test and develop without hardware (an essential tool in a programmers toolbox).
Over to Chuck:
I got a RPI as a Christmas present. I’ve been learning Python since then and decided to expand upon your GPIO simulation with a hardware simulator. The enclosed version of [the] project uses Tkinker and threads to present the LEDSs on a GUI.
Now bear in mind this is only a quick little test GUI, so it isn’t as modular as it could be and only basic colour mixing is supported so far. It is something which can be developed and improved as we go, with a little bit of work, a plug-in test module should be more than possible. Threads, Tkinker and Classes are all topics I am planning to cover in coming weeks, so I’ll leave the detail of it for now and just cover how to use it.
We may even pick this up as a pet project at a later date, to apply some of the things we have learnt (although Chuck may continue developing it anyway).
How to use the GUI
Within your application program (rgbledcontrol.py) you will need to make the following changes:
- Add imports at the top, for threading and start_gui from our to be created testGUI.
- Rename our main() function to be actions()
- Create a class led_tasks to run our actions() function as a separate thread.
- Create a new main() function, which runs the led_tasks thread and the new test GUI.
The result is your file will be similar to this (what you have in your actions() function may vary slightly if you’ve experimented, which should be fine):
rgbledcontrol.py:
#!/usr/bin/python #Python Version 2.* # rgbledcontrol.py # Test program to show the use of libaries import threading from testGUI import start_gui import time import rgbled as RGBLED some_leds = [RGBLED.LED1,RGBLED.LED3,RGBLED.LED5] sequence_leds = [RGBLED.LED1,RGBLED.LED2,RGBLED.LED3,RGBLED.LED4,RGBLED.LED5,RGBLED.LED4,RGBLED.LED3,RGBLED.LED2] def actions(): print "Setup the RGB module" RGBLED.led_setup() print "Switch on LED1 RED" RGBLED.led_time(RGBLED.LED1,RGBLED.RGB_RED,1) time.sleep(0.5) print "Switch on LED2 MAGENTA" RGBLED.led_time(RGBLED.LED2,RGBLED.RGB_MAGENTA,1) time.sleep(0.5) print "Switch on 1,3,5 WHITE" RGBLED.led_time(some_leds,RGBLED.RGB_WHITE,1) print "Random RGB over all LEDs" for i in range(10): for j in sequence_leds: RGBLED.led_rgbrandom(j,0.1,3) #Select from R/G/B print "Finished" RGBLED.led_cleanup() #Class to run our actions in a thread class led_tasks( threading.Thread ): def run (self): time.sleep(1) # Wait a bit to be sure the GUI has set up actions() #Run our required actions def main(): led_tasks().start() # Start the test sequence start_gui() # Will not return until GUI killed print("Exit GUI") main()
testRPiGPIO.py:
Add the following definition for pins above the functions, and set the value within the output() function, as follows:
pins = [0] * 30 def output(pin,value): print pin, ":", value pins[pin] = value
rgbled.py:
Be sure the testRPiGPIO import is active (remove #), and making sure RPi.GPIO is commented out with # at the start of the line.
#import RPi.GPIO as GPIO #Use for Raspberry Pi GPIO import testRPiGPIO as GPIO #Use for Debugging GPIO
Create a new file called testGUI.py:
Note: Due to differences with Python versions, you’ll need to include either Tkinter for python 2.* or tkinter for python 3+
#!/usr/bin/python #Python Version 2.* from Tkinter import * #Note Tkinter for python 2.*, tkinter for python 3+ import rgbled as RGBLED from testRPiGPIO import pins BUTTON1 = 0 BUTTON2 = 1 BUTTON3 = 2 BUTTON4 = 3 BUTTON5 = 4 LED_ON = 0 LED_OFF = 1 buttonLEDPairs = ( (BUTTON1, RGBLED.LED1), (BUTTON2, RGBLED.LED2), (BUTTON3, RGBLED.LED3), (BUTTON4, RGBLED.LED4), (BUTTON5, RGBLED.LED5) ) buttonList = ( BUTTON1, BUTTON2, BUTTON3, BUTTON4, BUTTON5 ) colorNames = ( 'black', # 0 'blue', # 1 'green', # 2 'cyan', # 3 'red', # 4 'magenta', # 5 'yellow', # 6 'white' # 7 ) buttonWidgets = [0] * 5 root = Tk() def update_gui(): for buttonLEDPair in buttonLEDPairs: buttonNumber = buttonLEDPair[0] ledPin = buttonLEDPair[1] colorName = colorNames[0] #default to black if pins[ledPin] == LED_ON: #Is the LED pin on? colorIndex = (pins[RGBLED.RGB_RED] << 2) + (pins[RGBLED.RGB_GREEN] << 1) + pins[RGBLED.RGB_BLUE] colorName = colorNames[colorIndex] buttonWidgets[buttonNumber].config(bg=colorName) root.after(50, update_gui) #queue up to run again def start_gui(): fraMain = Frame(root) fraMain.pack() for buttonNumber in buttonList: buttonWidgets[buttonNumber] = Button(fraMain, height=2, width = 4) buttonWidgets[buttonNumber].pack(side=LEFT) update_gui() root.mainloop() #end
To revert back to using the GPIO, simply switch over the import of testRPiGPIO with RPi.GPIO (the GUI will still start, but the LEDs will light instead) with rgbled.py.
You can also remove start_gui() if you don’t want the GUI to start either.
import RPi.GPIO as GPIO #Use for Raspberry Pi GPIO #import testRPiGPIO as GPIO #Use for Debugging GPIO
Enjoy!