RSS

// Beach Face

I made an e-paper screen that tells me whether it’s worth a swim. It shows the sea temperature, the waves, the tide, the air, and whether any sewage outfalls nearby are spilling. Next to all that is a simple face. Happy, flat or sad. And a two-line phrase, like GET YOUR / COSSIE ON, written by one of the language models that make up Pan on my Mac mini.

Beach Face on a wooden desk: a small white case with a square e-paper screen. BEACH FACE and the date along the top, RAMSGATE SANDS, GET IN THE SEA beside a big smiley face, then the sea at 19.2 degrees, waves 0.4m, tide out and air 21 degrees, each with a little icon, and 7/7 outfalls clear and excellent water quality along the bottom

It’s called Beach Face, a nod to the Resting Beach Face T-shirt from Harbour & Tide, my partner’s business.

A white T-shirt laid flat on rippled sand, with RESTING BEACH FACE printed across the back in big orange letters

Also: a font chosen pixel by pixel, a language model writing micro-copy, and a face that’s sad every night.

The board

It’s a Waveshare ESP32-S3 with a 1.54-inch e-paper screen, 200 pixels square, black and white. It lives in a little white case, which is about as far from Tick’s glowing strip as a screen can get. E-paper only uses power when the picture changes. Even unplugged, the screen keeps whatever it last showed.

From the web

Beach Face started as my Thanet Beach Conditions experiment, a web page that pulls together the weather, sea, tide and sewage data for the bathing beaches around Thanet. I live in Ramsgate. Ramsgate Sands is my closest beach. I wanted that one on my desk (or on the counter of Harbour & Tide) so it can be used without opening a browser.

The relay

The board is deliberately dumb. A small service on my mini PC cluster, next to the one that talks to Pan’s desk board, does the work. Every 15 minutes it fetches the same feeds as the web experiment: Open-Meteo for the weather and the sea, the UK Hydrographic Office’s EasyTide for Ramsgate’s tides, and Surfers Against Sewage’s live feed of storm overflows.

It picks the face, asks for new phrases if anything’s changed, and draws the whole screen, plus a strip for each phrase. The board downloads that every five minutes, about ten kilobytes, and puts it on the screen. It never reads a number or draws a letter, apart from the clock, which it keeps itself from an internet time server.

So I can change the layout, the rules, the prompt or a data source without touching the board. Same idea as Pan’s first home and Tick.

A diagram of Beach Face. Open-Meteo, ADMIRALTY EasyTide and Surfers Against Sewage on the internet feed beach-relay on the mini PC cluster every 15 minutes. The relay picks a face, sends the conditions and face to gpt-oss on the Mac mini for new phrases only when something changes, and draws the whole screen plus a strip per phrase. Beach Face downloads screen.bin every 5 minutes, shows the next phrase every 20 seconds and updates its clock on the minute

One bit graphical interface

With e-paper, every pixel is black or white. No grey, no smoothing.

Each reading gets an icon in the same spot in its quarter of the grid. A thermometer, some waves, an arrow or a mark for the tide, and the sun, the moon, a cloud or rain. The icons are placeholders Claude drew for the prototype.

E-paper is slow, and it flashes. A full refresh blinks the whole screen black and white a few times. A partial refresh changes only the pixels that need changing, with no flash, but leaves a faint ghost of what was there before. So the phrase changes every 20 seconds with a partial refresh, the clock ticks over every minute the same way, and once every half hour there’s a full refresh to wipe the ghosts. In between, the chip sleeps with its Wi-Fi off.

The upside of all these limits is a screen that’s a lot more ambient. It changes slowly and doesn’t glow, so it never demands attention. Like Tick, it doesn’t speak out loud because its job is to be background information.

Typography

Typography is hard on a screen that can’t support antialiasing. Type has to land on whole pixels, or it looks broken.

The word Sea in Inconsolata, magnified so each pixel shows. On the left, anti-aliased: the curves are smoothed with grey pixels along their edges. On the right, aliased in one bit, as on Beach Face: every pixel is black or white, so the curves become steps

The big type is Inconsolata, the same font as this site, at 22 pixels and a weight of 850. Inconsolata’s characters are half an em wide, so at odd sizes every other letter starts on half a pixel and comes out a slightly different shape. At most weights the strokes fall somewhere between two and three pixels, so some come out thin and some thick. At 22 and 850 most strokes land on whole pixels, two or three wide.

Each letter is drawn on its own, in a fixed slot one pixel wider than the font asks for, because the usual text layout nudged letters off the grid and wide ones like M and W touched their neighbours. The phrases are in capitals so a lowercase y can’t dangle into the line below.

Two letters still came out wrong. The K sat a pixel too high, so it got nudged down. The M sat high too, with one thick leg and one thin one, so Claude drew three replacements and I picked one.

Inconsolata as it appears on Beach Face, at 22 pixels and weight 850 in pure black and white: the alphabet in capitals and lowercase, the digits, and the punctuation the phrases can use, each letter in an evenly spaced slot

The small type is the tiny pixel font I made for my LED Matrix Simulator, at double size. It had no degree sign, so I drew one.

The tiny pixel font at double size: capital letters, digits, the added degree sign and the punctuation, each built from a handful of square pixels

The face

The face and phrase are there to make the UI glanceable. They answer the question “Is it OK to go for a swim?” instantly. The rest is the evidence.

It’s simple on purpose. Scott McCloud makes the case in his wicked book Understanding Comics: the simpler a cartoon face, the more of us can see ourselves in it.

Two panels from Understanding Comics. Scott McCloud’s cartoon self talks about how cartoons focus attention, then a row of faces runs from a photograph labelled ONE, through increasingly simple drawings labelled A FEW, THOUSANDS and MILLIONS, to a plain circle with two dots and a line labelled (NEARLY) ALL

From Understanding Comics by Scott McCloud, 1993.

I’ve always loved GERTY, the robot in Duncan Jones’s film Moon, for the same reason. It’s a battered, brutalist box with one camera eye, and all its feeling comes from a yellow smiley on a small screen.

GERTY from the film Moon: a scuffed grey industrial robot with a single round camera lens, a LUNAR logo, handwritten notes taped to its side and a mug on a ledge, and a small screen showing a simple yellow smiley face

GERTY in Moon, directed by Duncan Jones, 2009.

Three Beach Face screens side by side. Happy: GET IN THE SEA, sea 19.2 degrees, waves 0.4m, tide out, sunny. Flat: PADDLE ONLY, waves 1.6m, tide coming in, cloudy. Sad: KETTLE ON INSTEAD, high tide, the moon out at five past nine at night

Happy means get in. Flat means think about it: rough water, poor water quality, an outfall that spilled recently, or no sewage data at all. Sad means stay out, because an outfall nearby is spilling right now. Or, for the moment, because it’s dark.

Character

E-paper isn’t great for animating, but it can redraw parts of the screen, slowly. So the face has a few small moves that only show if you watch it for a while. A glance won’t catch them. It’s an old technique in animation, the illusion of life. A blink is enough to make something look like it’s paying attention, and the same instinct makes it easy to believe there’s someone home in a connected product with embedded AI.

The Beach Face smiley, slowly cycling through its moves at e-paper speed: glancing left and right, looking up and down, a long blink, a wink with a wider grin, and poking its tongue out with its eyes shut

A sprite sheet of every frame: five labelled rows for looking around, up and down, blinking, winking and poking its tongue out

Tone of voice

The first version said GOOD TO SWIM. I changed it to GET YOUR COSSIE ON, because that’s what a person would say. Now the phrases come from gpt-oss, one of Pan’s models. It gets a plain English description of the conditions and the face, and a brief. Something a friendly local would shout from the prom. Two to four everyday words. British, warm, dry, a bit cheeky. No numbers. On a sad day, say stay out kindly.

A list of fifty phrases would do the job. I wanted to see what happens when large language models write the micro-copy instead, and whether a bit of unpredictability makes the face feel more alive.

It only gets asked when something changes that you’d notice. The face, the tide turning, the sky, the sea warming by a couple of degrees. So it runs a few times a day, and the screen cycles through the latest batch.

The first phrases were word salad. PLAY SAIL. GLAD WAVE. I’d asked it to fit each line into ten characters, and a model counting letters while trying to be witty managed neither. It writes an ordinary phrase instead, “Go for a dip”, and the relay splits it into two lines itself. Anything that won’t fit gets dropped. It asks for 16 and keeps up to 8 that fit. If the Mac mini can’t be reached, there’s a built-in set for each face. The logs said it once attempted “Last one in’s a crab”. I love that, but constraints are constraints.

The top half of Beach Face cycling through GET YOUR COSSIE ON, GET IN THE SEA, GO FOR A DIP and WATER’S LOVELY beside the smiley face

So far, I like it. The slight unpredictability is the chewiest. With two to four words to play with, every guardrail needs fine-tuning, and each one dulls the character a bit. Where it’s landed is good enough to live with, so I’m going to leave it alone and see how it gets on. Letting a design run and watching what it does is a new way of working for me. Turning it into a product would take a lot more finessing.

Next

I’d like to try it on a larger display. My partner has asked me if I can make a version for the shop, so I’ve ordered a red and black one to experiment with. I quite fancy putting it in a picture frame too.

The face rules need work. They’re borrowed from the web experiment, which treats darkness as a reason to stay out, so Beach Face is sad every night. Swimming in the dark is a bad idea, but a sad face at nine on a July evening feels harsh. Proper rules might look at the water temperature, the wind, the waves and how long ago anything spilled. That’s harder than it sounds, and I’d like to try something like Ollaya to help weigh it all up.

The prompt needs tidying too. gpt-oss sometimes copies the examples word for word, and once wrote TIDE’S / COMING IN at high tide.

I'd love to tell you more. Let's work together.

// Tick - A New Home for Pan

This is a follow-up to Introducing Pan, which covers how Pan works and their first home on my desk. The whole point of owning my own AI infrastructure, end to end, is that I can play with it. Try out new ideas as I have them, with nobody else’s roadmap or agenda in the way. Pan has moved into an alarm clock. It’s a long, thin strip of a screen that shows the time, wakes me up, sets timers, tells me the time in Tokyo and answers questions about my notes.