Cartografía Celeste

Prototyping and Fabrication Techniques Sound and Music Computing, Aalborg University Autumn 2020

Starting point

When facing this project, I set a series of constraints:


By chance, I found a video by The Warthog Project, a channel dedicated to building a A-10C Warthog simulator. In this video, the author explains how to build the fuel panel from scratch.

The idea of a black acrylic backlighted panel seemed really interesting for me to explore.

The Warthog Project - Making Flight Sim Panels

First sketches

The first iterations revolved around the idea of random panels: placing different controls and labels on the panel. The random panel placed nonsensical controllers to create something resembling a formal controller. Upon closer inspection, the user realizes that the panel does not make any sense, but leaves some leeway to imagine what strange contraption could be controlled by this weird panel.

Random panel
Random audio synth

Another possibility would be for each panel to be a unique analog synthesizer: the tool generates the panel, the bill of materials, the schematics...

These panels present certain issues:

The nonsense panel doesn't "do" anything, the controls don't work, they are mere decorations, in fact, operating the controls won't produce any output, because there is no output as such.

The analog synthesizer could produce an output, but in return, the electronics are much more complicated. If we want the synth to be a little interesting, we must provide a minimum of controls, which complicates the programming, wiring and therefore the time required to build a copy.

Cartografía Celeste

Thinking about the black slab, a minimal interface, and the use of LEDs, I thought about constellations, stars and the blackness of space, and that sparked the idea of creating a "constellation generator" to map the universe with brand new constellations. Cartografía celeste (Celestial cartography) was born.

By using only LEDs (plus a microcontroller and a battery) the project would be simple, allowing me to build more than one copy, but at the same time producing an object interesting enough to display it at home.

First sketches

Cartografía Celeste covers all the bases stated in the starting point:

Open source

The main files are:

Development and learnings

The project is divided into four main blocks:

Generator A tool to generate the different constellations (star placement, connecting lines, information about the constellation) and save the files needed to build the object.

Physical object The materials must be laser-cuttable and have a finished professional look. The object must feel solid and elegant. Final size should be carefully chosen, so the information is not crammed, but also not to make the object disproportionately big.

Firmware The code should be small enough to fit in a microcontroller, as well as interesting enough so the users feel compelled to turn the system on.

Hardware The combination of microcontrollers, actuators, power source, etc. keeping in mind that there is not going to be a lot of room for the electronics, and the components should be on a budget.

During the development, a series of design choices have been made, motivated by:

The development has been an iterative process. As progress has been made in each of the four main blocks, the results obtained have influenced the rest of the blocks.


To operate the laser cutter, one of the recommended formats is SVG (Scalable Vector Graphics). I decided to use Processing to develop the tool, as it allows to generate SVG files almost effortlessly.

The tool generates an infinite series of constellations, placing twelve stars at random, joining them and generating additional information. The process is automatic: pressing the space bar generates and records a new constellation, including the additional parts needed for assembly. The SVG file includes the necessary line thicknesses for the cutter to cut the pieces or raster the lines and texts. The only manual task is to rescale the design by 65.415% from the program where the cutter will be used, since the generated SVG file does not include any units of measurement.

Generated SVG

In detail

Parametric design One of the decisions I made at the beginning was to parameterize all the measurements (margins, padding, LEDs size...). During the development process, I had to adjust them very often and by using parameters I avoided a lot of hassle.

translate(63, 0);
translate(traceW*2+panelMargin*2, 0);

Soldering aids To facilitate the process of soldering the LEDs, each copper tape is labelled (the columns marked A-D). Also, every LED is also labelled, showing to which pair of columns the LED is to be soldered to and in which position. For example, -CD+ means that at that position a LED is soldered to columns C (cathode) and D (anode)

LED layout

The LEDs are placed randomly in the available space, following a series of rules that will facilitate soldering them to the copper tape:

Generation of the constellation To generate the lines that form the constellation I was trying to reinvent the wheel (joining some stars, joining all of them and refining, removing some lines) until I realized that I could use existing algorithms. The constellation is created by following these steps:

  1. Calculate the Delaunay triangulation to obtain a mesh of triangles avoiding acute angles and segment crossing. This step returns a list of segments between stars.
  1. Calculate the convex hull, i.e. the list of segments that encompass all the stars. This step returns another list of segments.
  1. Remove the segments from the hull from the triangulation segment list.
  1. Break up the remaining triangles, removing one of the segments at random.
  1. If a star is connected to more than three stars, remove the extra connections.
  1. Assign a random radius to each star.
Constellation generation process: Delaunay triangulation, elimination of the hull, triangle break up, deletion of connections

After this process, we can be left with some disconnected stars, but this is usual in the depictions of the constellations.

Texts The name of the constellation is chosen at random from a list of Latin nouns. The surname of the discoverer of the constellation is chosen at random from a list of Flemish, French and English surnames. The year of cataloguing is assigned between 1600 and 1825. The rest of the astronomical data is generated at random, but by choosing plausible values. The number of stars in the constellation is the number of connected stars.

Extra parts The SVG design includes the additional spacer ring parts that we will need for assembly.

Possible improvements


The hardware consists of an ATtiny25 microcontroller, twelve 3mm diameter white LEDs and a 3v CR2032 battery. The LEDs are soldered between the four copper tapes, each of them attached to the corresponding output of the microcontroller.

Circuit schematics
Connecting the LEDs
Board with the ATtiny
LED and board assembly

In detail

ATtiny25 The ATtiny25 microcontroller is used as an alternative to the Arduino (ATmega328) microcontroller. The ATtiny25 has six I/O lines, operates between 2.7-6 volts and can be programmed from the Arduino IDE, so no additional toolchain is needed. If the amount of program memory (2kb) and SRAM (128b) weren't enough, it can be replaced by the ATtiny45, a pin-by-pin replacement, with twice the amount of program memory and SRAM.

Charlieplexing Charlieplexing is a technique used to control several LEDs using a minimum amount of output pins. Using this technique, the LEDs are turned on for a brief period of time, and the persistence of vision makes us believe that they are always on.

By using charlieplexing, with nn outputs one can control n(n1)n(n-1) LEDs, so using 4 output pins we get to control 12 LEDs.

The first tests were made on an Arduino compatible board and the ported to the ATtiny25. A very naive version of the charlieplexing code is available at the GitHub repository, using 35% of the available program memory and a 86% of RAM memory.

Charlieplexing on an ATtiny25. The Arduino is used only to power the microcontroller.

Power source The system is powered by a standard CR2032 battery. A fresh battery lasts for 22 hours. To keep the battery in place, I'm using a bent header pin. It is a provisional solution, but good enough as it supports the battery weight, and the object can be moved around without the battery getting loose.

Bent pins used to hold the battery.

Possible improvements


The code is a combination of charlieplexing and PWM to achieve regulation of the intensity of the LEDs and create the flicker effect.

In detail

Burning the code In order to burn the code in the ATtiny25, and considering building more than one object, I built a small programming shield, instead of just using a protoboard and needing to check and recheck the wiring every time.

The programming shield is based on the tutorials by Viktor S at and NotoriousRapper2Chainz at instructables, with an extra LED in the pin 9 of the Arduino, used as feedback and a second LED connected to the ATtiny pin 4 to check that the ATtiny is working as expected by running a test sketch.

Fritzing protoboard schematics
ATtiny programming shield
ATtiny programming shield on the Arduino board

In order to program the ATtiny25, four steps are required:

  1. Install the package extension for ATtiny microcontrollers: Arduino > Preferences > Additional Boards Manager URLs and paste . This step is needed only once.
  1. Transfer the ArduinoISP code to the Arduino board. ArduinoISP is included in the standard Arduino IDE release in File > Examples > 11.ArduinoISP. This step is needed only once.
  1. Choose the chip Tools > Board > DIY ATtiny > ATtiny 25 and burn the bootloader Tools > Burn bootloader. This step is needed once per chip we want to program. To burn the bootloader, make sure Tools > Use Bootloader is set to yes.
  1. Upload the ATtiny code to the microcontroller. To upload the code, make sure Tools > Use Bootloader is set to no. The sketch arduino/attiny_test available at the GitHub repository can be used to check that everything is working as expected.

The code The code is based on the article Twelve PWM Outputs from an ATtiny85 by David Johnson-Davies and includes the function to generate pseudo-random numbers developed by Rob Tillaart and published in the Arduino forum.

Johnson-Davies' code interprets an array of 12 integers as the intensity of each LED, using those values to adjust the duty cycle of the PWM while charlieplexing. In my case, I update the array every 10 milliseconds to achieve the flicker effect. In the current version, the LEDs are always lit at 12.5%. There is a 1 in 128 chance that a LED will light at 25% and a 1 in 1024 chance that it will light at maximum level. These values produce slight lighting intensity variation but do not distract or blind the user.

The final version uses 910 bytes (44%) of program storage space and 29 bytes (22%) of dynamic memory.

Initially, I had tried randomly changing the light intensity, but the effect was similar to a faulty power connection. A second version turned the panel into "Christmas lights" and it was also discarded.

Possible improvements

Physical object

The resulting object measures approximately 142x87x14mm and consists of three layers of glossy black acrylic 4mm thick and one layer of mate black / white laminate 1.6mm thick.

Render of the different layers

In detail

Laser cutter configuration An Epilog Fusion M2 60w laser cutter was used for cutting, with the following configuration:

Raster laminate / acrylic Speed: 90% Power: 60% Freq: -

Cut laminate Speed: 10% Power: 100% Freq: 100

Cut acrylic Speed: 6% Power: 100% Freq: 100

Layer 1: Front Panel The front panel is made of laminate, so when you rasterize the texts and lines, the black layer disappears, leaving the white layer visible. This panel has to be made in two independent passes. In the first one, the texts and lines are rasterized. Then, the piece is covered with painter tape and the holes for the stars and the panel are cut. If the cut is made without covering the part, the laser leaves too many markings. However, if the part is protected from the beginning, the text appears blurry.

Wrong: Rasterizing with tape
Wrong: Cutting without tape
Good: Rasterizing without tape, cutting with tape.

Layer 2: electronic components This layer and the following ones can be cut in the same operation. This layer includes an additional cut to embed 1) the perfboard and 2) some metal strips to keep the cover in place with magnets.

Layer 3: spacer ring The spacer ring is used to make room for the electronics, both the soldering of the LEDs and the chip and battery. To make better use of the material, the spacer ring is cut into pieces, although this makes the assembly slightly more difficult.

Layer 4: back cover The cover hides the electronics. It has two magnets glued to hold the cover in place. The back cover does not have an SVG template as such, I reuse the main template by erasing the contents of the front panel and leaving only the cutting shape.

Assembly The assembly starts by gluing the copper tape, soldering the electronic components and soldering the perfboard. The next step is to glue the spacer ring. With the ring in place, we can glue the metal strips and the magnet. To diffuse the light and hide the LEDs, we glue a piece of tracing paper on the front to the layer 2 + 3. Finally, we glue the magnets.

Material for four constellations: exploded spacer ring, electronic components, front panel (protected with tape) and back cover.
Layer 2 with the piece of paper attached.

Possible improvements


Thanks to David Navarro for the supervision of the astronomical data.
Thanks to Peter Williams for the trouble I have given him with the materials.
Thanks to Dan Overholt for the idea for the battery holder.