Categories
Gmail Google

Google Drive Woes

Recently I noticed that my Google Drive space was nearly full. I also noticed that Gmail was consuming a majority of the space. I could not understand why as I delete and move my emails to a local file in Outlook. Looking at this more, I found out why and spent a whole day to get my Gmail space down to zero.

Google keeps all email even if you delete it in Microsoft Outlook. This was something that I was not aware of but not surprised. The surprising part is that the space taken by the deleted emails counts against your Google Storage.

The problem I have is my security cameras send emails for alerts. Those emails include two attached images. It was these emails that were consuming most of the space. In addition to the alert emails, Gmail had emails going back ten years.

I found the article at HelloTech.com, that explained how to delete all your Gmail quickly. I proceeded with the steps in that article but found that 0 to 10,000 messages may be deleted using that method. Yes, there were several times where zero messages were deleted after waiting several minutes. I spent the rest of the day in my All Mail folder deleting messages and going to the trash to empty it. At the end of the day, I finally managed to get the space used by Gmail to zero.

I did find that deleting emails from other labels or categories using the Gmail web interface did indeed delete the email in the All Mail folder. The problem seems to be if you delete them from Outlook, it may remove the label applied to the email but does not delete the email. It looks like I may need to periodically go into Gmail’s web interface to delete the emails. This is not an ideal workflow so I will be looking to see if there are other ways to solve this issue including rolling my own application to delete emails from Gmail’s All Mail folder.

If you have any ideas on how to resolve this issue with Outlook and Gmail, please reply with a comment to let me know. If I make more progress with rolling my own solution, I will post an update to let you know including a link to any code that I develop.

Categories
Website

Website Changes

We’ve made some changes to the site to make it align more with our goals. When the website was first created, it was expect that the how-to articles and projects would be the major focus, however there have been too infrequent updates so the site was stale. This is mostly do to the amount of time needed to complete a project, then actually write good content to document the steps taken.

With the new year, we are going to take a different approach and put the blog posts front and center and make the projects and how-to articles a secondary aspect. This should allow us to make more frequent updates and hopefully make the site more useful and interesting. We would like to know what you think so please feel free to comment on the blog posts and projects.

We are also going to try a chat feature to see if it is something that visitors find useful. It may allow for more direct interaction. Just keep in mind that we may not respond to chats all the time. The best time to catch us on chat will be after 5 PM Eastern Time (New York) or on the weekend.

Hope you enjoy the new layout and find that this format and focus is more useful and interesting.

Categories
Raspberry Pi

Microchip AR1100 Resistive Touch Screen to USB

I’m currently working on a project similar to what Rune Kyndal did, which is putting a Raspberry Pi inside an old HP 95LX case. You can see Rune’s project on HACKADAY.IO.

I sourced a 800×320 screen from BuyDisplay.com, that is a good match for the original dimensions of the HP 95LX display. Arguably, the screen that Rune sourced is better at 800×480, but I wanted a display that would allow for the original faceplate to be used so it looks as close to the original as possible. I still need to cram everything into the housing.

One thing that I wanted to be able to do is use the device without a mouse if I want to. That requires getting the touch screen to work. Today I was finally able to get the touch screen in a usable state with the help of tool created by tom-2015 and available on GitHub. The application runs on Linux, which I needed as the screen is at an odd resolution so the Microchip calibration tool will not work for the display. I was able to get Windows to use the display, when connected through HDMI, but was unable to get the correct resolution for calibration.

The rpi-AR1100 application provided on GitHub does the trick but I did have an issue that I needed to work through first. It took a few days of looking through the Microchip datasheet and walking through the code to determine that it was a timeout issue with reading/recognizing the calibration points being touched.

Issue Prior to Calibration

Before Calibrating the screen, the touch did not track to the edges of the screen. It was fine in the middle of the screen but as you got out to the edges, the pointer was not tracking and would not reach to the edges of the screen. Below is an image with a red rectangle showing the approximate bounds of the touch area prior to calibration.

Rectangle showing perimeter of the pointer boundary prior to calibration

The AR1100 works well once it is calibrated. If you calibrate it on the Raspberry Pi using Tom’s rpi-AR1100 utility on GitHub and find that the calibration is not responding to touches, you may need to edit line 185 in AR1100.cpp by changing the timeout parameter passed to the read_data function. I made the following edit to get it working on the Raspberry Pi Zero W.

Changed AR1100.cpp line 185
FROM: int result = read_data((unsigned char *) & response, sizeof(response), & bytes_read, 5);
TO: int result = read_data((unsigned char *) & response, sizeof(response), & bytes_read, 50);

UPDATE: Tom has made this change to the code in his repository. If you find that the application is not responding when touching the screen, you may need to increase this value.

Hope this helps you if you are working with the Microchip AR1100.
BTW: I’m using the Adafruit Resistive Touch Screen to USB Mouse Controller – AR1100, product number 1580.

Categories
Raspberry Pi

Raspberry Pi 4 – 19″ Rack with four units

Source Files are located on GitHub at https://github.com/richteel/pi_status.

The inspiration for this project is from a UCTRONICS Pi Rack that Jeff Geerling reviewed on his YouTube channel. The UTRONICS product may be seen at https://www.uctronics.com/cluster-and-rack-mount/for-raspberry-pi/1u-rack-mount/uctronics-pi-rack-pro-for-raspberry-pi-4b-19-1u-rack-mount-support-for-4-2-5-ssds.html. While I cannot build something as elegant as the UCTRONICS Pi Rack, I wanted to do something similar. I had a 1U ABS 19″ Rack Mount Case, so I decided to replicate the UCTRONICS product. Below is some information on my build.

Materials

Notes

  • Source and product pages are representative of items. Materials may be sourced from other vendors such as Adafruit, Digi-Key, Mouser, etc.
  • Currently (October 2022), Raspberry Pi boards are difficult to source. The situation should improve shortly. It is recommended that you use Raspberry Pi boards that you currently have or wait until they are available at approved vendors such as PiShop.us, Adafruit, Digi-Key, SparkFun, etc. You may be able to get a Raspberry Pi 4 at Amazon but it will be nearly triple the retail price. Below is the Amazon listing for a Raspberry Pi 4 with 4GB of RAM at $149.90 verses the retail price of $55 US.
Raspberry Pi listing on Amazon

You may find official retailers with Raspberry Pi boards in stock by going to https://rpilocator.com/.

Tools and Prerequisites

  • Laser Cutter or hand tools for cutting mounting and front plates
  • Ethernet Switch/Hub with PoE capability if using PoE+ Hat. If you plan to use PoE, your switch must support the IEEE 802.3at standard. (See Jeff Geerling’s video Review: Raspberry Pi’s new PoE+ HAT)

Laser Cutting Files

Download the files from GitHub at https://github.com/richteel/pi_status.

There are two files located in the case folder for use with a laser cutter. The front panel will be having some changes shortly so be warned if you decide to use it that it will not fit properly. I had only 1/8″ material so it is smaller to fit the case for testing. I now have 1/16″ stock and will be modifying the file for the 1/16″ material to fit properly in the case. I will also modify the notch for the USB to SATA adapter cable. I’m considering running them on top of the mounting plate rather than under it as it is not a good fit. If I do that, I may move the SD Card slot back to the center to avoid running it over a mounting hole.

The base was made with 1/8″ draftboard. The outline for the Raspberry Pi’s were scored while the rest was cut.

Glowforge Application – Mounting Plate
Glowforge Application – Front Panel

Assembly

The following directions utilize an unsupported method for mounting the PoE Hat. The PoE Hat should be mounted with the provided 10mm standoffs to provide a solid connection to the Raspberry Pi. Using the 11mm standoffs reduces the mating area but provides more contact area to allow a male header to make connection with the GPIO pins through the top of the PoE Hat. If you have a 2U case, it would be best to utilize the recommended 4 & 40 Pin Extra Tall Header (Push Fit Version) – POE HAT Set and a perfboard to make the GPIO connections. I attempted this setup but was unable to make it fit in the 1U case. That explains why UCTRONICS uses pogo pins on the bottom of the Raspberry Pi to make the GPIO Connections.

  1. Once the mounting and front plates are cut, the assembly may begin. The M2.5*5+5mm Male-Female Standoffs are secured to the mounting plate with M2.5 nuts for the Raspberry Pi mounts.
  2. The plastic housings for the Micro SD to Micro SD Card Extension Cables are removed and are secured to the mounting plate with the double sided tape provided. Make certain to line them up with the front plate and make certain that they are flush or extend slightly from the front plate.
  3. Once the standoffs and Micro SD Card Extension Cables are mounted, secure the mounting plate to the case with the 6#32*6BM or similar screws. You will not be able to put a screw under the second Raspberry Pi from the right as the Micro SD Extension Cable passes over the mounting point. I did not place any screws under either Raspberry Pi.
  4. Secure the Raspberry Pi boards to the mounting plate with the M2.5*11+6mm Male-Female Standoffs.
  5. Plug the Raspberry Pi PoE+ HATs into each Raspberry Pi and secure with the M2.5*5mm Screws.
  6. Secure the M2*4+3mm Male-Female Standoffs to the front plate with the M2*4mm Screws for mounting the displays.
  7. It is recommended to use MX1.25-4P Male & Female connectors to connect the switches to the 2×7 Header as the switches cannot be removed easily if not used. If you will not use the connectors, mount the switches to the front panel.
    Solder wires to the push-button switches.
  8. Solder wires to the OLED displays.
  9. Solder the wires to the 2×7 2.54mm Double Row Male Header. Refer to the diagram below. It is recommended to use a perfboard or heat-shrink to prevent accidental shorts.
  10. Once all the wires are soldered, mount the displays on the front panel with the M2 Nuts.
  11. Mount the push-button switches and plug the switches into the connectors if the connectors were used.
  12. Mount the front panel into the case.
  13. Spread the 2×7 male header pins apart slightly to provide a better connection when inserting through the top of the PoE Hat.
  14. Carefully plug the 2×7 male header into the PoE Hat. Make certain that you pay attention to the orientation. It is easier if you place the inside row into the PoE Hat then work the outside row into the PoE Hat.
  15. Double check that all connections are correct and all the screws, nuts, and standoffs are tight.
  16. Do not close the case yet! You need to test each Raspberry Pi first as it is likely that one or more of the pins on the 2×7 header will not be making contact with the GPIO pins so you will need to spread some pins apart a bit more to make good contact. It is also possible that one or more PoE hats will not make good contact with the Pi so that the fan will not run when the Raspberry Pi gets hot. You will need to check that everything on all Raspberry Pi boards are working before closing up the case.
  17. Once everything is working, you may close the case.
Wiring Pinout for the Front Panel and Button

Below are a few photos of the build.

Header Pins Spread Apart
Showing wiring using a perfboard for the 2×7 male header.
Mounting Plate with one Raspberry Pi mounted. (The screw under the 3rd Raspberry Pi was not installed in the final build.)
Installation showing SSD Drives installed.

Software Installation

Follow the steps in the README.md file in the GitHub repository to install the pi_status software on each Raspberry Pi.

Testing and Troubleshooting

No Power to the Raspberry Pi

  • Check if the PoE Hat has power.
    • Is the Red LED lit on the PoE Hat? – No
      • Does the network switch provide PoE+ (IEEE 802.3at standard)?
      • Is the switch port that the Raspberry Pi is connected to provide PoE+? (Some switches supply PoE+ to some but not all ports.)
      • Try another ethernet cable to see if that is the problem. Make certain that there are 4 pairs in the cable as all 8 wires are needed for PoE.
    • Is the Red LED lit on the PoE Hat? – Yes
      • Attempt to reseat the PoE Hat.
      • Unplug the 2×7 male header to see if there is a fault causing a short.

Raspberry Pi boots but the fan does not run when the Raspberry Pi is over 50C

  • Attempt to reseat the PoE Hat.
  • Unplug the 2×7 male header to see if there is a fault causing the issue.

Display does not work at all

  • From a Terminal Window, connect to the Raspberry Pi and run i2cdetect to see if device 3c is found.
    i2cdetect -y 1
  • Device 3c is found – No
    • Remove the 2×7 male header and spread apart the pins a bit more or if not all pins are spread apart the same, spread the pins that are closer together apart further until they are all spread apart the same distance. Most likely the issue will be with pins 1 through 6 so concentrate your effort on those pins.
    • Check for cold/bad solder connections on the display lines.
  • Device 3c is found – Yes
    • Make certain that the script is running. Run the following command to get the pid of the running script. If no pid is returned, then the script is not running.
      ps ax | grep ‘code.py’ | grep -v grep
    • If the script is not running, try to run it again.
      sh /home/pi/pi_status/display/launcher.sh -v
    • Check the error log to see if any errors were logged.
      cat /home/pi/pi_status/display/logs/error.txt
      or
      sudo tail -f /home/pi/pi_status/display/logs/error.txt

Display is garbled or stops working

  • Most likely, the display wires are too close to the transformer on the PoE Hat. Move the display wires so they are not close to the transformer and restart the script.
  • Double check that Display SDA is connected to the Raspberry Pi SDA and the Display SCL is connected to the Raspberry Pi SCL.
  • Check for cold/bad solder connections on the display lines.

LED on the switch is not lit and/or switch does not shutdown the Raspberry Pi

  • Remove the 2×7 male header and spread apart the pins a bit more or if not all pins are spread apart the same, spread the pins that are closer together apart further until they are all spread apart the same distance. Most likely the issue will be with pins 7 through 14 so concentrate your effort on those pins.
  • Check for cold/bad solder connections on the switch wires.
  • Make certain that the switch and LED are connected to the correct GPIO pins on the Raspberry Pi.

Going Further

Once everything is working as expected, you can set up the Raspberry Pi boards to boot from SSD instead of the Micro SD Card. Below is a list of high-level steps that I followed to boot from the SSD Drives.

Steps from https://www.tomshardware.com/reviews/raspberry-pi-headless-setup-how-to,6028.html to setup a headless Raspberry Pi.

Raspberry Pi Imager

  • Choose OS button
    • Select your OS (Pi 4)
      • Raspberry Pi OS (other)
        • Raspberry Pi OS (64-bit)
  • Choose Storage
  • Click the settings button or hit CTRL + Shift + X to bring up the settings menu
    • Set Hostname
    • Enable SSH
    • Set username and password
    • Set Wi-Fi network SSID, password, & country
    • Set Locale
    • Click Save
  • Choose Write

Enabling I2C & VNC

  • Open SSH Session
  • sudo raspi-config
    • Select Interfacing Options
      • Select I2C
        • Turn on the option
    • Select Interfacing Options
      • Select VNC
        • Turn on the option, then exit

Steps from https://github.com/richteel/pi_status to setup the display and button.

Setup Display and Button

  • Open SSH Session
    • sudo apt-get update
    • sudo apt-get upgrade
      * May want to reboot if updates were applied that require reboot
    • sudo pip3 install adafruit-blinka
    • sudo pip3 install adafruit-circuitpython-ssd1306
    • git clone https://github.com/richteel/pi_status.git
    • sudo crontab -e
    • Add the following line to the end of the file
      @reboot sh /home/pi/pi_status/display/launcher.sh
    • Reboot to make certain that the script starts at boot
      • sudo reboot now

Steps from https://www.tomshardware.com/how-to/boot-raspberry-pi-4-usb to boot from USB.

Allow booting from USB

  • Boot Raspberry Pi from SD Card
  • Open VNC to machine and use the SD Card Copier to copy SD Card to USB Drive
  • Open SSH Session
  • sudo raspi-config
    • Select Advanced Options
      • Select Boot Order
        • Select USB Boot
  • Shutdown the Raspberry Pi
    • sudo shutdown now
  • Remove the SD Card and restart the Raspberry Pi
Categories
Psion Raspberry Pi Pico

Re-creation of Psion Organiser II

In 1984, Psion launched the first practical pocket computer, the Psion Organiser I. Psion followed up with the Psion Organiser II.

Andrew Menadue has a project which recreates the Psion Organiser II with the Raspberry Pi Pico and ESP32-WROOM-32. He has several videos on YouTube and some GitHub repositories. Andrew was nice enough to send me a set of boards, which I’m in the process of building.

Bill of Materials

The bill of materials is an Excel document located on GitHub.

Power Supply

Categories
Software Development Web Application Development

Physical File Folder Tabs – HTML Solution to Print Folder Tabs

Today, I needed to print some physical folder tabs. I wanted to challenge myself a bit to see if it were possible to build an HTML application that could do the job. Ideally, I wanted to load an Excel file and use the contents of a worksheet to create the labels. I was able to find some example code that uses some AJAX libraries from CloudFlare to parse the Excel file. With that and a few other bits of code samples, I was able to build a robust local page for creating physical folder tabs that may be printed and cut to help keep my filing tidy.

The code is available on GitHub at https://github.com/richteel/FileFolderTabs.

Categories
Raspberry Pi Pico

Armachat

I have been working on the Armachat project by Peter Misenko. I rewrote the code to implement functions that Peter had not completed and added a few more. Some of the added features include:

  • Implemented detection of a long keypress
  • Dedicated keys when not in the editor
    • Q – Toggle the keyboard backlight
    • A – Toggle the display backlight
    • V – Increase volume / Long keypress to decrease volume
    • B – Increase display brightness / Long keypress to decrease display brightness
  • Ability to receive messages in all screens including editor
  • Validation of editor input
  • Confirmation prompts

I have been working on an issue with editor text input. The display update procedure takes 400 to 500 milliseconds which causes an issue as keypresses are dropped when typing quickly. Initially it was taking nearly 1 second to update the screen so some improvement has been made but it is still not good enough. I continue to work on improving the screen draw time and may deploy a few things to allow all keys to be detected and handled.

Another area for improvement is the long keypress detection. I noticed that removing the long keypress detection speed up the code enough to catch all key presses however the added functionality that the long keypress provides is too much to ignore.

GitHub locations for Peter’s code and my rewrite.

Categories
Raspberry Pi

SainSmart 2.8″ TFT LCD Display Touch Screen on Raspberry Pi

I have a SainSmart 2.8″ TFT LCD Display Touch Screen a couple of years ago from MicroCenter. I want to use it on the Raspberry Pi and was surprised that no one has posted how to do this. I looked into this a bit and it looks like it should be easy enough. One of the things that throws folks off is the display is 16 bit verses 8 bit that is typically used on these displays. You can still use them with only 8 bits of data. Unfortunately SainSmart does not provide information on their product pages to allow their products to be used with anything other that their adapters or other products.

Here are some useful links that will be used in this writeup.

  1. Product Page for SainSmart 2.8″ TFT LCD Display Touch Screen
  2. Discussion page on Raspberry Pi Forum
  3. Zip file mentioned in the Raspberry Pi Forum post by M15H
  4. Posts on Adafruit’s Leaning site
LCD Raspberry Pi
Pin Function Pin Function
1 GND 6, 9, 14, 20, 25, 30, 34, 39 GND
2 VCC 1, 17 3V3
3 NC
4 RS 12 GPIO 18
5 WR 11 GPIO 17
6 RD  1, 17 3V3
7 DB8 15 GPIO 22
8 DB9 16 GPIO 23
9 DB10 18 GPIO 24
10 DB11 19 GPIO 10
11 DB12 22 GPIO 25
12 DB13 21 GPIO 9
13 DB14 23 GPIO 11
14 DB15 24 GPIO 8
15 CS 7 GPIO 4
16 F_CS
17 RESET 26 GPIO 7
18 NC
19 LED-A 1, 17 3V3
20 NC
21 DB0 6, 9, 14, 20, 25, 30, 34, 39 GND
22 DB1 6, 9, 14, 20, 25, 30, 34, 39 GND
23 DB2 6, 9, 14, 20, 25, 30, 34, 39 GND
24 DB3 6, 9, 14, 20, 25, 30, 34, 39 GND
25 DB4 6, 9, 14, 20, 25, 30, 34, 39 GND
26 DB5 6, 9, 14, 20, 25, 30, 34, 39 GND
27 DB6 6, 9, 14, 20, 25, 30, 34, 39 GND
28 DB7 6, 9, 14, 20, 25, 30, 34, 39 GND
29 D_CLK -23-  -GPIO 11-
30 D_CS -26- -GPIO 7-
31 D_DIN -19- -GPIO 10-
32 D_BUSY
33 D_OUT -21- -GPIO 9-
34 D_Penirq
35 SD_OUT(F_SI)
36 SD_SCLK(F_SCK)
37 SD_DIN(F_SO)
38 SD_CS
39 F_WP
40 F_HOLD

Raspberry Pi Pinouts
Raspberry Pi Pinouts

 

ILI9325

http://www.anya.bagge.no/hacks/2018/02/17/tft-panel/

https://www.raspberry-pi-geek.com/Archive/2014/07/TFT-touchscreens-for-the-Raspberry-Pi

https://www.raspberrypi.org/forums/viewtopic.php?t=208264

 

 

Categories
Android Microcontroller

ATtiny85

I’m once again revisiting the ATtiny85 and wanted to see how to load sketches through USB in addition to the ICSP connection. I ran into quite a few stumbling blocks so I want to capture what I found in hopes that it will help others.

 

Categories
Arduino

All Electronics LCD-101 (256×128 LCD) with Arduino – Part 2

I posted about the All Electronics LCD-101 display in February 2018. The other day, I noticed that they were back in stock, so I decided to dust off where I last left off with the display. I had designed an I2C backpack with a contrast voltage driver for the display and modified the test Arduino code that I had to work with the backpack. The code was incomplete, so I needed to pick up where I left off, start over, or look at extending another library. I did look at the U8g2 library (https://github.com/olikraus/U8g2_Arduino) but it does not work well with the display. It may be because it is expecting the display to be 240 x 128 rather than 256 x 128.

LCD Pins

Pin No. Symbol Level Function JP2 Pin I2C bit
1 FG 0V Frame Ground 1 N/A
2 Vss(Gnd) 0V Ground 1 N/A
3 Vdd(Vcc) +5V Power supply voltage for logic and LCD 2 N/A
4 Vo Operating voltage for LCD (variable) N/A N/A
5 /RES H/L Reset signal 3 A0
6 /RD H/L Read signal 4 A1
7 /WR H/L Write signal 5 A2
8 /CS H/L Chip select signal 6 A3
9 A0 H/L Data type select signal 7 A4
10 DB0 H/L Display data bit 0 8 B0
11 DB1 H/L Display data bit 1 9 B1
12 DB2 H/L Display data bit 2 10 B2
13 DB3 H/L Display data bit 3 11 B3
14 DB4 H/L Display data bit 4 12 B4
15 DB5 H/L Display data bit 5 13 B5
16 DB6 H/L Display data bit 6 14 B6
17 DB7 H/L Display data bit 7 15 B7

 

A0 /CS /WR /RD /RES
I2C A4 I2C A3 I2C A2 I2C A1 I2C A0 Binary MASK HEX Decimal Valid Op Valid Result Function/Note
X X X X 0 11110 0x1E 30 OR 11110 Reset
X 0 0 0 1 01111 0x0F 15 AND 00001 Invalid State
X 0 1 1 1 01111 0x0F 15 AND 00111 No Operation
X 1 X X 1 01001 0x09 9 AND 01001 No Operation
0 0 0 1 1 00011 0x03 3 EQUAL/XOR 00011 Display data and parameter write
0 0 1 0 1 00101 0x05 5 EQUAL/XOR 00101 Status flag read
1 0 0 1 1 10011 0x13 19 EQUAL/XOR 10011 Command write
1 0 1 0 1 10101 0x15 21 EQUAL/XOR 10101 Display data and cursor address read

 

 

A0 /CS /WR /RD /RES Mask Valid Result
A4 A3 A2 A1 A0 Binary HEX Decimal Valid Op Binary HEX Decimal Function/Note
X X X X 0 11110 0x1E 30 OR 11110 0x1E 30 Reset
X 0 0 0 1 01111 0x0F 15 AND 00001 0x01 1 Invalid State
X 0 1 1 1 01111 0x0F 15 AND 00111 0x07 7 No Operation
X 1 X X 1 01001 0x09 9 AND 01001 0x09 9 No Operation
0 0 0 1 1 00011 0x03 3 EQUAL/XOR 00011 0x03 3 Display data and parameter write
0 0 1 0 1 00101 0x05 5 EQUAL/XOR 00101 0x05 5 Status flag read
1 0 0 1 1 10011 0x13 19 EQUAL/XOR 10011 0x13 19 Command write
1 0 1 0 1 10101 0x15 21 EQUAL/XOR 10101 0x15 21 Display data and cursor address read

 

12 June 2022 Update

I had a question about this display, so I have updated the GitLab repository at https://gitlab.com/richteel/LCD-101/ to include the I2C Backpack that I designed for the LCD with a negative charge pump for the contrast and I2C or SPI interface for Arduino and Raspberry Pi. You may order the black PCB from Oshpark at https://oshpark.com/shared_projects/LwLCCjaW.

The schematic for the backpack is in the LCD-101/LCD-101 2020/I2C Backpack folder and is named I2C Backpack.pdf.