ECE 5725 lab 2 solved

$35.00

Category: You will Instantly receive a download link for .zip solution file upon Payment || To Order Original Work Click Custom Order?

Description

5/5 - (2 votes)

Outline In Lab2, we will go through the following steps: • Add external buttons to the RPi setup to expand the control functions of video_control.py from Lab1 • Compare performance of video_test.py in lab 1 and modified versions of this program. • Develop general methods for checking performance of applications on the Pi with an eye towards performance tuning. • Develop some test programs using the PyGame and expand these programs into control panels for video_test.py Lab safety We have all been in lab before and handled electronic components. Please apply all the cautions that you have learned including the items below: Integrated electronics are REALLY susceptible to static discharge. • Avoid walking around while holding bare components • Confine assembly to the grounded mats on the lab bench • Make sure you ground yourself by staying in contact with the mat. Personal safety • Safety goggles are REQUIRED for soldering Experimental Safety • If something on your board is • Really hot • Smoking • Just doesn’t look right • Immediately unplug power • Train yourself so that this is your first reaction – know where the power switch/cutoff is for your experiment. Experimental assembly • Before adding any hardware to the system, power should be OFF • Before powering up the equipment, please have staff check your added circuit 2 video_control.py application from Lab1 A few more buttons In the final step of Lab 1 (step 6), you created the video_control.py to control buttons on the piTFT. This section includes some modifications to this program. As a first step, make sure the original program, as defined in Lab 1, is working as designed. A short description includes the button functions: On the piTFT: • Pause • Fast-forward 10 seconds • Rewind 10 seconds • Quit Reference step 5 and 6 in Lab 1, week 2 for additional details. Using the breakout cable (‘Pi-cobbler’), add two additional buttons to the RPi setup used for playing the video on the PiTFT. Consider which GPIO pins to use, based on what free pins are available • Once the cable is connected to the protoboard, check that the polarity of the plug is correct. Using a voltmeter, check that the +5 pins and several of the +3.3 pins are in the correct locations (according to the indications on the cable header). If not, or if you are unsure, please check in with the TA. • Use the safe development techniques discussed in class, so as not to ‘cook’ the GPIO pins if something goes wrong. • Once the buttons are wired correctly; STOP and please check with the TA to insure correct connections and GPIO selection. 3 A photo of a setup connected correctly: Notes: • The white stripe on the piCobbler breakout cable is on the same side as the piTFT buttons • On the protoboard, you can read the pin assignments (starting from the left) 3.3, SDA, SCL, 4, Gnd, etc…. • The photo is a bit distorted on the left edge: The red wire is connected to 3.3 V (the pin labeled 3V3), NOT SDA • Note that the numbering on the piCobbler corresponds to BCM numbering (for example pin ‘26’ on the piCobbler is GPIO26) • The above example has a single button wired into GPIO26. • Note wire insulation used on bare resistor leads to prevent shorts (please see the’Lab2 parts’ video on Canvas for a demonstration) 4 Some references: 3.3 Volts 3.3 Volts 5 • Stop and check your wiring with a TA. Be prepared to show the connections over zoom. • Once checked, power up and extend four_buttons.py to create ‘six_buttons.py’ to make sure you can correctly read the existing four, and two new buttons • Extend ‘video_control.py’ to create ‘more_video_control.py’ to add two new functions to video control; fast forward 30 seconds and rewind 30 seconds • Modify the ‘start_video’ bash script to use the new code, more_video_control.py. Step2: interrupt callbacks Modification of video_control.py Once more_video_control.py is running, copy the verified file into a new file, more_video_control_cb.py. In this code, modify the button presses to use threaded callback interrupt routines for button presses. Note: • Most (all) of the buttons can be modified to use callback routines • The polling loop used in more_video_control.py will require alteration • The quit function may be a special case. • For each button, you will need to: o Setup a callback routine o Define an event that accesses the callback routine Once this routine has been redesigned, verify that it operates correctly in a bash script, similar to the operation of start_video from lab1. Name this new bash script start_video_cb. Confirm that the operation of all buttons in start_video_cb is identical to the function in the original start_video script. Take a backup of your SD card at this point in the lab. The backup at this point is optional. 6 Performance measurement with ‘perf’ utilities This section explores the Linux ‘perf’ utility to measure performance of applications on the R-Pi. We will be looking into the performance difference between polling loop and interrupt versions of programs implemented in Python during lab. Step1: Install Perf with the following commands: sudo apt-get install linux-tools Try the command: perf –help And it should fail! The message will tell you that your system is missing the correct version of perf. Example: pi@ece5725-f21:/bin $ perf /usr/bin/perf: line 13: exec: perf_5.10: not found E: linux-perf-5.10 is not installed. This error is caused by a quirk in the perf bash script. In fact, by installing the linux tools, perf_4.9 has been installed. We are also going to install the latest version of perf by running: sudo apt-get install linux-perf-4.18 Step2: Test that the latest version of perf is operating as designed by running: perf_4.18 –help perf_4.18 list perf_4.18 –version Notes: 1. Perf is able to track a number of different hardware and software events. Take a look at the output of ‘list’, above, to get an idea of these events perf is able to track. 2. Keep in mind that not all of these measurements are available on all platforms. 3. With perf, there is a bash shell installed in /usr/bin/perf. Run this by issuing the command ‘perf’. What error do you see? Take a look at the bash script and see if you can form a theory for why this fails and how you might overcome the problem. 7 Step3: Create a python file named cal_v1.py containing the following statements: import time time.sleep(0.2) # sleep Step4: Run the following: sudo perf_4.18 stat -e task-clock,context-switches,cpumigrations,page-faults python cal_v1.py This will show the following performance statistics: • Task-clock: program execution time in milliseconds • Context-switches: how many times the Linux process scheduler switched control between running processes • cpu-migration: how many times process was moved to a different cpu (or core) • page-faults: How many times a part of the processes virtual memory was copied to physical memory This test gives a baseline set of statistics for a simple python code. Record the results. Performance measurement of video_control.py This section includes a series of tests to begin to characterize performance of the polling and interrupt versions of the video_control routines. Please use either python2 or python3 for all runs for consistency of measurement (do not mix the two for different runs). Plan to record results from all runs for comparison. In order to fairly compare the polling and interrupt versions of video_control, consider how you might need to modify the codes to perform for a fixed amount of time; that is, all codes in the experiment should run for a fixed time of 10 seconds (for example), then quit. The idea is to determine how much overhead may be present in the programs associated with button control; not the functions called by the button presses but, rather, the logic used to establish the control for the buttons. Step1: Modify more_video_control.py to introduce fixed timing prior to the perf run. Rename this function ‘more_video_control_perf.py’. Run the perf tools for more_video_control_perf.py , using a perf call: sudo perf_4.18 stat -e task-clock,context-switches,cpumigrations,page-faults python more_video_control_perf.py 8 In the polling loop, make sure to start with a ‘sleep’ value of 200 milliseconds ( time.sleep(0.2) ). Step2: Modify more_video_control_cb.py to introduce a fixed run-time prior to running the perf tool. Once modified, run the perf tools, for more_video_control_cb_perf.py Step3: make successive runs of more_video_control_perf.py, changing polling loop times to: • 20 milliseconds • 2 milliseconds • 200 microseconds • 20 microseconds • with no sleep statement at all Step4: Note changes to the perf measurements and deduce impacts of changes and compare the results between successive runs of more_video_control_perf.py and with more_video_control_cb_perf.py. Include discussion in the Lab report. PyGame: Bounce Program Notes for bounce program: • Plan to implement a physical quit button (one of the piTFT buttons works well) and a timeout for the following codes. • remember, from the lecture examples, that you’ll need to consider the following environment variables when running on the piTFT: import os os.putenv(‘SDL_VIDEODRIVER’, ‘fbcon’) os.putenv(‘SDL_FBDEV’, ‘/dev/fb1’) 1. On your Raspberry Pi, implement the ‘Bounce’ code in python using pygame (you can find pygame documentation in the Canvas ‘References’ section). 9 2. Extend this code to include 2 balls, two_bounce.py, where each ball moves on the screen at a different speed. Note that the two bouncing balls are designed to be ‘transparent’ to one another. That is, although a ball bounces off the ‘walls’ at the edge of the screen, balls may pass over each other when they intersect. Design this code to run on the monitor desktop (or /dev/fb0). 3. Expand two_bounce.py to create two_collide.py, so that the balls alter their trajectories as they collide with one another. o There are many techniques for collision of pygame objects. Have a look at the Pygame reference document for possible calls to help with detecting collisions. o For physically correct 2-dimensional collisions, check out the following references: § https://scipython.com/blog/two-dimensional-collisions/ § https://en.wikipedia.org/wiki/Elastic_collision § Note that you can also check the ‘Dynamics’ section in: http://people.ece.cornell.edu/land/courses/ece4760/labs/f2016/lab3_particle_beam .html For another suggestion on how to alter velocity after collisions. [1] 4. Implement a version of two_collide.py that runs on the piTFT screen. Design this code to run on the piTFT screen and to exit when one of the buttons is hit. Example of a two_bounce.py screen: 10 Demonstrate your work to the TA; note that all demonstrations should be on the RPi and PiTFT. Demonstrate all Codes to the TA including: • six_buttons.py • more_video_control.py and modified start_video script • more_video_control_cb.py and start_video_cb bash script • demonstrate perf runs with modified and more_video_control_perf.py more_video_control_cb_perf.py • bounce.py, two_bounce.py and two_collide.py Backup your SD card – Important as next section has some detailed changes. 11 Week 2: piTFT touch control If you haven’t done it yet, backup your SD card to preserve the system from week 1…. The move from Wheezy to Jessie, Stretch, and Buster has disrupted the control of the touch screen a bit. In short, some of the SDL calls are broken in later kernel versions; a fix that seems to work reverts to some wheezy functions for these calls. In order to proceed, please issue the following commands to enable the correct operation of the touch function of the piTFT. The following instructions, detailed below, were created by the Raspbian user community and ultimately included into Adafruit instructions for using the PiTFT. The following instructions originated in the reference [3] on the Adafruit site. Note on the following instructions: If you are cutting and pasting these instructions using a console window, I had some issues with the ‘dash’ character, ‘-‘ and the double quote ‘ “ ‘ character. These characters do not seem to copy correctly and will lead to install failures in the following commands. If the entries are typed into the console window (rather than using a cut and paste), everything works correctly. On to the commands: 1) Enable wheezy package sources by editing the new file: sudo vim /etc/apt/sources.list.d/wheezy.list and adding the line: deb http://legacy.raspbian.org/raspbian wheezy main Save and close the file Note that the above commands will create a new file. 2) Set stable as default package source (for the wheezy changes) by editing the new file: sudo vim /etc/apt/apt.conf.d/10defaultRelease and adding the line: APT::Default-release “stable”; # not working! 9/27/2021 APT::Default-release “wheezy”; Save and close the file 12 Note that the above commands will create a new file. 13 3) Set the priority for libsdl from wheezy higher than the Buster package by editing the new file: sudo vim /etc/apt/preferences.d/libsdl and adding the lines: Package: libsdl1.2debian Pin: release n=buster Pin-Priority: -10 Package:libsdl1.2debian Pin: release n=wheezy Pin-Priority: 900 Save and close the file The above commands also create a new file. You can check the state of the sdl libraries before applying the changes by running the following: pi@RPi-jfs9:~ $ dpkg -l *libsdl* Desired=Unknown/Install/Remove/Purge/Hold | Status=Not/Inst/Conf-files/Unpacked/halF-conf/Half-inst/trig-aWait/Trig-pend |/ Err?=(none)/Reinst-required (Status,Err: uppercase=bad) ||/ Name Version Architecture Description +++-==========================-===================-============- ================================================================= un libsdl-1.3-0 (no description available) ii libsdl-image1.2:armhf 1.2.12-10+deb10u1 armhf Image loading library for Simple DirectMedia Layer 1.2, libraries ii libsdl-mixer1.2:armhf 1.2.12-15 armhf Mixer library for Simple DirectMedia Layer 1.2, libraries ii libsdl-ttf2.0-0:armhf 2.0.11-6 armhf TrueType Font library for Simple DirectMedia Layer 1.2, libraries un libsdl1.2 (no description available) un libsdl1.2-all (no description available) un libsdl1.2-esd (no description available) un libsdl1.2-nas (no description available) un libsdl1.2-oss (no description available) ii libsdl1.2debian:armhf 1.2.15+dfsg2-4+rpt2 armhf Simple DirectMedia Layer un libsdl1.2debian-all (no description available) un libsdl1.2debian-alsa (no description available) un libsdl1.2debian-esd (no description available) un libsdl1.2debian-nas (no description available) un libsdl1.2debian-oss (no description available) un libsdl1.2debian-pulseaudio (no description available) ii libsdl2-2.0-0:armhf 2.0.9+dfsg1-1+rpt1 armhf Simple DirectMedia Layer 14 4) Install the changes by running the commands: sudo apt-get update sudo apt-get –y –-allow-downgrades install libsdl1.2debian/wheezy Example of the second command: pi@RPi-jfs9:~ $ sudo apt-get -y –allow-downgrades install libsdl1.2debian/wheezy Reading package lists… Done Building dependency tree Reading state information… Done Selected version ‘1.2.15-5’ (Raspbian:7.0/oldoldstable [armhf]) for ‘libsdl1.2debian’ The following additional packages will be installed: libdirectfb-1.2-9 libts-0.0-0 tsconf The following packages will be REMOVED: libts-bin libts0 The following NEW packages will be installed: libdirectfb-1.2-9 libts-0.0-0 tsconf The following packages will be DOWNGRADED: libsdl1.2debian 0 upgraded, 3 newly installed, 1 downgraded, 2 to remove and 35 not upgraded. Need to get 1,342 kB of archives. After this operation, 1,757 kB of additional disk space will be used. Get:1 http://legacy.raspbian.org/raspbian wheezy/main armhf tsconf all 1.0-11 [13.4 kB] Get:2 http://legacy.raspbian.org/raspbian wheezy/main armhf libts-0.0-0 armhf 1.0-11 [31.0 kB] Get:3 http://legacy.raspbian.org/raspbian wheezy/main armhf libdirectfb-1.2-9 armhf 1.2.10.0- 5 [1,094 kB] Get:4 http://legacy.raspbian.org/raspbian wheezy/main armhf libsdl1.2debian armhf 1.2.15-5 [203 kB] Fetched 1,342 kB in 1s (991 kB/s) (Reading database … 97046 files and directories currently installed.) Removing libts-bin (1.19-1) … Removing libts0:armhf (1.19-1) … Selecting previously unselected package tsconf. (Reading database … 96984 files and directories currently installed.) Preparing to unpack …/archives/tsconf_1.0-11_all.deb … Unpacking tsconf (1.0-11) … Selecting previously unselected package libts-0.0-0:armhf. Preparing to unpack …/libts-0.0-0_1.0-11_armhf.deb … Unpacking libts-0.0-0:armhf (1.0-11) … Selecting previously unselected package libdirectfb-1.2-9:armhf. Preparing to unpack …/libdirectfb-1.2-9_1.2.10.0-5_armhf.deb … Unpacking libdirectfb-1.2-9:armhf (1.2.10.0-5) … dpkg: warning: downgrading libsdl1.2debian:armhf from 1.2.15+dfsg2-4+rpt2 to 1.2.15-5 Preparing to unpack …/libsdl1.2debian_1.2.15-5_armhf.deb … Unpacking libsdl1.2debian:armhf (1.2.15-5) over (1.2.15+dfsg2-4+rpt2) … Setting up tsconf (1.0-11) … Installing new version of config file /etc/ts.conf … Setting up libts-0.0-0:armhf (1.0-11) … Setting up libdirectfb-1.2-9:armhf (1.2.10.0-5) … Setting up libsdl1.2debian:armhf (1.2.15-5) … Processing triggers for mime-support (3.62) … Processing triggers for gnome-menus (3.31.4-3) … Processing triggers for libc-bin (2.28-10+rpi1) … Processing triggers for man-db (2.8.5-2) … Processing triggers for desktop-file-utils (0.23-4) … pi@RPi-jfs9:~ $ 15 After the update commands have run, reboot the system. After the system restarts, you can check the status of the sdl libraries with the following command: pi@RPi-jfs9:~ $ dpkg -l *libsdl* Desired=Unknown/Install/Remove/Purge/Hold | Status=Not/Inst/Conf-files/Unpacked/halF-conf/Half-inst/trig-aWait/Trig-pend |/ Err?=(none)/Reinst-required (Status,Err: uppercase=bad) ||/ Name Version Architecture Description +++-==========================-==================-============- ================================================================= un libsdl-1.3-0 (no description available) ii libsdl-image1.2:armhf 1.2.12-10+deb10u1 armhf Image loading library for Simple DirectMedia Layer 1.2, libraries ii libsdl-mixer1.2:armhf 1.2.12-15 armhf Mixer library for Simple DirectMedia Layer 1.2, libraries ii libsdl-ttf2.0-0:armhf 2.0.11-6 armhf TrueType Font library for Simple DirectMedia Layer 1.2, libraries un libsdl1.2 (no description available) un libsdl1.2-all (no description available) un libsdl1.2-esd (no description available) un libsdl1.2-nas (no description available) un libsdl1.2-oss (no description available) ii libsdl1.2debian:armhf 1.2.15-5 armhf Simple DirectMedia Layer un libsdl1.2debian-all (no description available) un libsdl1.2debian-alsa (no description available) un libsdl1.2debian-esd (no description available) un libsdl1.2debian-nas (no description available) un libsdl1.2debian-oss (no description available) un libsdl1.2debian-pulseaudio (no description available) ii libsdl2-2.0-0:armhf 2.0.9+dfsg1-1+rpt1 armhf Simple DirectMedia Layer Compare the output of the dpkg command to the command run before the changes for wheezy downgrade were run. Do you notice any differences in the installed libsdl package list when comparing the before and after dpkg runs? Once the above changes have been completed, work may proceed on using touch screen controls. The idea for the following codes will be to use touch as a mouse click to press on-screen buttons controlling your software. It is MUCH easier to begin this process by displaying the small screen on the monitor or VNC (rather than the piTFT). Using the monitor, you will be able to observe the impact of code changes and any debug/log information and using a console window. In addition, you can add print statements to a running program to indicate response to events (‘pause button hit’ for example). Control for monitor use is determined by the environment variables: os.putenv(‘SDL_VIDEODRIVER’, ‘fbcon’) # Display on piTFT os.putenv(‘SDL_FBDEV’, ‘/dev/fb1’) # os.putenv(‘SDL_MOUSEDRV’, ‘TSLIB’) # Track mouse clicks on piTFT os.putenv(‘SDL_MOUSEDEV’, ‘/dev/input/touchscreen’) 16 If you add these into your python program, comment them out to display the on the monitor (or VNC window) instead of on the piTFT. You will also be using: pygame.mouse.set_visible(False) Which will turn off the mouse cursor. When debugging on the monitor, set this to True so you can easily use the mouse to click the on-screen buttons. Once you have your code debugged and running on the monitor, you can switch to the actual piTFT. Un-comment the 4 environment variable settings and set the mouse to invisible. If you now launch from an ssh window (on your laptop) the application should run on the piTFT. You may also be able to start the piTFT code from a console window in startx however, there may be a Linux problem that prevents this method from working (might be fixed in Stretch and Buster); also, this may not work using VNC As a final test, the code should be started from the command line on the piTFT to show the embedded operation of the application. Optionally, if you do not have a USB keyboard available, you can demonstrate this running using ssh. [2] • Design a python application, quit_button.py, that displays a single ‘quit’ button on the lower edge of the screen. The program should be designed so that touching the ‘quit’ button ends the program and returns to the Linux console screen. Initially, the quit function may be implemented by touching at any location on the screen. For easier control while debugging all touch screen programs: • Implement a physical ‘bail out’ button. This button may be one of the piTFT buttons or an external button. Hitting this button should end the program. • Also implement a code time-out that will end the program after a given time interval. For example, when you are first starting to develop the code, you may want to set this timeout to 30 seconds. This time-out can be lengthened, or eliminated, as your code stabilizes. These methods will prevent excessive power off/power on restarts of a hung RPi system. 17 • Expand quit_button.py into a second python application, screen_coordinates.py. The above example shows a screenshot of some test code to display button press (you do not need to implement the start button for this step, only the quit button) The operation of screen_coordinates.py should be: • Display a single quit button at the bottom of the screen • Tapping any location on the screen still display ‘Touch at x, y’ where x, y show the screen coordinates of the hit. Note that the screen should be updated correctly for successive screen hits. • As a quick guide, the upper-left of the screen is coordinate (0,0), lower-right is (320,240), upper-right is (320,0) and lower-left is (0,240) • Tapping the ‘quit’ button will exit the program. Note that you may need to iterate over several runs of screen_coordinates.py to refine the coordinates of the quit button. • All hits should be displayed on the Linux console as well • Plan to include a copy of 20 screen taps, ranging over the extent of the piTFT screen, in your lab report. Think about how best to collect these data on screen taps; what are some simple ways to save all twenty events? • Implement a physical bail-out button, and a time-out, for this code. 18 What if screen_coordinates.py doesn’t work? quit_button.py and screen_coordinates.py are the true tests of the correct function of the Wheezy downgrade. In spite of all of the above checks during install steps, there may still be problems. The symptoms of incorrect coordinates include: • All previous checks are correct (dpkg output looks OK, for example) • evtest (from Lab1) runs correctly (because this tests to see if linux is recognizing the piTFT touch. The Wheezy downgrade is needed for correct touch in pygame) • screen_coordinates runs correctly on a monitor or VNC screen (because the Wheezy downgrade only impacts the piTFT not monitor displays) From experience, there are several classes of problem: Cannot get quit_button or screen_coordinates running on piTFT: • Check ‘ ls –l /dev/fb* ’ If this only shows /def/fb0, then make sure your code is directed to this device (not /dev/fb1). If both /dev/fb0 and /dev/fb1 are defined, then direct your code to /dev/fb1 to run on the piTFT • Make sure you run python codes preceded with sudo (sudo python3 quit_button.py, for example) • Check that the environment variables are set correctly (no typos) AND uncommented. • Make sure that pygame.init() occurs after the definition of the environment variables. • Try running on an ssh console window (from your laptop) and/or directly on the piTFT console window (if you have a USB keyboard attached to the piTFT) • Check ‘ls –l /dev/input/touchscreen’. This should point at ‘eventN’. If it points to something else, run ‘fix_touchscreen’. If /dev/input/touchscreen is not defined, recheck the instructions for the udev rule in lab1 Screen_coordinates runs on the piTFT, but the coordinates are incorrect: • Try rebooting the RPi and re-test • Double check for correct entries in the environment variables in your python code • Double check the entries you typed in for the wheezy downgrade files. Check with your teammate and look closely for typos. If you discover any typos, correct and run the wheezy downgrade commands again. • Changes to the wheezy downgrade files are very sensitive to included hidden characters. If you used cut and paste, you may want to retype the files on the RPi, carefully….try to avoid any typos! 19 Assume you get these codes working, you may proceed with the lab. If not, please discuss the issues with staff. • Design a python program ‘two_button.py’ with the following functions: • Two, on-screen buttons are displayed ‘start’ and ‘quit’ • Hitting ‘start’ begins playback of two_collide.py • Hitting ‘quit’ ends the program and returns to the Linux console screen. • Hitting any other location on the screen displays screen coordinates. • The start and quit buttons should be displayed on the screen, and operate whenever they are displayed, during the entire time the program is running (including while the animation is playing) • Note that button placement should be designed so as not to interfere with video playback. • Implement a physical bail-out button, and a time-out, for this code. 20 • Design a python program control_two_collide.py with the following functions: Example screenshot showing implementation of second level touch controls • As in ‘two_button.py’, start and quit are implemented with identical functions. Screen coordinates should be displayed if hits occur outside of start and quit buttons. This is the ‘level 1’ menu. • Once the animation begins to play, a second level of button controls, shown above on the ’level 2’ menu, should be displayed including the following buttons and associated functions: • Pause/restart: pause a running animation. Restart a paused animation • Faster: speed up the animation by a fixed amount • Slower: slow the animation by a fixed amount • Back: stop the animation and return to the ‘top’ menu screen which implements the start and quit buttons. • Note that button placement should not interfere with the running animation. In particular, watch out for the placement of level 1 ‘Quit’ and level2 ‘Back’. Also, coordinates should be detected so as to separate button function (that is, avoid a single tap causing multiple buttons to be hit) • Implement a physical bail-out button, and a time-out, for this code. 21 Backup your SD card. Demonstrate all codes to the TA: • Quit_button.py • Screen_coordinates.py • Two_button.py running with two_collide.py animation • Control_two_collide.py running with two_collide.py animation • Correct function of ‘bail out’ button for all the above codes. IMPORTANT: Backup your SD card. References: [1] From ECE4760, Lab 3, Professor Bruce Land. Link suggested by Junyin Chen, ECE5725, Fall 2016 student, Cornell MEng 2016. [2] This section on debugging with the monitor and piTFT paraphrases a note posted by Junyin Chen, ECE5725, Fall 2016 student, Cornell MEng 2016. [3] Detailed instructions for running PyGame touch features on a piTFT gathered from user forums and consolidated in a single document by Adafruit: https://learn.adafruit.com/adafruit-pitft-28-inch-resistive-touchscreen-display-raspberry-pi/pitft-pygame-tips