After just messing about and experimenting with my Sense Hat a bit I had a short python script that just loaded each ‘.png’ file it found in the current directory and displayed it on the 8×8 LED matrix.
#!/usr/bin/python import time _sense = sense_hat.SenseHat() _sense.set_rotation(180) # Optional _sense.low_light = True # Optional - but a good idea try: while True: # Repeats forever (until an exception is raised) for _file in glob.glob("*.png"): _sense.load_image(_file) # Load the image and display it print _file # Display filename - optional time.sleep(2) # Wait two seconds except KeyboardInterrupt: # User pressed Ctrl-C so exit _sense.clear() raise SystemExit
Note – For this to work each image must be 8×8 pixels.
Though quite it is quite fun to see the minecraft characters shown on the Sense Hat’s display it soon got a bit tedious – two seconds can quickly start to seem like a long time when nothing is happening!
What I decided I really wanted was to be able to do was press a key to get the program to display the next image immediately. I couldn’t find a routine that would let me do this, though I did find a couple of articles on ‘StackOverflow’ that each solved half the problem, so all I had to do was join up the dots (or is it pixels…).
The result a function that waits for a specified number of seconds (or indefinitely if less than one second is specified) and returns the character code corresponding to the key that the user pressed or a ‘null’ character if there was no input.
Note – This only works on Linux though I think it could be made to work in Windows quite easily.
#!/usr/bin/python # # pi-sense-slideshow # # Attempts to display every '.png' file in the current directory on the LED # display of the Sense Hat. Obviously each image can only be 8x8 pixels but # much silliness can still be had using the faces of Minecraft characters, # however - some look better than others! # # This program is free software: you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation, either version 3 of the License, or (at your # option) any later version. # # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General # Public License for more details. # # You should have received a copy of the GNU General Public License along # with this program. If not, see <http://www.gnu.org/licenses/>. # import glob, sense_hat def _get_char(_timeout): # # get_char # # Note - This only works on Linux. # # Sets up a signal to interrupt the program when the specified timeout has # elapsed. It then configures the terminal so that it just reads a single # character from stdin and waits until the for the user to press a key, or # for the signal to interrupt program execution. # # If the user presses a key before the signal fires then the signal is # cancelled and the terminal characteristics restored before the character # code fo the key that was pressed is returned. # # If the signal fires then this raises an exception, which causes the # program to stop waiting for the user to press a key, cancels the signal, # restores the terminal characteristics and returns a null character. # # Finally if the user pressed Ctrl-C then a 'Keyboard Interrupt' exception # is raised. # # Although it is self-contained the amount of work that has to be done each # time the routine is called makes it quite inefficient - if it was to be # used heavily then the code to set up and restore the terminal state should # really be moved to separate routines. # import termios, fcntl, sys, os import signal def _interrupt(_signum, _frame): raise Exception("") _char ='\x00' # Set up the default if _timeout < 0: _timeout = 0 signal.signal(signal.SIGALRM, _interrupt) if _timeout > 0: signal.alarm(_timeout) # Set the timeout try: _filedescriptor = sys.stdin.fileno() # Save current terminal state _backup_flags = fcntl.fcntl(_filedescriptor, fcntl.F_GETFL) _backup_attrs = termios.tcgetattr(_filedescriptor) # Modify terminal attributes - see termios(3) man page. _new_attrs = list(_backup_attrs) # Use a copy of the backup # - iflag _new_attrs &= ~(termios.IGNBRK | termios.BRKINT | termios.PARMRK | termios.ISTRIP | termios.INLCR | termios. IGNCR | termios.ICRNL | termios.IXON ) # - oflag _new_attrs &= ~termios.OPOST # - cflag _new_attrs &= ~(termios.CSIZE | termios. PARENB) _new_attrs |= termios.CS8 # - lflag _new_attrs &= ~(termios.ECHONL | termios.ECHO | termios.ICANON | termios.ISIG | termios.IEXTEN) # Set terminal attributes termios.tcsetattr(_filedescriptor, termios.TCSANOW, _new_attrs) # Turn off non-blocking fcntl.fcntl(_filedescriptor, fcntl.F_SETFL, _backup_flags & ~os.O_NONBLOCK) # Wait for a keystroke _char = sys.stdin.read(1) except: # If an exception is raised (by the signal) pass finally: # Disable the signal and restore the terminal state signal.alarm(0) termios.tcsetattr(_filedescriptor, termios.TCSAFLUSH, _backup_attrs) fcntl.fcntl(_filedescriptor, fcntl.F_SETFL, _backup_flags) if _char == '\x03': raise KeyboardInterrupt return _char _sense = sense_hat.SenseHat() _sense.set_rotation(180) # Optional _sense.low_light = True # Optional - but a good idea try: while True: # Repeats forever (until an exception is raised) for _file in glob.glob("*.png"): _sense.load_image(_file) # Load the image and display it print _file # Display filename - optional _get_char(2) # Wait two seconds for the user to press a key except KeyboardInterrupt: # User pressed Ctrl-C so exit _sense.clear() # Clear the display raise SystemExit
The code in this post is based on the following posts:
# My thanks to the authors for their write-ups.
Raspberry Pi is a trademark of the Raspberry Pi Foundation