# Pixelfed Photo Viewer on Fruit Jam

## Overview

![Adafruit Fruit Jam in 3D Printed case connected to a small display. On display is a photo of a cat looking through the handle of a white wicker basket.](https://cdn-learn.adafruit.com/assets/assets/000/140/940/medium800/circuitpython_pixelfed_photo_hero.png?1762360294 )

[Pixelfed](https://pixelfed.org/) is a decentralized photo sharing social media system. It supports the&nbsp;[Fediverse](https://en.wikipedia.org/wiki/Fediverse) protocols, so users and posts can interact with other Fediverse services like [Mastodon](https://en.wikipedia.org/wiki/Mastodon_(social_network)). This project for the Adafruit Fruit Jam downloads images of cats or any other hashtags you search for from [Pixelfed.social](https://pixelfed.social), the largest Pixelfed instance, and displays them via the HSTX/DVI output port on the Fruit Jam.

## Parts
### Adafruit Fruit Jam - Mini RP2350 Computer

[Adafruit Fruit Jam - Mini RP2350 Computer](https://www.adafruit.com/product/6200)
We were catching up on a recent [hackaday hackchat with eben upton](https://hackaday.io/event/202122-raspberry-pi-hack-chat-with-eben-upton)&nbsp;and learned some fun facts: such as the DVI hack for the RP2040 was inspired by <a...></a...>

Out of Stock
[Buy Now](https://www.adafruit.com/product/6200)
[Related Guides to the Product](https://learn.adafruit.com/products/6200/guides)
![Angled shot of assembled mini computer PCB with plate.](https://cdn-shop.adafruit.com/640x480/6200-10.jpg)

### HDMI Cable - 1 meter

[HDMI Cable - 1 meter](https://www.adafruit.com/product/608)
Connect two HDMI devices together with this basic HDMI cable. It has nice molded grips for easy installation, and is 1 meter long (about 3 feet). This is a HDMI 1.3 cable.

We're now stocking a very fancy Official Raspberry Pi cable with overmolding and a Pi logo. Please note...

In Stock
[Buy Now](https://www.adafruit.com/product/608)
[Related Guides to the Product](https://learn.adafruit.com/products/608/guides)
![Official Raspberry Pi HDMI Cable - 1 meter](https://cdn-shop.adafruit.com/640x480/608-03.jpg)

### USB Type A to Type C Cable - approx 1 meter / 3 ft long

[USB Type A to Type C Cable - approx 1 meter / 3 ft long](https://www.adafruit.com/product/4474)
As technology changes and adapts, so does Adafruit. This&nbsp;&nbsp; **USB Type A to Type C** cable will help you with the transition to USB C, even if you're still totin' around a USB Type A hub, computer or laptop.

USB C is the latest industry-standard connector for...

In Stock
[Buy Now](https://www.adafruit.com/product/4474)
[Related Guides to the Product](https://learn.adafruit.com/products/4474/guides)
![Angled shot of a coiled black, USB-C to USB-A cable.](https://cdn-shop.adafruit.com/640x480/4474-02.jpg)

### Snap-on Enclosure for Adafruit Fruit Jam

[Snap-on Enclosure for Adafruit Fruit Jam](https://www.adafruit.com/product/6425)
Here is a cool&nbsp;and minimal enclosure for your [Fruit Jam](https://www.adafruit.com/product/6200)&nbsp;to keep it safe during use and transport. This case has been custom-designed and 3D printed to accommodate all&nbsp;connection ports of the Fruit Jam. No screws or...

In Stock
[Buy Now](https://www.adafruit.com/product/6425)
[Related Guides to the Product](https://learn.adafruit.com/products/6425/guides)
![Angled Demo Shot of the Assembled Snap-on Enclosure with the Fruit Jam inside and powered on showing a rainbow effect of the LED's.](https://cdn-shop.adafruit.com/640x480/6425-02.jpg)

### 7" Display 1280x800 (720p) IPS + Speakers - HDMI/VGA/NTSC/PAL

[7" Display 1280x800 (720p) IPS + Speakers - HDMI/VGA/NTSC/PAL](https://www.adafruit.com/product/1667)
Yes, this is an adorable small HDMI television with incredibly high resolution **and built in 3W stereo speakers**! We tried to get the smallest possible HDMI/VGA display with high-res, high-contrast visibility. The visible display measures only 7" (17.8cm) diagonal, and the TFT comes...

In Stock
[Buy Now](https://www.adafruit.com/product/1667)
[Related Guides to the Product](https://learn.adafruit.com/products/1667/guides)
![Front view of assembled and powered on HDMI 4 Pi - 7" Display. The monitor displays a desktop background with a raspberry logo.](https://cdn-shop.adafruit.com/640x480/1667-00.jpg)

# Pixelfed Photo Viewer on Fruit Jam

## Install CircuitPython

[CircuitPython](https://github.com/adafruit/circuitpython) is a derivative of [MicroPython](https://micropython.org) designed to simplify experimentation and education on low-cost microcontrollers. It makes it easier than ever to get prototyping by requiring no upfront desktop software downloads. Simply copy and edit files on the **CIRCUITPY** drive to iterate.

## CircuitPython Quickstart

Follow this step-by-step to quickly get CircuitPython running on your board.

Warning: Please use the latest release of 10.x or higher for the Fruit Jam. Also use the latest libraries for the best functionality.

[Download the latest version of CircuitPython for this board via circuitpython.org](https://circuitpython.org/board/adafruit_fruit_jam/)
 **Click the link above to download the latest CircuitPython UF2 file.**

Save it wherever is convenient for you.

![install_circuitpython_on_rp2040_RP2040_UF2_downloaded.jpg](https://cdn-learn.adafruit.com/assets/assets/000/101/655/medium640/install_circuitpython_on_rp2040_RP2040_UF2_downloaded.jpg?1618943202)

![reset and boot highlighted](https://cdn-learn.adafruit.com/assets/assets/000/138/708/medium800/adafruit_products_Resetboot.jpg?1754331128 )

To enter the bootloader, hold down the **BOOT/**** BOOTSEL button**(highlighted in red above), and while continuing to hold it (don't let go!), press and release the**reset button**(highlighted in red or blue above).&nbsp;**Continue to hold the BOOT/BOOTSEL button until the RP2350 drive appears!**

If the drive does not appear, release all the buttons, and then repeat the process above.

You can also start with your board unplugged from USB, press and hold the BOOTSEL button (highlighted in red above), continue to hold it while plugging it into USB, and wait for the drive to appear before releasing the button.

A lot of people end up using charge-only USB cables and it is very frustrating! **Make sure you have a USB cable you know is good for data sync.**

You will see a new disk drive appear called **RP2350**.

&nbsp;

Drag the **adafruit-circuitpython-_boardname_-_language_-_version_.uf2** file to **RP2350.**

![install_circuitpython_on_rp2350_Screenshot_2024-09-11_111518.png](https://cdn-learn.adafruit.com/assets/assets/000/132/253/medium640/install_circuitpython_on_rp2350_Screenshot_2024-09-11_111518.png?1726067809)

![install_circuitpython_on_rp2350_Screenshot_2024-09-11_111742.png](https://cdn-learn.adafruit.com/assets/assets/000/132/254/medium640/install_circuitpython_on_rp2350_Screenshot_2024-09-11_111742.png?1726067866)

The **RP2350** drive will disappear and a new disk drive called **CIRCUITPY** will appear.

That's it, you're done! :)

![install_circuitpython_on_rp2350_Screenshot_2024-09-11_111843.png](https://cdn-learn.adafruit.com/assets/assets/000/132/255/medium640/install_circuitpython_on_rp2350_Screenshot_2024-09-11_111843.png?1726067932)

## Safe Mode

You want to edit your **code.py** or modify the files on your **CIRCUITPY** drive, but find that you can't. Perhaps your board has gotten into a state where **CIRCUITPY** is read-only. You may have turned off the **CIRCUITPY** drive altogether. Whatever the reason, safe mode can help.

Safe mode in CircuitPython does not run any user code on startup, and disables auto-reload. This means a few things. First, safe mode _bypasses any code in_ **boot.py** (where you can set **CIRCUITPY** read-only or turn it off completely). Second, _it does not run the code in_ **code.py**. And finally, _it does not automatically soft-reload when data is written to the_ **CIRCUITPY** _drive_.

Therefore, whatever you may have done to put your board in a non-interactive state, safe mode gives you the opportunity to correct it without losing all of the data on the **CIRCUITPY** drive.

### Entering Safe Mode
To enter safe mode when using CircuitPython, plug in your board or hit reset (highlighted in red above). Immediately after the board starts up or resets, it waits 1000ms. On some boards, the onboard status LED (highlighted in green above) will blink yellow during that time. If you press reset during that 1000ms, the board will start up in safe mode. It can be difficult to react to the yellow LED, so you may want to think of it simply as a slow double click of the reset button. (Remember, a fast double click of reset enters the bootloader.)

### In Safe Mode

If you successfully enter safe mode on CircuitPython, the LED will intermittently blink yellow three times.

If you connect to the serial console, you'll find the following message.

```terminal
Auto-reload is off.
Running in safe mode! Not running saved code.

CircuitPython is in safe mode because you pressed the reset button during boot. Press again to exit safe mode.

Press any key to enter the REPL. Use CTRL-D to reload.
```

You can now edit the contents of the **CIRCUITPY** drive. Remember, _your code will not run until you press the reset button, or unplug and plug in your board, to get out of safe mode._

## Flash Resetting UF2

If your board ever gets into a really _weird_ state and CIRCUITPY doesn't show up as a disk drive after installing CircuitPython, try loading this 'nuke' UF2 to RP2350. which will do a 'deep clean' on your Flash Memory. **You will lose all the files on the board** , but at least you'll be able to revive it! After loading this UF2, follow the steps above to re-install CircuitPython.

[Download flash erasing "nuke" UF2 for RP2350](https://cdn-learn.adafruit.com/assets/assets/000/132/526/original/rp2350_flash_nuke.uf2)
# Pixelfed Photo Viewer on Fruit Jam

## Create Your settings.toml File

CircuitPython works with WiFi-capable boards to enable you to make projects that have network connectivity. This means working with various passwords and API keys. As of [CircuitPython 8](https://circuitpython.org/downloads), there is support for a **settings.toml** file. This is a file that is stored on your **CIRCUITPY** drive, that contains all of your secret network information, such as your SSID, SSID password and any API keys for IoT services. It is designed to separate your sensitive information from your **code.py** file so you are able to share your code without sharing your credentials.

CircuitPython previously used a **secrets.py** file for this purpose. The **settings.toml** file is quite similar.

Warning: Your **settings.toml** file should be stored in the main directory of your **CIRCUITPY** drive. It should not be in a folder.

## CircuitPython **settings.toml** File

This section will provide a couple of examples of what your **settings.toml** file should look like, specifically for CircuitPython WiFi projects in general.

The most minimal **settings.toml** file must contain your WiFi SSID and password, as that is the minimum required to connect to WiFi. Copy this example, paste it into your **settings.toml** , and update:

- `your_wifi_ssid`
- `your_wifi_password`

```auto
CIRCUITPY_WIFI_SSID = "your_wifi_ssid"
CIRCUITPY_WIFI_PASSWORD = "your_wifi_password"
```

Many CircuitPython network-connected projects on the Adafruit Learn System involve using Adafruit IO. For these projects, you must _also_ include your Adafruit IO username and key. Copy the following example, paste it into your settings.toml file, and update:

- `your_wifi_ssid`
- `your_wifi_password`
- `your_aio_username`
- `your_aio_key`

```auto
CIRCUITPY_WIFI_SSID = "your_wifi_ssid"
CIRCUITPY_WIFI_PASSWORD = "your_wifi_password"
ADAFRUIT_AIO_USERNAME = "your_aio_username"
ADAFRUIT_AIO_KEY = "your_aio_key"
```

Some projects use different variable names for the entries in the **settings.toml** file. For example, a project might use `ADAFRUIT_AIO_ID` in the place of `ADAFRUIT_AIO_USERNAME`. **If you run into connectivity issues, one of the first things to check is that the names in the settings.toml file match the names in the code.**

Warning: Not every project uses the same variable name for each entry in the **settings.toml** file! Always verify it matches the code.

## **settings.toml** File Tips
Here is an example **settings.toml** file.

```auto
# Comments are supported
CIRCUITPY_WIFI_SSID = "guest wifi"
CIRCUITPY_WIFI_PASSWORD = "guessable"
CIRCUITPY_WEB_API_PORT = 80
CIRCUITPY_WEB_API_PASSWORD = "passw0rd"
test_variable = "this is a test"
thumbs_up = "\U0001f44d"
```

In a **settings.toml** file, it's important to keep these factors in mind:

- Strings are wrapped in double quotes; ex: `"your-string-here"`
- Integers are _ **not** _ quoted and may be written in decimal with optional sign (`+1`, `-1`, `1000`) or hexadecimal (`0xabcd`).
  - Floats (decimal numbers), octal (`0o567`) and binary (`0b11011`) are not supported.

- Use `\u` escapes for weird characters, `\x` and `\ooo` escapes are not available in **.toml** files
  - Example: `\U0001f44d` for 👍 (thumbs up emoji) and `\u20ac` for € (EUR sign)

- Unicode emoji, and non-ASCII characters, stand for themselves as long as you're careful to save in "UTF-8 without BOM" format

&nbsp;

&nbsp;

When your&nbsp; **settings.toml&nbsp;** file is ready, you can save it in your text editor with the **.toml** &nbsp;extension.

![adafruit_products_dotToml.jpg](https://cdn-learn.adafruit.com/assets/assets/000/117/071/medium640/adafruit_products_dotToml.jpg?1671034293)

## Accessing Your **settings.toml** Information in **code.py**
In your **code.py** file, you'll need to `import` the `os` library to access the **settings.toml** file. Your settings are accessed with the `os.getenv()` function. You'll pass your settings entry to the function to import it into the **code.py** file.

```python
import os

print(os.getenv("test_variable"))
```

![](https://cdn-learn.adafruit.com/assets/assets/000/117/072/medium800/adafruit_products_tomlOutput.jpg?1671034496)

In the upcoming CircuitPython WiFi examples, you'll see how the **settings.toml&nbsp;** file is used for connecting to your SSID and accessing your API keys.

# Pixelfed Photo Viewer on Fruit Jam

## Code

## Getting the Program's Files

To use the application, you need to obtain **code.py** with the game program to place on the Fruit Jam **CIRCUITPY** drive.

Thankfully, this can be done in one go. In the example below, click the **Download Project Bundle** button below to download the necessary libraries and the **code.py** file in a zip file.

Connect your board to your computer via a known good data+power USB cable. The board should show up in your File Explorer/Finder (depending on your operating system) as a flash drive named **CIRCUITPY**.

Extract the contents of the zip file, copy the **lib** directory files to **CIRCUITPY/lib**. Copy the **code.py** file&nbsp;to your **CIRCUITPY** drive. The program should self start.

https://github.com/adafruit/Adafruit_Learning_System_Guides/blob/main/Fruit_Jam/Fruit_Jam_Pixelfed_Photos/code.py

## Drive Structure

After copying the files, your drive should look like the listing below. It can contain other files as well, but must contain these at a minimum.

![Screenshot of required project files and libraries](https://github.com/adafruit/Adafruit_Learning_System_Guides/blob/folder-images/Fruit_Jam_Fruit_Jam_Pixelfed_Photos.png?raw=true )

# Pixelfed Photo Viewer on Fruit Jam

## Code Explanation

## **code.py**

This is a very basic project with only a **code.py** file necessary to run it. First, the code initializes a variable for the tag to search (`search_tag`). The `search_tag` to an f-string that holds URL for the Pixelfed JSON API. Next the DVI/HSTX display is set to 320x240 resolution. WiFi and Adafruit IO details are pulled from the&nbsp; **settings.toml** file. If there is already a downloaded image file, an&nbsp;`OnDiskBitmap` and `TileGrid` are created and added to the `main_group` to show it on the display. Next the code connects to the configured WiFi network and initializes the `adafruit_requests` module.

There are two helper functions:

- `fetch_pixelfed_search()` - Uses the Pixelfed JSON API to search for posts containing the specified tag. Caches the search results into **CPSAVES** as **/saves/pixelfed.json**.
- `build_img_url_list()` - Reads the search results from the cached file and extracts just the preview URLs for each image contained in the posts that appear in the results. Randomizes the order of the URLs in the list.

The main loop iterates over the image URLs in the randomized list. For each one, it uses the Adafruit IO conversion service to convert the image to BMP and resize it to fit within the 320x240 display size. The converted and resized image is downloaded to **CPSAVES** as **/saves/downloaded\_img.bmp**. After being downloaded, the image is shown on the display with an `OnDiskBitmap` and accompanying `TileGrid`. The code sleeps for a few minutes and then moves on to the next image in the list.

The **code.py** file is embedded below. It contains comments that explain the purpose of each line or section of code.

https://github.com/adafruit/Adafruit_Learning_System_Guides/blob/main/Fruit_Jam/Fruit_Jam_Pixelfed_Photos/code.py

# Pixelfed Photo Viewer on Fruit Jam

## Use

The Photo Viewer requires an internet connection as well as an Adafruit IO username and authentication key. If you haven't already done so, follow the directions on the&nbsp;[Create Your settings.toml File](https://learn.adafruit.com/pixelfed-photo-viewer-on-fruit-jam/create-your-settings-toml-file) page then return here. You must have all of the following values filled in inside of the **settings.toml** file.

```auto
CIRCUITPY_WIFI_SSID = "your_wifi_ssid"
CIRCUITPY_WIFI_PASSWORD = "your_wifi_password"
ADAFRUIT_AIO_USERNAME = "your_aio_username"
ADAFRUIT_AIO_KEY = "your_aio_key"
```

## Specify Tag Search Term

By default the project searches for posts containing the `"cats"` hashtag on pixelfed.social. The search term can be easily modified by changing the value of the `search_tag` variable near the top of **code.py.**

For example to change it to search for `"birds"` instead:

```python
# what kind of images to search for
search_tag = "birds"
```

## Display Photos

The code will download a cached copy of the JSON tag search results, then automatically begin showing photos from the results on the display. The photos are resized using the Adafruit IO image converter service to fit onto the 320x240 resolution display. The small display size was chosen to avoid memory errors from larger image files.

Every few minutes a new photo will be shown. Once per hour, it will fetch the latest search results for the specified tag. The order of the images is randomized so it won't be the same every time.

![Adafruit Fruit Jam in 3D Printed case connected to a small display. On display is a photo of a cat looking through the handle of a white wicker basket.](https://cdn-learn.adafruit.com/assets/assets/000/140/942/medium800/circuitpython_pixelfed_photo_hero.png?1762361671 )


## Featured Products

### Adafruit Fruit Jam - Mini RP2350 Computer

[Adafruit Fruit Jam - Mini RP2350 Computer](https://www.adafruit.com/product/6200)
We were catching up on a recent [hackaday hackchat with eben upton](https://hackaday.io/event/202122-raspberry-pi-hack-chat-with-eben-upton)&nbsp;and learned some fun facts: such as the DVI hack for the RP2040 was inspired by <a...></a...>

Out of Stock
[Buy Now](https://www.adafruit.com/product/6200)
[Related Guides to the Product](https://learn.adafruit.com/products/6200/guides)
### HDMI Cable - 1 meter

[HDMI Cable - 1 meter](https://www.adafruit.com/product/608)
Connect two HDMI devices together with this basic HDMI cable. It has nice molded grips for easy installation, and is 1 meter long (about 3 feet). This is a HDMI 1.3 cable.

We're now stocking a very fancy Official Raspberry Pi cable with overmolding and a Pi logo. Please note...

In Stock
[Buy Now](https://www.adafruit.com/product/608)
[Related Guides to the Product](https://learn.adafruit.com/products/608/guides)
### USB Type A to Type C Cable - approx 1 meter / 3 ft long

[USB Type A to Type C Cable - approx 1 meter / 3 ft long](https://www.adafruit.com/product/4474)
As technology changes and adapts, so does Adafruit. This&nbsp;&nbsp; **USB Type A to Type C** cable will help you with the transition to USB C, even if you're still totin' around a USB Type A hub, computer or laptop.

USB C is the latest industry-standard connector for...

In Stock
[Buy Now](https://www.adafruit.com/product/4474)
[Related Guides to the Product](https://learn.adafruit.com/products/4474/guides)
### Snap-on Enclosure for Adafruit Fruit Jam

[Snap-on Enclosure for Adafruit Fruit Jam](https://www.adafruit.com/product/6425)
Here is a cool&nbsp;and minimal enclosure for your [Fruit Jam](https://www.adafruit.com/product/6200)&nbsp;to keep it safe during use and transport. This case has been custom-designed and 3D printed to accommodate all&nbsp;connection ports of the Fruit Jam. No screws or...

In Stock
[Buy Now](https://www.adafruit.com/product/6425)
[Related Guides to the Product](https://learn.adafruit.com/products/6425/guides)
### 7" Display 1280x800 (720p) IPS + Speakers - HDMI/VGA/NTSC/PAL

[7" Display 1280x800 (720p) IPS + Speakers - HDMI/VGA/NTSC/PAL](https://www.adafruit.com/product/1667)
Yes, this is an adorable small HDMI television with incredibly high resolution **and built in 3W stereo speakers**! We tried to get the smallest possible HDMI/VGA display with high-res, high-contrast visibility. The visible display measures only 7" (17.8cm) diagonal, and the TFT comes...

In Stock
[Buy Now](https://www.adafruit.com/product/1667)
[Related Guides to the Product](https://learn.adafruit.com/products/1667/guides)

## Related Guides

- [Adafruit Fruit Jam](https://learn.adafruit.com/adafruit-fruit-jam.md)
- [Logic Gates Simulator on Fruit Jam](https://learn.adafruit.com/logic-gates-simulator-on-fruit-jam.md)
- [Tiny Wiki for CircuitPython](https://learn.adafruit.com/tiny-wiki-for-circuitpython.md)
- [Holiday Card Maker on Fruit Jam](https://learn.adafruit.com/holiday-card-maker-on-fruit-jam.md)
- [Egg Hunt Maze Game on Fruit Jam](https://learn.adafruit.com/egg-hunt-maze-game-on-fruit-jam.md)
- [Fruit Jam Sega Genesis](https://learn.adafruit.com/fruit-jam-sega-genesis.md)
- [Apple //e Emulator on Fruit Jam](https://learn.adafruit.com/apple-e-emulator-on-fruit-jam.md)
- [Fruit Jam, Zork and the Z Machine](https://learn.adafruit.com/zork-and-the-z-machine.md)
- [NeXT Bus Mouse to USB HID with CircuitPython](https://learn.adafruit.com/next-bus-mouse-to-usb-hid-with-circuitpython.md)
- [Smart Mirror with PyPortal](https://learn.adafruit.com/smart-mirror-with-pyportal.md)
- [Adafruit PiCowbell DVI Output](https://learn.adafruit.com/adafruit-picowbell-dvi-output.md)
- [CircuitPython Connected Weather Cloud Lamp](https://learn.adafruit.com/circuitpython-connected-weather-cloud.md)
- [File Glider](https://learn.adafruit.com/file-glider.md)
- [Adafruit IO Connected Animated GIF Display](https://learn.adafruit.com/adafruit-io-connected-animated-gif-display.md)
- [Adafruit ATWINC1500 WiFi Breakout](https://learn.adafruit.com/adafruit-atwinc1500-wifi-module-breakout.md)
- [Adafruit Hallowing M4](https://learn.adafruit.com/adafruit-hallowing-m4.md)
