I recently decided to play around with the PiTFT screen and create a Raspberry Pi PiTFT PyGame Monitoring Screen to monitor my home environment.
For this I am using the following:
- Raspberry Pi 2B
- Adafruit 2.8″ PiTFT capacative touch screen – https://www.adafruit.com/products/1983
- 3D Printed Case – http://www.thingiverse.com/thing:802232
- Edimax Wifi EW-7811Un USB Dongle
Initial Raspberry Pi and PiTFT Setup
The first thing to do, is setup your raspberry pi. Adafruit have a great guide on getting setup here. Follow these instructions to get your Raspberry Pi setup. Change the hostname / password and install updates here.
Controlling the PiTFT Backlight
I wanted to leave this running 24/7 and wanted to be able to turn the screen off after inactivity and turn it on only when the user presses the screen. To do this you need to enable the PiTFT backlight control. If you have the resistive version, I believe you can skip this step, but for the capacitive screen you will need to solder a connection on the back of the board. Adafruits instructions are here.
Creating the Status Monitoring Screen
I used pygame to create my status screen. Its really easy to use and the instructions here are to get that working. Adafruit also have a great guide for this too here. Follow the instructions and you should be able to fill the screen with a particular colour.
The Monitoring Script
I code below will create a blank screen and draw the time in the middle as text. It will also turn the screen off after a minute and turn it back on if the screen is pressed. It also has a thread that should be used to update any values that you want to display on the screen.
If you are adding monitoring of a host for example, you might want to ping the host to check its responding. This snippet is OS specific and sends 1 ping packet with a timeout of 2 seconds and discards all console output.
import os hostname = "google.com" #example response = os.system("ping -c 1 -w2 " + hostname + " > /dev/null 2>&1")
These updates should be done on the thread rather than the drawing loop. The code example can be seen below. The original file is also attached here.
#!/usr/bin/env python import pygame from pygame.locals import * import os import signal import sys import time import RPi.GPIO as GPIO from threading import Thread # Init os.putenv('SDL_FBDEV', '/dev/fb1') os.putenv('SDL_MOUSEDRV', 'TSLIB') os.putenv('SDL_MOUSEDEV', '/dev/input/touchscreen') pygame.init() # Setup out black screen SCREEN_WIDTH = 320 SCREEN_HEIGHT = 240 lcd = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT)) lcd.fill((0,0,0)) pygame.mouse.set_visible(False) pygame.display.update() # Fonts small_font = pygame.font.Font(None, 24) # Colours WHITE = (255,255,255) # Threading bits stopping = False # Last Click Time lastClickTime = time.time() screenOn = True # GPIO Setup GPIO.setmode(GPIO.BCM) BACKLIGHT_PIN = 18 # The channel for PiTFT backlight control GPIO.setup(BACKLIGHT_PIN, GPIO.OUT) def writeText(text, font, x, y): text_surface = font.render('%s'%text, True, WHITE) rect = text_surface.get_rect(center=(x,y)) lcd.blit(text_surface, rect) def updateValues(): """ Thread that updates all values! """ # Loop while not stopping: # Do some work... time.sleep(1) def turnScreenOn(): GPIO.output(BACKLIGHT_PIN, 1) def turnScreenOff(): GPIO.output(BACKLIGHT_PIN, 0) # The thread t = Thread(target=updateValues) # Exit ctrl+c handler def signalHandler(signal, frame): global stopping stopping = True t.join(15) # Wait for the thread to close nicely sys.exit(0) signal.signal(signal.SIGINT, signal_handler) t.start() # Turn the screen on if it isnt already turnScreenOn() # Drawing loop while not stopping: lcd.fill((0,0,0)) # Draw the time in the middle of the screen writeText(time.strftime('%d/%m/%Y %X', time.gmtime()), small_font, (SCREEN_WIDTH/2), (SCREEN_HEIGHT/2)) # Update and sleep pygame.display.update() # Any clicks to care about for event in pygame.event.get(): if (event.type is MOUSEBUTTONDOWN): # Set the last click time, we will use this to turn the screen on/off lastClickTime = time.time() # Turn the screen off after 60 seconds if ((time.time() - lastClickTime) > 60): # If the screen isnt already off, turn it off. if screenOn: screenOn = False turnScreenOff() else: # If we have a click within the last 60 seconds, and the screen is not on, turn it on. if not screenOn: screenOn = True turnScreenOn() time.sleep(0.1)
After running this script, you should now have something that looks like this:
You can now just get this script to run on startup and it will run when the Raspberry Pi reboots. You will need to run the script as root. I added my python script to crontab:
sudo crontab -e
You can draw shapes, images, graphs etc with pygame. Take a look at the documentation in order to look at drawing a more advanced status screen.
Finally, I wanted to do was disable the LED’s. Disabling the power LED was quite easy. You can just run this command:
echo 0 > /sys/class/leds/led1/brightness
Disabling the Edimax WIFI led, is harder and a bit more involved and you will need to recompile the kernel driver. There is a great guide here for doing this.