‹ Guides

Taking a Pico Portal OS screenshot over USB

Check serial access, understand the capture formats, and account for the interruption and soft reset.

The Screen Capture tool reads a Pico Portal OS display over its USB serial connection and saves a PNG. It doesn't point a camera at the screen or record a video. The device needs a build with the ppos_screenshot() hook, and the browser needs access to its serial port.

One detail is easy to miss: capture interrupts the running app and restarts the OS afterward. Save any work that depends on the current app staying open before you begin.

Get the browser and port ready

Open the tool in desktop Chrome or Edge with Web Serial support. Use HTTPS, or localhost while developing. The page tells you if serial support isn't available. The Web Serial documentation explains the browser permission and secure-context requirements.

Connect the Pico with a USB data cable. A cable that supplies power without data won't provide the port the tool needs. Close Thonny, mpremote, and any other serial console first. An editor can hold onto the port even after you've stopped typing in its terminal.

Select Connect and take screenshot, then choose the Pico's port in the browser's dialog. That choice grants this page access to the selected device. Don't choose an unrelated serial device just because it shows up in the list.

What happens during capture

The tool opens the port at 115200 baud, sends Ctrl-C to reach the MicroPython console, and requests __main__.ppos_screenshot(). The device streams the framebuffer it already has, with a header giving the width, height, and pixel format. The browser checks the payload length and decodes the pixels locally.

Afterward, the tool sends Ctrl-D for a soft reset and releases the port. It tries the same cleanup if a capture fails or is canceled after the interrupt. Your previous app doesn't pick up where it left off. The OS boots again. It's one screenshot at a time, not live screen sharing.

Wait for the screenshot preview and the restart status, then select Save PNG. The saved image has the captured display's dimensions. Check its orientation and colors before using it in project documentation.

Capture formats and image assets are different

The current 2.1.0 source uses RGB332 for the small display and indexed P8 for the larger profile when supported, with an RGB332 fallback. Both use one byte per framebuffer pixel. P8 needs the accompanying palette to turn indexes into colors. RGB332 packs channel information into the byte itself.

The browser also accepts big-endian and little-endian RGB565 capture payloads. That support doesn't mean the current OS always sends RGB565. The header decides how the data is read. Treating an RGB332 byte stream as pairs of RGB565 bytes gives the wrong colors and pixel count.

The Image Converter has a different job: it prepares two-byte RGB565 assets for the device. Don't use its BIN output in place of a screenshot payload just because both involve the same display. The asset guide covers that format.

A protocol example, not a device test

This tiny fixture shows the structure of an RGB332 transfer:

PPOS_SCREEN 2 2 RGB332
PPOS_PALETTE -
PPOS_DATA
00e01cff
PPOS_END

It describes four pixels, not a real 2-by-2 Pico panel. The browser parser was checked against this fixture in Chromium 146 on Windows. It produces black, red, green, and a light combined color using the device's channel mapping. The fixture checks the decoding, not the USB wiring, an installed firmware build, or the physical display.

The current project screenshots are on the Pico Portal page. For your own device, take a fresh capture after installing the current build and compare it with the screen in front of you.

If the transfer stops

A missing ppos_screenshot() message means the installed firmware doesn't have the hook. A busy port means another console still has it open. A timeout or incomplete byte count means the transfer didn't finish, so don't treat a partial image as a successful capture.

Let the restart cleanup finish, check the cable and installed build, and try again. If the browser couldn't send its reset, restart the Pico yourself before opening another session. Connecting from several programs over and over makes the port problem harder to track down.