‹ Pico Portal OS

Pico Portal 1.x reference

The original portal demo, before it grew into an OS.

The first Pico Portal had one job: run a portable captive portal demo with its own display. This page keeps the original design around for reference.

Historical reference. The file names, settings, and controls here belong to the 1.x project. For a new installation, use Pico Portal OS 2.x and its current build instructions.

Original Pico Portal device
The original Pico Portal hardware. The current OS still uses the Pico W and supported Pimoroni displays.

A demo I could bring into a classroom

I built this because I wanted a small device for explaining how captive portals work. Access points, DNS, and form submissions make a lot more sense when people can watch the requests arrive on the device.

The Pico W handled the wireless side, and the display showed status and submitted data. Once the files were installed, I could power it over USB and run the demo without a computer attached.

How 1.x booted

Version 1.x started an access point, a DNS catch-all service, and a small web server at boot. The selected HTML file became the portal page. The server handled common captive portal detection paths and kept the browser inside the local demo.

Settings lived in options.json. They covered the network name, password, local domain, template, display profile, brightness, timestamps, and dark mode. All templates lived in one templates/ folder. The current OS splits login and success pages.

The screen was part of the demonstration

The screen showed startup messages, connection activity, and submitted form fields. It wrapped everything for the small panel and wrote the same messages to log.txt for later review.

The logging matters here. We used made-up values in the classroom, never real account credentials. A local portal can still record whatever someone types into it. Showing that was the point of the demo.

In 1.x, B opened template selection, A chose a template, and X and Y scrolled. I could switch the active page without copying files or restarting everything. These letter-based controls are different from the physical-position navigation in 2.x.

Small services kept it manageable

The entry point connected the portal, display, messages, menu, and buttons, then ran the server and input loops with uasyncio. PortalService owned the network and routes. ScreenService set up the display. MessagesService handled wrapping, scrolling, and file logging.

MenuService found the available templates, and ButtonService supplied the input. Keeping those jobs separate let me change a page or display detail without piling everything into the main loop.

Why it stays here

The old design shows where the project started and helps when you run into instructions written for older hardware. It's much smaller: one app with a local status screen.

With 2.x, the portal moved behind a menu and the device picked up other tools, games, settings, and diagnostics. USB screen capture came in 2.1.0. Those features belong on the current project page, not this reference.

The repository history holds the earlier source. Keep the software version and its instructions together when digging through it. Mixing generations is a reliable way to waste an afternoon.