Interstellar display (Seeeduino-based)

I made an Interstellar figurine that displays messages, as a parting gift for a dear colleague that worked on this movie asset. This post contains some of my design process and everything to make your own.

Hardware

I ended up going through very similar design stages as described in my Wooden Arcade post.

1) Requirements

I set out to build the figurine with these goals in mind:

  • Decently looking
  • Compact enough to be a desk figurine
  • Poseable legs
  • Efficient manufacturing
  • Storage for at least 100 messages

2) Sketch

Since this design is based directly on a film prop I gathered reference first:

To dial in the proportions I made a crude 3D model, which was quick to adjust.

From now on I will refer to “body” and “legs”, as highlighted in the picture.

3) Draft

Since the design was given, I only had to worry about fitting all “limiting components” inside.

The most limiting off-the-shelf piece was the display. One of the most commonly available options for a small display is this 0.96″ OLED display with 128×64 pixels. Combining the two middle parts of the robot into the “body” would allow me to use one such display. Limited display colors and resolution were no concern, since I aimed for a command line feeling anyways.

The display defined the width of the body and therefore locked in the overall scale of the robot. That meant that I knew how much space I had to fit the remaining parts.

The next concern was to find a suitable microcontroller. My go-to option for small projects is usually the Arduino Nano, but it had a few downsides:

  • Fitting it into the body would be tricky due to the Arduino’s size.
  • On-board storage of the Nano is small, which might have limited the amount of messages I could load onto it.

So I pursued one of my favorite pastimes: Looking for electronic components.

I found a microcontroller that deserves more attention: The Seeeduino XIAO. Its upsides for this project:

  • Small
  • Decent on-board storage
  • Bonus: USB-C

With these components in mind I created a first Fusion360 sketch and made sure to keep things parametric, so I could change dimensions easily, if necessary.

4) Prototype

There were some unknowns I wanted to figure out as soon as possible to avoid insurmountable roadblocks down the line. This meant lots of tweaks and design iterations:

The magic L

When I tried to fit everything into the first housing prototype I caught myself in one of those “I will figure it out later” moments. Unfortunately it was now “later“: How the heck do I power this thing?!

I did not want to use batteries, so I had to find a way to connect a cable to the microcontroller. I could have soldered a cable directly onto the Seeeduino, but I prefer designs that can be disassembled. Connecting a cable on the inside would have taken too much space and unfortunately not even the tiny Seeeduino fit into the body with its USB-C plug pointing backwards.

So I had to keep the Seeeduino parallel to the body and somehow get its plug out the back. As if it would take a 90° turn… Like an L-shape……………. Oh!!!

It took me surprisingly long to think about L-shaped connectors. Here is why this was such an awesome find:

  • This connector was easy to model in Fusion 360, to build a 3D printed holder for it.
  • The solid casing of this connector absorbs all mechanical stress that might have otherwise damaged the Seeeduino.
  • The final design uses this connector to lock the Seeeduino into place without any glue, while still being rock solid.

Simple components

The entire design requires no 3D printed supports whatsoever.

To avoid having to paint the small font and braille, I simply printed them as holes and allowed for a small inlay behind it. A colored piece of plastic (or even a thin piece of brass) glued on from the inside made it super easy to get a clean paint job.

The display is held in place by 3D printed stubs and a simple rubber band. Therefore it’s easy to disassemble without additional costs.

The OLED display module is not the prettiest, which I managed to hide with a small piece of lighting gel filter.

Magnets!

I thought it would be cool to make the legs poseable. At first I printed the body and legs with a hole and axle. But I had concerns about the fit: If it was too tight the legs might snap off, if it was too loose the figurine would not stand upright. So – as always – I tried to solve my problems with magnets.

This ended up working really well: The figurine can be taken apart and posed freely. The magnets are subtle and the figurine holds its pose well. For extra style points I added magnets (diametrically magnetized) to one end of the legs, which makes the robot extra stable on metal surfaces.

I did not take pictures of the assembly of the legs, but all it takes is some instant glue to attach the hinge magnets, optionally add the diametrically magnetized magnet into the cavity on one end and then snap the leg pieces together. I added a bit of glue to prevent the 3D printed leg parts from ever coming apart.

A “raw” model straight off the 3D printer. Use spraypaint or so, for extra stylepoints 😛

Software

Write-on effect

Driving the display with the Seeeduino worked well, but I was not happy with the default write-on effects of the Adafruit_SSD1306 library:

Displaying messages statically or scrolling them does not portray any personality. Unacceptable for this character. Therefore I wrote my own version of a simple write-on animation, which allowed for a few neat features:

Any message could have an “author”, which is displayed at the top right. This was a nice touch for all the leaving messages from the team.

The blinking cursor and randomized delay between characters gives it more life. And as the screen fills up the text scrolls up. I did not include proper line breaks – partially due to laziness, partially because the display is so small that there was not much use for it.

I added a “joke indicator” at the top left, which the robots in the movie use. This allowed for an extra layer when people wrote their messages.

randomSeed(random)

As I was testing the software I noticed that the quotes were in a random order, as intended. But every time the program started that random sequence was the same. Since the figurine would probably be plugged into a computer it would be quite boring if the sequence would be the same every time the computer was booted up. Imagine drinking your morning coffee to the same sequence of messages – where is the spice of life in that?! Unacceptable!

The problem lies with “random()”. It is only a pseudo-random function that is based on a seed. The same seed always yields the same sequence of random values.

randomSeed(123);
int randomNumber = random(0, 100);

I do not know what I expected when I tried:

randomSeed(random(0, 100));
int randomNumber = random(0, 100);

Even though this looked genius to me at first, it is utter nonsense. During the Seeeduino boot up process “randomSeed” is initialized with a default value and therefore the first call of “random” will always return the same value. Not random at all!

I did not want to add extra components just for this, but how else can true randomness be added to a system that is designed to be deterministic..? This had me stomped for a while. Until it hit me; the best source of randomness is the messy & chaotic real world. And the best way of “accessing” this from the Seeeduino was by reading a volatile analog pin:

An analog pin of a microcontroller can set or read a range of values, opposed to a 0 or 1 for digital pins. The voltage of any unconnected pin is influenced by all kinds of surrounding factors and therefore highly volatile. So all I had to do was to read the state of such an unused pin (fortunately the Seeeduino has such analog pins, with a resolution of up to 4096 values). This read pin value could then be used for the “randomSeed”, which meant that subsequent starts of the system would be very unlikely to have the same sequence of quotes.

This is the exact technique that is suggested by Arduino. Fortunately I did not see this until I wrote this post, because figuring it out by myself was a personal highlight of the project.

Data ingestion

I used a google sheet to collect messages in an easy way. Feel free to do the same by copying and editing this template: docs.google.com/spreadsheets/d/1Ykk0tgYsliaIzMqltVZ3Ye2wybARJx4l-eyqKgYxkgA

Once you are done, you can download the sheet as a CSV file and use the quote_ingestion.py Python script in the github repo to convert the CSV data to the quotes.h file my Arduino project expects.

Resources

Code

github.com/mischakolbe/interstellar_display

Parts

I unfortunately can not share the Fusion 360 project itself, only the model preview (I do not own a paid license for Fusion 360). But you can download the STL files from my google drive to 3D print them. There are two body models: body_front_tars & body_front_case. Chose your favorite 😉

This should be the full list of items you’ll need (none of these are affiliated or sponsored links).

Wiring guide

How I soldered the Seeeduino and OLED display together. Make sure this is correct for your parts, too!

Conclusion

There are minor issues:

  • The legs warp slightly when 3D printed, but once they are assembled the warp is almost entirely gone.
  • The code is not particularly efficient and adding linebreaks would be neat.
  • The figurine is not perfectly stable. Some more iterations on the legs would help.

But overall I am really happy with the result – and it was a fun goodbye present 🙂


One thought on “Interstellar display (Seeeduino-based)

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s