Make a Blinking Top Hat

Arduino Pro Mini

The Blinking top hat was created by a couple of do-it-yourselfers to give as a gift at their friends’ engagement party. As the hat is tilted it lights up with rotating effects. The blinking top hat combines white LED strips, a small Arduino Pro mini and an accelerometer to obtain the really cool effect.


Parts needed


  • Arduino Pro Mini
  • Mini FET shield
  • ADXL335 Triple Axis Accelerometer
  • Rectangle AA battery holder
  • Power switch
  • Wire wrap wire
  • 12V strip LEDs


The light for the blinking top hat comes from regular white LED strips. They are driven by 12V, and are extremely bright. There are 16 strips in all, which are wired ingeniously in parallel so that the Arduino Pro Mini shield only has to deal with 8 channels.


Each strip has a self adhesive backing that holds the strip solidly (during extreme head maneuvers) to the top hat. The + and – connections are created with thin 30AWG wire wrap wire and poked through the fabric.


The Arduino Pro Mini 3.3 V/8MHz is the perfect size and has plenty of computing power to read the accelerometer and control 8 channels of LEDs. It uses a fraction of the power that the LEDs use and can be reprogrammed with an FTDI Basic for other cool lighting effects.


Each strip has 15 LEDs, which means it will use about (15 * 20) 300mA per strip when illuminated. This is way more than the ATmega328 can handle (about 20mA max) so the Mini FET Shield came in super handy. This shield allows a low voltage Arduino (3.3.Vs in the case of the top hat) to control much larger loads (12V and 300mA in the case of the LED strips).


Each of the 8 channels on the Mini FET shield can handle 2 amps, so the MOSFETs shouldn’t  even get warm. As previously mentioned, there are 16 LED strips, but they are wired in parallel so that you only need to control 8 channels to get a really cool effect.



The hat uses the ADXL335, a classic workhorse with easy to read analog outputs for the three axes. But any solid state accelerometer, such as the ADXL345, the MMA7361, or the MMA8452Q, should work just fine.


The ADXL335 is old (3 years is ancient in the world of electronics), but it is very easy to read the analog voltages and convert them into 10-bit integers using Arduino. The real trick is doing the basic math to figure out how the top is moving. In general we take the three vectors (X, Y, and Z) and combine them into one vector.



Because the LED strips run at 12V, the hat uses 8 AAs in two battery holders, to distribute the weight. When the batteries are fresh, we have a nominal voltage of 1.5V * 8 = 12V. The LEDs use a fair amount of juice, so lithium batteries were used to maximize the run time. In practice, the hat runs for tens of hours on a set of batteries, so alkalines could also be used. An in-line slide switch makes it easy to kill the power to the hat at the end of the night.



The on/off switch provides power to the Arduino Pro Mini as well as power to the LED strips. There are 8 MOSFETs on the MiniFET that are individually controlled. You can use the shield or use 8 discrete MOSFETs. The accelerometer is wired into the analog inputs.


Vector Math

For the purpose of this project, you only need to be concerned with the movement of the hat (magnitude of movement), not direction:


A² + B² + C² = Z²


or in code:


float magnitude = sqrt((aX * aX) + (aY * aY) + (aZ * aZ)); //Combine all vectors


This is what the actual code looks like:


float avgMag = 0;
for(int x = 0 ; x < 8 ; x++)
aX = analogRead(accelX);
aY = analogRead(accelY);
aZ = analogRead(accelZ);

float magnitude = sqrt((aX * aX) + (aY * aY) + (aZ * aZ)); //Combine all vectors
avgMag += magnitude;
avgMag /= 8;


You will need to take 8 readings and average them together to reduce the noise. Next you will need to decide what to do with this magnitude reading.


For the purpose of The Blinking Top Hat you will need to have the LEDs spin fast when acceleration or movement is detected and then begin to slow the rotation as the movement of the hat slows. To do this, use an exponential growth equation to organically increase the time between channel changes (tBCC in the code).


Time delay between LED changes = A * xt

This is a basic exponential growth equation. The time between LED changes will increase exponentially with time based on a constant A and a growth rate x.

For example, if you want the LED strips to slow down across 3 or 4 seconds when the accelerometer stops detecting movement, then you will need to determine A and x.

You can determine the constant A by programming the hat to rotate in a circle and then see how small a delay the rotation could use before your eyes couldn’t discern the difference. 10-20ms between a step to the next LED strip looked pretty awesome. Anything less than 10ms just turns into a blur.

To determine the growth rate x, a spreadsheet was used to find that a growth rate of 1.00086 would cause the delay to increase to over 500ms within 3.5 seconds.


Soft PWM

You may find that the LED is too bright. You can reduce the brightness by pulse-width-modulating (PWM) the 8 channels. If you reduce the PWM ratio, then the LED strips should be less bright and you should be able to extend the battery life. The problem is that the Arduino Pro Mini only has 6 PWM channels, not enough to run all 8.

SoftPWMSetPercent(chan0, brightLevel);

This simple function allows you to set a given LED strip to a brightness level between 0 (off) and 99 (full brightness). Although, testing has shown that a brightness level of 9% was bright enough, without being overbearing.

The Blinking Top Hat is a fantastic experiment that will amaze everyone.

Please join the conversation with your input.

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

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

Google photo

You are commenting using your Google 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