Lightmap Monaco - Turn A Country Into Light

About the project

LightMap Monaco, a 179-cuboid PMMA light sculpture mapping the city in real time. Custom protocol, dual Meanwell PSUs, Pi 5 plus dual RP2040 control stack, ~800 addressable LEDs. Control panel coded for both computer and mobile device to control the map in real time. React to touch, weather, data. Event booked before it shipped.

Project info

Difficulty: Difficult

Platforms: Adafruit,  NeoPixel,  Raspberry Pi

Estimated time: 2 months

License: GNU General Public License, version 3 or later (GPL3+)

Items used in this project

Hardware components

Awg20/22 Awg20/22 x 1
Meanwell 12V Meanwell 12V x 2
Individually addressable RGBW LEDs /m Individually addressable RGBW LEDs /m x 10
PMMA bars (acrylic) (1m) PMMA bars (acrylic) (1m) x 21
2020 Aluminum Extrusion 2020 Aluminum Extrusion x 10
T-plate For 2020 Aluminum Extrusion T-plate For 2020 Aluminum Extrusion x 4
L-plate For 2020 Aluminum Extrusion L-plate For 2020 Aluminum Extrusion x 8
Laser Cut DMX file outline (Stainless Steel) Laser Cut DMX file outline (Stainless Steel) x 1

View all

Software apps and online services

Visual Studio Code (for Pi5 code) Visual Studio Code (for Pi5 code)
PIO (for adafruit code and compile) PIO (for adafruit code and compile)

Hand tools and fabrication machines

mitre saw mitre saw x 1
orbital sander orbital sander x 1
angle grinder angle grinder x 1
soldering iron set soldering iron set x 1
crimping tool crimping tool x 1

Story


LightMap Monaco: a 179-cuboid light sculpture that maps a country in real time


Monaco runs on events. Grand Prix, yacht shows, galas, the works. The way the Principality still promotes most of that is paper maps and pamphlets, and the printing press was invented 600 years ago. So I built the country instead.

LightMap is a physical 3D map of Monaco, 179 hand-cut PMMA cuboids arranged over the country's real footprint, each one lit individually and driven live off real event data. When something happens in a neighborhood, that neighborhood glows. Grand Prix weekend, the circuit lights up red. Yacht show, the harbor goes blue. It's meant to make an entire national events calendar readable at a glance, and to look good doing it.




Why I built it

I'd just come back from working across Europe and remote in Dubai, and after seeing what creative technology studios elsewhere were doing, Monaco's own showcase of that kind of work felt thin. Being a national here is actually an advantage for getting attention on something like this, so the goal was twofold: build something genuinely interesting as a technical showcase for the Principality, and use it to open doors, both for future commission work here and for jobs elsewhere in Europe. The media coverage angle hasn't fully paid off yet, but the sculpture already sold before it shipped and has been running at the Invest Monaco Forum, so the commission side is working.

Getting the data

Before any wood or acrylic touched the design, I needed two things: Monaco's exact outline, and enough elevation and building-height data to turn that outline into 179 cuboid heights.

The outline came from OpenStreetMap. Free, precise, no bureaucracy, credited under ODbL.

The height data was the harder problem. Copernicus has the elevation data Europe runs on, but direct access needs an institutional authority behind the request, not something a one-person studio gets waved through on. Instead I pulled it through a third-party weather API that exposes Copernicus-derived elevation at around 90m resolution, which was enough precision for a country the size of Monaco. I wrote a script to grid the whole territory into 100m x 100m cells, pull the average elevation per cell from that API, then cross-reference against OSM's building data to recover actual building heights where they existed, since raw terrain elevation alone doesn't capture a 30-story tower sitting on a hillside.

Both datasets get reprojected in QGIS, from lat/lng into meters, gridded, corrected for Monaco's rotation relative to true north/east, then reprojected back into a CSV of lat/lng centroids with a height value attached to each one. That CSV is what maps 1:1 onto the 179 physical cuboids, each one's height in the sculpture is a direct read of that cell's real-world elevation and building profile.

How it's built

Structure: 2020 aluminum extrusion frame carries everything, Meanwell PSUs, fuseboxes, the Pi and Feather boards, all mounted directly to it. The frame's shell is 10mm birch ply on the sides, heavily stained, with a 12mm marine birch ply top, laser cut and fitted with aluminum corners.





The cuboids themselves are cut from 12 bars of 1m PMMA, mitre-sawed to length, then hand-sanded to fit through a laser-cut stainless steel top plate, one at a time, 179 times.
Underneath, a steel mesh plate supports the LED runs, roughly 10m total, hand-cut and hand-soldered.

On the electronics side: originally built around Olimex boards, which turned out to be a nightmare of flashing failures and random crashes. Ripped that out and rebuilt the whole control layer on Adafruit Feather RP2040 Scorpio boards, which have been solid since. A Raspberry Pi 5 acts as the master, calculating LED coordinates from live event and idle-mode data and pushing them to the Scorpio boards over a custom COBS serial protocol, which then drive the individually addressable RGBW strips.

Software

The control stack is a Raspberry Pi 5 running Python, talking to the two Feather Scorpio boards over a custom binary serial protocol: a start byte, length, payload, checksum. Each Scorpio is a dumb pixel pusher, it just parses the frame and writes to Adafruit's NeoPXL8 library across 8 concurrent PIO+DMA channels, RGBW.

On the Pi side, a ModeManager owns the render loop and the clock. Every mode (Ambient, Data, Event, Touch) is a stateful object that paints one frame when asked, nothing sleeps or loops on its own. Switching modes never hard-cuts, everything crossfades, including the boot sequence, which doubles as a smoke test since the wash sweeps across every single pixel before the sculpture goes live.

A Flask operator panel on the LAN controls all of it from a phone: mode switching, brightness, white balance, a tap-to-ripple map for spawning live pulses at any point in Monaco. Events (Grand Prix, yacht show, whatever's happening) either radiate outward from a point or sweep along a path, same underlying pulse system either way.


Worth mentioning for other makers: the whole thing originally ran on Olimex boards and was borderline unusable, random flashing failures and crashes that ate a lot of the two-week delay. Swapping to Adafruit Scorpio boards fixed it outright, that's the one component swap I'd flag if anyone's building something similar.




The result is a sculpture that's a display piece when idle and a live readout of what's happening in the country the rest of the time, controllable down to the individual LED.

Code

Lightmap Clean code

Credits

Leave your feedback...