Stage 1 setup
- Follow Adafruit instructions for PiTFT
- Get the tutorial code: git clone https://github.com/jerbly/tutorials.git
Test the setup
pi@raspberrypi ~ $ sudo python Python 2.7.3 (default, Mar 18 2014, 05:13:23) [GCC 4.6.3] on linux2 Type "help", "copyright", "credits" or "license" for more information. >>> import pygame >>> import os >>> os.putenv('SDL_FBDEV', '/dev/fb1') >>> pygame.init() (6, 0) >>> lcd = pygame.display.set_mode((320, 240)) >>> lcd.fill((255,0,0)) <rect(0, 0, 320, 240)> >>> pygame.display.update() >>> pygame.mouse.set_visible(False) 1 >>> lcd.fill((0,0,0)) <rect(0, 0, 320, 240)> >>> pygame.display.update()You can also run this test (with a one second sleep) from the pygamelcd project: sudo python test1.py
From GPIO to screen
So, we can paint colours on the screen - let's do this from GPIs!
We'll use the four tactile buttons along the bottom of the screen to draw the GPIO number and a coloured background. From left to right the buttons correspond to GPIO #23, #22, #27, and #18.
(Note: If you have a revision 1 board then #27 is #21 - you'll just have to change the code a little)
We'll use the four tactile buttons along the bottom of the screen to draw the GPIO number and a coloured background. From left to right the buttons correspond to GPIO #23, #22, #27, and #18.
(Note: If you have a revision 1 board then #27 is #21 - you'll just have to change the code a little)
import pygame import os from time import sleep import RPi.GPIO as GPIO #Note #21 changed to #27 for rev2 Pi button_map = {23:(255,0,0), 22:(0,255,0), 27:(0,0,255), 18:(0,0,0)} #Setup the GPIOs as inputs with Pull Ups since the buttons are connected to GND GPIO.setmode(GPIO.BCM) for k in button_map.keys(): GPIO.setup(k, GPIO.IN, pull_up_down=GPIO.PUD_UP) #Colours WHITE = (255,255,255) os.putenv('SDL_FBDEV', '/dev/fb1') pygame.init() pygame.mouse.set_visible(False) lcd = pygame.display.set_mode((320, 240)) lcd.fill((0,0,0)) pygame.display.update() font_big = pygame.font.Font(None, 100) while True: # Scan the buttons for (k,v) in button_map.items(): if GPIO.input(k) == False: lcd.fill(v) text_surface = font_big.render('%d'%k, True, WHITE) rect = text_surface.get_rect(center=(160,120)) lcd.blit(text_surface, rect) pygame.display.update() sleep(0.1)
You can also run this from the pygamelcd project: sudo python test2.py
From screen to GPIO
With the PiTFT installed and the 4 tactile buttons there aren't many GPIs left on the model B Raspberry Pi. So wire up #17 and #4. The software renders 4 labels on the screen and then looks for mouse events in the four quarters:
import pygame from pygame.locals import * import os from time import sleep import RPi.GPIO as GPIO #Setup the GPIOs as outputs - only 4 and 17 are available GPIO.setmode(GPIO.BCM) GPIO.setup(4, GPIO.OUT) GPIO.setup(17, GPIO.OUT) #Colours WHITE = (255,255,255) os.putenv('SDL_FBDEV', '/dev/fb1') os.putenv('SDL_MOUSEDRV', 'TSLIB') os.putenv('SDL_MOUSEDEV', '/dev/input/touchscreen') pygame.init() pygame.mouse.set_visible(False) lcd = pygame.display.set_mode((320, 240)) lcd.fill((0,0,0)) pygame.display.update() font_big = pygame.font.Font(None, 50) touch_buttons = {'17 on':(80,60), '4 on':(240,60), '17 off':(80,180), '4 off':(240,180)} for k,v in touch_buttons.items(): text_surface = font_big.render('%s'%k, True, WHITE) rect = text_surface.get_rect(center=v) lcd.blit(text_surface, rect) pygame.display.update() while True: # Scan touchscreen events for event in pygame.event.get(): if(event.type is MOUSEBUTTONDOWN): pos = pygame.mouse.get_pos() print pos elif(event.type is MOUSEBUTTONUP): pos = pygame.mouse.get_pos() print pos #Find which quarter of the screen we're in x,y = pos if y < 120: if x < 160: GPIO.output(17, False) else: GPIO.output(4, False) else: if x < 160: GPIO.output(17, True) else: GPIO.output(4, True) sleep(0.1)
Stage 2 setup
We're now going to improve the UI by introducing a widget framework PygameUI.
1. Update your version of distribute: sudo easy_install -U distribute
2. Install PygameUI: sudo pip install pygameui
PygameUI GPIOs
![](https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiuacih-zU-ZHxilMgRL5CRkXWKKGdpsN62OscHrgla0Z0tDBVhqj01K_YIl4jlnzdfS_KVjxr-sYSKeRnLDkCMahBjmMcu4McPprq_bJqsZ8upUDNZUl20x0M2EQ9UlmtoYTIVRA/s1600/Screen+Shot+2014-08-17+at+4.23.05+PM.png)
The widget rendering and touchscreen events are handled by PygameUI. The PiTft class defines the buttons to draw on screen and the click event to be fired when a button is pressed.
import pygame import os import pygameui as ui import logging import RPi.GPIO as GPIO #Setup the GPIOs as outputs - only 4 and 17 are available GPIO.setmode(GPIO.BCM) GPIO.setup(4, GPIO.OUT) GPIO.setup(17, GPIO.OUT) log_format = '%(asctime)-6s: %(name)s - %(levelname)s - %(message)s' console_handler = logging.StreamHandler() console_handler.setFormatter(logging.Formatter(log_format)) logger = logging.getLogger() logger.setLevel(logging.DEBUG) logger.addHandler(console_handler) os.putenv('SDL_FBDEV', '/dev/fb1') os.putenv('SDL_MOUSEDRV', 'TSLIB') os.putenv('SDL_MOUSEDEV', '/dev/input/touchscreen') MARGIN = 20 class PiTft(ui.Scene): def __init__(self): ui.Scene.__init__(self) self.on17_button = ui.Button(ui.Rect(MARGIN, MARGIN, 130, 90), '17 on') self.on17_button.on_clicked.connect(self.gpi_button) self.add_child(self.on17_button) self.on4_button = ui.Button(ui.Rect(170, MARGIN, 130, 90), '4 on') self.on4_button.on_clicked.connect(self.gpi_button) self.add_child(self.on4_button) self.off17_button = ui.Button(ui.Rect(MARGIN, 130, 130, 90), '17 off') self.off17_button.on_clicked.connect(self.gpi_button) self.add_child(self.off17_button) self.off4_button = ui.Button(ui.Rect(170, 130, 130, 90), '4 off') self.off4_button.on_clicked.connect(self.gpi_button) self.add_child(self.off4_button) def gpi_button(self, btn, mbtn): logger.info(btn.text) if btn.text == '17 on': GPIO.output(17, False) elif btn.text == '4 on': GPIO.output(4, False) elif btn.text == '17 off': GPIO.output(17, True) elif btn.text == '4 off': GPIO.output(4, True) ui.init('Raspberry Pi UI', (320, 240)) pygame.mouse.set_visible(False) ui.scene.push(PiTft()) ui.run()
Analog input
![](https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiesdl72G8vpdMdzC5mzWO-e8DkvSSjYvIxZ06FBn8Z4gLEEeQ3dEAoiAvcGD04uIo48UCEXkQO7VqhsRZwU2Fdzrp9LVK3i3WbpK02SEyghcuZ5pgzIGNJh-nyRg5z-cyDbixpkw/s1600/Screen+Shot+2014-08-25+at+8.44.20+PM.png)
Get the Adafruit Python library: git clone https://github.com/adafruit/Adafruit-Raspberry-Pi-Python-Code.git
If you need to enable i2c follow this guide: Configuring I2C
A few important notes about this code.
A few important notes about this code.
- A thread is used to constantly read the potentiometer. If you take the reading in-line in the scene update method then you'll slow down the screen refresh rate.
- The PotReader class is given a reference to the PiTft class in order to pass data
- The ui.Scene class (PiTft) is instantiated after the call to ui.init - if you do this the other way around it will fail.
- A signal handler is used to trap ctrl+c and terminate the PotReader thread before calling sys.exit - otherwise the program will not close.
import sys sys.path.append('/home/pi/Adafruit-Raspberry-Pi-Python-Code/Adafruit_ADS1x15') import pygame import os import pygameui as ui import logging import RPi.GPIO as GPIO import signal from Adafruit_ADS1x15 import ADS1x15 import threading import time ADS1015 = 0x00 # 12-bit ADC ADS1115 = 0x01 # 16-bit ADC # Select the gain # gain = 6144 # +/- 6.144V gain = 4096 # +/- 4.096V # gain = 2048 # +/- 2.048V # gain = 1024 # +/- 1.024V # gain = 512 # +/- 0.512V # gain = 256 # +/- 0.256V # Select the sample rate sps = 8 # 8 samples per second # sps = 16 # 16 samples per second # sps = 32 # 32 samples per second # sps = 64 # 64 samples per second # sps = 128 # 128 samples per second # sps = 250 # 250 samples per second # sps = 475 # 475 samples per second # sps = 860 # 860 samples per second # Initialise the ADC using the default mode (use default I2C address) # Set this to ADS1015 or ADS1115 depending on the ADC you are using! adc = ADS1x15(ic=ADS1115) #Setup the GPIOs as outputs - only 4 and 17 are available GPIO.setmode(GPIO.BCM) GPIO.setup(4, GPIO.OUT) GPIO.setup(17, GPIO.OUT) log_format = '%(asctime)-6s: %(name)s - %(levelname)s - %(message)s' console_handler = logging.StreamHandler() console_handler.setFormatter(logging.Formatter(log_format)) logger = logging.getLogger() logger.setLevel(logging.DEBUG) logger.addHandler(console_handler) os.putenv('SDL_FBDEV', '/dev/fb1') os.putenv('SDL_MOUSEDRV', 'TSLIB') os.putenv('SDL_MOUSEDEV', '/dev/input/touchscreen') MARGIN = 20 class PotReader(): def __init__(self, pitft): self.pitft = pitft self.terminated = False def terminate(self): self.terminated = True def __call__(self): while not self.terminated: # Read channel 0 in single-ended mode using the settings above volts = adc.readADCSingleEnded(0, gain, sps) / 1000 self.pitft.set_volts_label(volts) self.pitft.set_progress(volts / 3.3) class PiTft(ui.Scene): def __init__(self): ui.Scene.__init__(self) self.on17_button = ui.Button(ui.Rect(MARGIN, MARGIN, 130, 60), '17 on') self.on17_button.on_clicked.connect(self.gpi_button) self.add_child(self.on17_button) self.on4_button = ui.Button(ui.Rect(170, MARGIN, 130, 60), '4 on') self.on4_button.on_clicked.connect(self.gpi_button) self.add_child(self.on4_button) self.off17_button = ui.Button(ui.Rect(MARGIN, 100, 130, 60), '17 off') self.off17_button.on_clicked.connect(self.gpi_button) self.add_child(self.off17_button) self.off4_button = ui.Button(ui.Rect(170, 100, 130, 60), '4 off') self.off4_button.on_clicked.connect(self.gpi_button) self.add_child(self.off4_button) self.progress_view = ui.ProgressView(ui.Rect(MARGIN, 200, 280, 40)) self.add_child(self.progress_view) self.volts_value = ui.Label(ui.Rect(135, 170, 50, 30), '') self.add_child(self.volts_value) def gpi_button(self, btn, mbtn): logger.info(btn.text) if btn.text == '17 on': GPIO.output(17, False) elif btn.text == '4 on': GPIO.output(4, False) elif btn.text == '17 off': GPIO.output(17, True) elif btn.text == '4 off': GPIO.output(4, True) def set_progress(self, percent): self.progress_view.progress = percent def set_volts_label(self, volts): self.volts_value.text = '%.2f' % volts def update(self, dt): ui.Scene.update(self, dt) ui.init('Raspberry Pi UI', (320, 240)) pygame.mouse.set_visible(False) pitft = PiTft() # Start the thread running the callable potreader = PotReader(pitft) threading.Thread(target=potreader).start() def signal_handler(signal, frame): print 'You pressed Ctrl+C!' potreader.terminate() sys.exit(0) signal.signal(signal.SIGINT, signal_handler) ui.scene.push(pitft) ui.run()
No comments:
Post a Comment