CC Blog Projects Research & Design Hub

The Lego Hat

FIGURE 1 There is a lot happening around the finished hat: lots of colorful bricks, lots of Lego mini-figures, and lots of spinning gears. On the back of the hat, there are three 8x8 bicolor LED grids.
Written by Chris Cantrell

Built with a Raspberry Pi Zero and Lots of Glue

Each year I build a new Lego hat for the FIRST Lego League robotics event, and this year I went all out. In this article, I’ll show you how I built my hat from foam, Legos, and lots of glue, and how I wired up the motors, LED displays, and Raspberry Pi Zero.

  • What’s a fun project with a Raspberry Pi Zero?
    How can I use a microcontroller in a Lego project?
    What’s a fun project using LEDs?
  • Raspberry Pi Zero

AFIRST Lego League robotics event is an energetic, emotional roller coaster. You’ll see kids and adults jump and cheer when their robot successfully moves the three Lego satellites into the orbit area on the table. You’ll see the same kids and adults in tears after a bad run in which the robot’s arm accidentally knocked over the Lego chicken statue. Search “FIRST Lego League” on YouTube to see past competitions.

Adults at FIRST robotics competitions always tell me, “I wish we would have had this when we were young.” But it’s never too late to be a kid! If you want to play with Lego robots, then buy yourself a set from Amazon. The software is free, and tutorials abound. And if you want to coach or mentor Lego robotics, there’s a team in your area that needs your service—even if you don’t have kids in the program. My kids are all grown and gone, but I volunteer as a project judge every year.

Creative hats, costumes, glasses, and pins are encouraged at FIRST events. Even the judges and the referees get in on the fun. I try to build a new hat for every season. This year I went all-out and built a Lego hat with spinning gears, flashing lights, and lots of miniature figures. You can see the finished hat in Figure 1, and you can see a video of the hat in action via a link on Circuit Cellar’s Article Materials and Resources webpage [1].

There is a lot happening around the finished hat: lots of colorful bricks, lots of Lego mini-figures, and lots of spinning gears. On the back of the hat, there are three 8x8 bicolor LED grids.
There is a lot happening around the finished hat: lots of colorful bricks, lots of Lego mini-figures, and lots of spinning gears. On the back of the hat, there are three 8×8 bicolor LED grids.

In this article, I’ll show you how I built my Lego hat from foam, Legos, and lots of glue. I’ll show you how I wired up the Lego motors, LED displays, and Raspberry Pi Zero. Finally, I’ll show you the simple Python code that brings the hat to life.


The hat’s internal frame is made from 3/8” foam. I was tempted to use my wife’s yoga mat, but I avoided the bruises and ordered a camping pad from Amazon instead [2]. The pad came rolled up, so I stretched it out on the floor and placed books on it for a few days to flatten it.

Chris Huebert at Lost Wax sells an awesome, printable hat pattern [3]. I printed the pattern, traced it onto the foam pad, and cut the pieces to match my head size. His website also has a great tutorial for making the hat from his pattern [4]. You can see my hat coming together at the top of Figure 2.

The hat is made from blue foam covered with thin Lego bricks. Three Lego motors are mounted to the inside foam wall. The battery and electronics are packed into the top of the hat.
The hat is made from blue foam covered with thin Lego bricks. Three Lego motors are mounted to the inside foam wall. The battery and electronics are packed into the top of the hat.

The next step was to cover the foam with Lego plates. I used a single large green plate for the top of the hat. I carefully shaped the plate with a Dremel tool and glued it into place with Krazy Glue (Lord Business’s dreaded “Kragle” from the Lego Movie).

The bottom of the hat’s brim is a single gray plate. I used a heat gun to warp it into the hat’s curved shape, and I glued it into place. Then I used the Dremel tool to cut the hole for my head and to trim the edges of the plate. You can see the gray plate at the bottom of Figure 2.

I used individual Lego bricks for the body and brim of the hat. I have a 20-gallon tub of Legos saved from when my kids were young, but the bricks are mostly the blacks and whites of Lego Star Wars sets. I wanted lots of colorful bricks for the hat.

I needed to buy them from the Lego “Pick a Brick” Store—but how many would I need? Here is an engaging, real-world math problem we need in our grade school textbooks: “Sara is building a Lego hat with the dimensions shown. How many 2×4 bricks will she need to cover her hat?”

My hat is roughly elliptical with major/minor axes of 12cm and 9.5cm. The hat is 15cm tall. The brim extends 5cm from the body. I used an online calculator for the area and circumference of an ellipse. The surface area of the body cylinder is the circumference of the ellipse times the height: 68cm x 15cm = 1020cm2. The area of the brim is the area of the larger “+5cm” ellipse minus the inner ellipse: 99cm2 – 68cm2 = 31cm2. Thus, the total area to cover is 1020cm2 + 31cm2 = 1051cm2.

We talk about Lego brick width and height in terms of “bumps.” A Lego bump is 0.8cm by 0.8cm. Thus, a 2×4 brick (8 bumps) is 1.6cm x 3.2cm. Converting to bumps, we have the answer to our math problem: “Sara needs 1051cm2 / (0.8cm x 0.8cm) = 1642 bumps worth of Legos for her hat. That’s 206 of the 2×4 bricks.”

I ended up buying 1500 bumps worth of plates in assorted colors and sizes: 1×2, 2×2, 1×4, and lots of 2×4. I spent a solid week Krazy gluing the bricks to the hat’s foam. I used the Dremel tool to shape bricks to fit in the nooks and crannies, but Lego tape was easier to cut and shape for the smaller areas. The covering isn’t perfect; you can see lots of gaps and flaws in Figure 1.


I bought three Lego Power Function motors from eBay. You can buy them from Amazon [5], but they are more expensive. The same goes for gears, beams, and axles. I have listed the Amazon links for these parts [6][7], but check your own collection of Legos first.

The front of a Lego motor has four holes for support studs surrounding the central output shaft. Imagine a “five” on a game die with the axel as the middle pip. I glued short Lego Technic beams to the outside of the hat and drilled the five-hole pattern through the plastic and foam to the inside of the hat. The holes in the beam guide the drill precisely. I used a matching set of Technic beams on the inside of the hat with long shafts connecting the inside beams to the outside beams. The motor attaches to the inside beams, and glue holds everything together tightly.

I could have used a real Lego Spike controller to run the motors, but I also wanted to drive a flashy LED display. Instead, I used a Raspberry Pi Zero [8] (no Wi-Fi needed) with an Adafruit motor driver bonnet for the motors [9]. Any microcontroller with an I2C driver would do the trick.

I used three Adafruit I2C 8×8 bicolor LED displays on the hat [10]. The individual elements of the display are square and blocky and look natural alongside Lego bricks on the hat. I drilled tiny holes in the hat for the three sets of four wires for each display.

You can see the wiring schematic in Figure 3. I used a 9.6V rechargeable battery pack with a 5V “Buck” DC-DC converter to power the Pi and motors [11]. Lego motors have a 4-wire ribbon cable. The inner two wires drive the motor; the outer two wires are not used. I cut the brick connector from the end of the cable, stripped the two inner wires, and attached them to the motor bonnet’s screw terminals.

The wiring schematic for the project. I used a 9.6V rechargeable battery pack with a 5V buck DC-DC converter to power the Pi and motors.
The wiring schematic for the project. I used a 9.6V rechargeable battery pack with a 5V buck DC-DC converter to power the Pi and motors.

I added a pushbutton to the bottom of the hat to cycle through various modes: “sleep,” “high-activity,” “low-activity,” and “display-only.” The button connects between ground and a Pi GPIO pin, which is configured with an internal pull-up resistor [12].


My favorite part of the hat is the spinning gear trains wrapped around the hat’s body. The gears must be precisely aligned so their teeth can mesh. That can be tricky on a curved surface. I used a short, three-hole technic beam to mount each gear. One end of the beam holds the gear’s axle. The other end of the beam attaches to the hat with a one-peg block. I mounted the one-peg block on the hat and pivoted the arm to align the teeth with its neighboring gear. Then I repeated the process with several gears to make a chain like you see in the upper right of Figure 4. The gear closest to the top of the hat in that chain is mounted on the motor’s shaft.

On the top of the hat, two teams face off at the game table. Below on the brim, two developers debug a code printout. Three LED grids wrap around the back of the hat.
On the top of the hat, two teams face off at the game table. Below on the brim, two developers debug a code printout. Three LED grids wrap around the back of the hat.

There are several busy scenes scattered around the hat; the Lego Hat is a crowded place. I bought a bag of mini-figures from eBay. I found several doors, windows, and other interesting bricks in my collection. Others, like the ship’s steering wheel on the front, I bought from the web.

In the upper left of Figure 4, you see a robot competition in progress on the top of the hat. Two teams, the “Bot Hats” and the “Gear Girls,” watch their robots move game pieces on the table. The mat on the table is an actual photo-reduced mat from the 2018 “Into Orbit” game. I used a Sharpie to draw the lines on the referee’s shirt. His clipboard has a real photo-reduced score sheet from the 2018 game.

There is a spinning radar dish on top of the hat next to the game table. Maybe it’s streaming the game to the Internet. Maybe it’s scanning for transmissions from alien civilizations. Honestly, it’s there because it looks cool. And it’s geared down to spin slowly.

You see the three LED displays in the bottom right of Figure 4. I glued Lego beams to the top and bottom of the displays. Each display attaches to the hat with a single pivot point, which allows me to angle them precisely. The wiring on the back of each display passes through a drilled hole to the Pi controller on the inside.

In the bottom left of Figure 4, two programmers debug a long code printout. Debugging can be a frustrating process, but these two coders are smiling, nonetheless. The graphics on the paper strip are from a real Lego robotics program. They are photo-reduced snippets of the drag-and-drop Blockly programming language.

The word “coopertition” is a registered trademark of FIRST. Teams compete, but they also cooperate with one another by loaning wisdom, parts, tools, and assistance where needed. The bottom middle of Figure 4 is a perfect example. Here the wizard loans his hat to another team. A little magic never hurts.


You can download the complete source code for the hat from my GitHub repository [13]. There are only three files: a driver for the display, a driver for the motors, and a short main program. I’ll discuss some key points of the driver code next.

The Adafruit Python motor driver is easy to work with. You control each motor by giving it a power percentage from -1 (full backward) to 0 (stop) to 1 (full forward). A value of None removes power from the motor, which conserves the battery.

The three Lego motors in my hat are under different mechanical loads. The radar dish (motor 1) turns easily while the gear trains (motors 2 and 3) take more power to spin. I experimented with each motor at high and low battery levels and defined three different speed values for each motor: slow, medium, and fast. I found that the radar dish stalled under 30% power and the gear chains stalled under 50%. The list named MOTORS in Listing 1 shows the values used by the code for the motors in my hat.


Each motor runs in its own code thread. The thread loop picks a random motion sequence, drives the motor through each speed/duration pair, and pauses for a few seconds before selecting a new sequence.

kit = adafruit_motorkit.MotorKit()

    (kit.motor1, [-1.00, -0.75, -0.50, None, 0.50, 0.75, 1.00]),
    (kit.motor2, [-1.00, -0.90, -0.80, None, 0.80, 0.90, 1.00]),
    (kit.motor3, [-0.95, -0.85, -0.75, None, 0.75, 0.85, 0.95]),

runs = [
    [(4,1.0),(3,0.5),(2,2.0),(1,3.0),(3,1.0),(5,2.0)], # 9.5s total
    [(4,1.0),(6,3.0)], # 4s total
    [(2,1.0),(0,3.0)], # 4s total
    [(4,1.0),(3,0.5),(2,1.0),(3,0.5),(4,1.0),(3,0.5),(2,1.0)], # 5.5s total
    [(6,3.0)], # 3s total
    [(0,3.0)], # 3s total

def _loop(sleep_mode, motor, speeds):        
    while True:
        # Abort if the sleep-switch was pressed
        if sleep_mode[0]:
        # Pick an activity profile
        run = random.choice(runs)
        for v,delay in run:
            thr = speeds[v]            
            motor.throttle = thr
            for _ in range(delay*10):
                if sleep_mode[0]:
        motor.throttle = None
        # Pause for a few seconds between runs
        for _ in range(random.choice([10,15,18,20])):
            if sleep_mode[0]:

The list named runs in Listing 1 contains six different motor action sequences. Each sequence is a list of speed/time tuples. Each speed value is an index into the MOTORS percent values. The time is in seconds. For instance, the second sequence [(4,1.0), (6,3.0)] spins the motor slow-forward (index 4 in the speeds) for one second, then full-forward (index 6) for three seconds.

I used three threads, one for each motor, to run the motors independently. The _loop function at the bottom of Listing 1 is the main loop for each thread. First, the function picks a random action sequence from the runs list. Then it walks the list, setting the motor value and sleeping the given time. When all the steps are done, the function pauses randomly from 10 to 20 seconds and repeats with another action sequence.

The sleep_mode variable passed into the function is shared by all threads and the main program loop. The main program watches for button presses and signals the threads to abort their sequences. This puts the hat into sleep mode until the button is pressed again.

Now for the bicolor LED displays. I’ve used these displays in several projects over the years. Each has a four-wire interface: power, ground, clock, and data. All three displays can use the same I2C bus, but you must make solder bridges on the back of the displays to configure each with a different I2C address.

I used a fourth thread to animate the three LED displays. Adafruit has a great full graphics library for these displays, but controlling them is simple with a few I2C commands. You write three configuration bytes to the display to turn it on. After that, you write 16 bytes of pixel data whenever you want to refresh the display. The displays are 8×8 bicolor (red, green) pixels. That’s 128 total LEDs. Each LED is on or off—one bit. 128 LEDs divided by 8 bits is 16 bytes to draw the display.

Listing 2 shows part of the display driver code. Each physical display is controlled by a separate instance of my Display class. Each display object keeps an internal 16-byte pixel buffer that you draw on with primitive commands like clear() and set_pixel(x, y, color). All the drawing takes place off-screen in the memory buffer. When you are done drawing, you call refresh() to push the internal buffer to the physical display. While that picture is showing, you can clear the buffer and draw a new picture.


The Display class maintains an internal 2D pixel buffer for a single display. The class provides familiar access methods for clearing the display and setting individual pixels. Once you have twiddled the desired pixels in the background buffer, you call “refresh” to quickly push the buffer to the display.

class Display:

    def __init__(self, i2c, address):
        self._buffer = [0]*16 # Pixel buffer
        self._i2c = i2c
        self._address = address
        self._i2c.writeto(address, bytes([0x21]) ) # Turn the oscillator on
        self._i2c.writeto(address, bytes([0xEF]) ) # Full brightness
        self._i2c.writeto(address, bytes([0x81]) ) # Blinking off, display on        
        self.clear()    # Clear the internal pixel buffer
        self.refresh()  # Write the blank buffer to the display

    def clear(self,c=0):        
        # Fill the buffer with color c
        v = COLOR_MASK[c]
        self._buffer = [v[0],v[1]]*8
    def set_pixel(self, x, y, color):
        # Set pixel (x,y) to color
        # ... removed for brevity ...

    def refresh(self):
        # Write the buffer to the display
        self._i2c.writeto(self._address, bytes([0]+self._buffer) )

I coded three animation sequences for the hat. First, the “random fiz” fills the displays with random pixels like white noise on an old TV set, if you are old enough to remember when TVs could show noise. Next, the three letters “F L L” (for FIRST Lego League) scroll onto their separate displays from different random directions. Finally, the “F L L” message scrolls across the entire 3-character display from left to right.


I try to make a new hat every year, but maybe I’ll use this hat again for FLL events next year. A hat this involved is worth repeating for a year or two (or five). I might make a pair of flashy NEO pixel glasses to wear with the hat. The hat’s Pi Zero and battery can easily drive everything.

Eventually, I want to replace the motor controller with a real Spike Lego robot controller. Then I can print the graphical code and show the kids how it works in code they understand. I’ll replace the Pi Zero with an inexpensive ESP8266 with micropython to drive the display. I’ll print the easy-to-read code to share with the kids along with the simple wiring diagram. Hopefully, that will inspire kids to keep making and to graduate into a “real-world” programming language. 

[1] Lego Hat in Action:
[2] Foam Camping Pad:
[3] Hat pattern:
[4] Hat-making tutorial:
[5] LEGO Motor:
[6] Gears and axels:
[7] Technic beams, axels, and connectors:
[8] Pi Zero:
[9] Motor Controller:
[10] Bicolor LED Matrix:
[11] UBEC 5V converter:
[12] Pushbutton:
[13] The Lego Hat GitHub repository:

Raspberry Pi |

Code and Supporting Files


Keep up-to-date with our FREE Weekly Newsletter!

Don't miss out on upcoming issues of Circuit Cellar.

Note: We’ve made the Dec 2022 issue of Circuit Cellar available as a free sample issue. In it, you’ll find a rich variety of the kinds of articles and information that exemplify a typical issue of the current magazine.


Advertise Here

Would you like to write for Circuit Cellar? We are always accepting articles/posts from the technical community. Get in touch with us and let's discuss your ideas.

Sponsor this Article

Chris Cantrell ( is a Staff Engineer for Vertiv. He
also teaches for Professional and Continuing Studies at the University of
Alabama in Huntsville. When he isn’t working, you’ll find him soldering on
some fun IoT project or digging around in the ROMs of an old arcade game.
Chris has written several articles for Circuit Cellar over the years.

Supporting Companies

Upcoming Events

Copyright © KCK Media Corp.
All Rights Reserved

Copyright © 2024 KCK Media Corp.

The Lego Hat

by Chris Cantrell time to read: 13 min